Services provider and consumer in Spring DM - spring

I have a bundle that should provide and consum a service. My application context is:
<bean id="dbConsumer" class="service.User">
<property name="db" ref="DBservice"></property>
</bean>
<osgi:reference id="DBservice">
<osgi:interfaces>
<value>com.db.manager.DatabaseManager</value>
</osgi:interfaces>
</osgi:reference>
<bean name="ServicioZB" id="zbservice" class="service.ZBService"/>
<osgi:service ref="zbservice">
<osgi:interfaces>
<value>service.IZBService</value>
</osgi:interfaces>
</osgi:service>
The problem is when I deploy. I work on Equinox and if I watch services I can see that the bundle consums DBservice. However, the service is noy exposed. But if I remove the reference tag, my service is exposed. It is to say, I have 3 bundles (A,B,C). B exports a service that is consumed by A. Also, C exports a service which is consumed by B Then, my question is: Can not the tags be together? How could I develop a bundle to consum and provide services?
Thanks in advance!
Regards!

If you are only using publishing one interface, try to use the interface property instead of the interfaces-tag. So replace
<osgi:service ref="zbservice">
<osgi:interfaces>
<value>service.IZBService</value>
</osgi:interfaces>
</osgi:service>
with
<osgi:service ref="zbservice" interface="service.IZBService"/>
I had a similar issue one time and this approach did work for me.

Related

WAS 8.5 - Can a blueprint managed OSGI service have a reference to a declarative services managed OSGI service?

We use WebSphere 8.5 (NON-Liberty Profile… just straight-up WAS) and we have a Spring 3.2 web app that is accessing an OSGI service which is using the blueprint component model via an SCA service bridge. We did this this way because to our understanding, this was the only way to be able to access the OSGI services layer from within our current architecture. If anyone might know of another/better way, I'm also all-ears on this as well.
From within this blueprint managed service, we'd like to have a reference to another service. This other service(and any service references within it) we'd like to have managed by the declarative services component model.
My question is… is this possible? Does anyone know if this mixing of these two component models from within WAS 8.5 is do-able in any way, shape, or form??
And if it is possible, might anyone be able to point me in the right direction on how to approach this?
Edit - Dec 5th
So the approach I decided to take was to first, build a small proof-of-concept application that uses three different OSGI bundles all using blueprint. Then once I have this working, take one of the blueprint managed services, and attempt to convert it to a ds managed service.
Here's what I've got so far:
I have ran through and created the tutorial located here. I currently have the CounterApp OSGI bundle Application containing the following bundles as application content:
CounterServiceBundle
CounterWebBundle
CounterWorldBundle
As is stated in the tutorial, all of the above are tied together using the blueprint component model via the blueprint.xml files.
So it all breaks down as follows:
From within the doGet method of the CounterWebBundle's CounterServlet I have a Greet service being used in the following manner:
Greet greet;
try {
InitialContext ic = new InitialContext();
greet = (Greet) ic.lookup("osgi:service/"+Greet.class.getName());
String greetText = greet.getText();
String output = "greet.getText()="+greetText;
response.getOutputStream().println(output);
} catch (NamingException e) {
e.printStackTrace(System.out);
}
This "greet" service is defined in the blueprint xml as "GreetBeanService". Now, within its implementation class it has references to two other services, "CounterBean" and "WorldRef".
Here is the blueprint.xml file to clarify:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<bean id="CounterBean" class="com.ibm.ws.eba.counter.CounterImpl"
init-method="init"></bean>
<service id="CounterBeanService" ref="CounterBean"
interface="com.ibm.ws.eba.counter.Counter" />
<bean id="GreetBean" class="com.ibm.ws.eba.counter.GreetImpl"
init-method="init">
<property name="counter" ref="CounterBean"/>
<property name="worldBean" ref="WorldRef"/>
</bean>
<service id="GreetBeanService" ref="GreetBean"
interface="com.ibm.ws.eba.counter.Greet" />
<reference id="WorldRef" interface="com.ibm.ws.eba.world.World" />
</blueprint>
So the thing is this:
I'm aiming to convert the "WorldRef" service to a DS managed service with a component.xml file and the following added to the MANIFEST.MF header Service-Component: OSGi-INF/component.xml of the implementation Class, not the API Class if I'm understanding correctly.
Would this be all I would need to do for the conversion? Or do I also need to add an Activator for the Class? Also, would I need to add 'activate' and 'deactivate' methods in the API implementation Class?
Also I'm of the understanding that I have to somehow include the service component runtime, as a separate bundle and include it in the "CounterApp" application, how exactly would I do this? Do I have to create a separate bundle project consisting of the following bundle/jars
org.eclipse.equinox.util
org.eclipse.equinox.ds
org.eclipse.osgi.services
where I would then re-export all of the exported interfaces from all of these jars?
Or do I have to define some sort of service to export that exposes the SCR?
Edit - Dec 6th
I went ahead and created a new DS OSGI bundle/jar containing all of the above mentioned jar files required to provide the equinox DS implementation, then just passed on the exports of each jar in this new bundle. I then added this DS bundle to my CounterApp application and imported each of these DS bundle exports into the bundle containing the WorldRef service.
This is where I appear to be getting hung up:
The OSGI framework is loading the bundle containing the WorldRef service but the service is not being added to the registry, which suggests that the component.xml file defining the service isn't being read, which, intern suggests that the SCR is not running because it is what reads that file to my understanding.
So still stuck on the ability to get the SCR running. I am under a very tight deadline (I know… who isn't, right?

Spring customised PropertyPlaceholderConfigurer

I have config xml based spring application for which I have moved proprties required at start up time in database. It was very difficult to manage hundreds in property file and that is why database is introduced. To read properties a spring restful service is developed to return a map of all properties required at start up time.
I want to know how to replace properties reading from a map to spring context file e.g. ${config.service.url} should be polulated from a map read via web service.
One option I considered is to upgrade to Annotation based and start using MapPropertySource and Environment interface as environment.getRequiredProperty("config.service.url"). However upgrading to Annotation based is a big impact on project and is no at this time.
Second option that I am looking forward is to have a customised PropertyPlaceholderConfigurer.
Any pointer/help on this will be great.
Cheers,
Amber
You could define a PropertyPlaceholderConfigurer, but instead of specifying a file location, you can pass the properties directly as returned by your restful service.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="properties" .../>
</bean>

Create beans with property names as element names?

I am new to spring and happy to see that following works as expected:
<bean id="..." class="server.Shell">
<property name="usableCommands" value="cat"/>
</bean>
The above is in the client code, where I have provided the server.Shell. Now I would like for the clients to be able to use the following:
<shell id="...">
<usableCommands value="cat"/>
</shell>
Is there anything in springframework that I can use to map say an xsd to bean classes? Any other suggestion for easily creating a simple xml based domain language?
You can register a custom XML Namespace in Spring that would allow you to customize your configuration XML. If you're looking to create a sort of DSL in your Spring configuration XML, that might be a good place to start.
UPDATE:
Check out this link for a general example of how custom namespaces in Spring work. This pattern should hold in OSGi as well -- check out Section 6.4 of the Spring OSGi docs for an explanation. If you're new to OSGi, it can be daunting in general. SpringDM can help. Try here for some background and here for an example. Hope that helps.

Exposing multiple implementations of a interface as OSGI service

I have an interface that has two implementations. I want to expose both implementations as OSGi services, but when I am doing that one overrides the other. Please find the configuration that I am doing:
<bean id="formService" class="com.dbt.form.service.FormService"/>
<bean id="formAPIService" class="com.dbt.form.service.FormAPIService"/>
<osgi:service
ref="formAPIService"
interface="com.dbt.form.service.ifc.IFormService"/>
<osgi:service
ref="formService"
interface="com.dbt.form.service.ifc.IFormService" />
Here formService is overriden by formAPIService implementation.
Please help me on how to sort out this issue.
The second service does NOT override the first... both of these services will be published separately, and you can confirm this by typing the inpect cap service command in the OSGi Gogo shell.
What MAY happen is that your consumer code will only choose one of the available service instances. In this case you need to write your consumer to either bind to all instances, or use a combinations of rankings or target filters to determine which particular service you want. You should give more information on how you are using these services since that is where the problem lies (probably).
Read this page...Chapter 8. The Service Registry section 8.2.2.3.
You can use bean-name attribute of osgi reference tag. While importing a service bean-name refers to the id attribute of that service when its exported.

why is jax-ws spring service reference prefixed with #, as in ws:service bean="#myService"

I've developed a web service with jax-ws and Spring using the tutorials at the jax-ws commons website. It shows you how to define and reference your service from your spring applicationContext file (https://jax-ws-commons.dev.java.net/spring/).
What is the reason for the "#" when referencing the web service? I would expect to see something more like
<ws:service name="myEventWS" ref="eventWebService"/>
but following example at the above link I created the following which works.
<bean id="eventWebService" class="com.myws.EventWS">
<property name="model" ref="EventModel"/>
</bean>
<wss:binding url="/EventWS">
<wss:service>
<ws:service bean="#eventWebService"/>
</wss:service>
</wss:binding>
<ws:service> is using a custom configuration namespace, which is a feature of Spring which allow you to express complex bean graphs using simpler namespace. The meaning and interpretation of these custom namespaces is down to the implementation in question, in this case the JAX-WS-Commons project. It seems the authors of that decided that bean=#eventWebService means what you refer to as ref="eventWebService".
I don't know whay they did it that way, maybe they thought it was more readable... maybe they thought that bean=eventWebService (without the hash) means a name, rather than a reference... I don't know. The documentation isn't very clear either.
Either way, I'm pretty sure sure it's not a core Spring syntax, nor a convention that I've seen before.
the "#" tells the bean that it's not a class, but rather a ref.
HTH
#eventWebService refers to the bean of type EventWebService (according to the default Spring naming convention when bean is is not specified).

Resources