Let's say the Connector interface has two methods,
Services getAllService()
Service getService(String id)
what we wanted to do is to set a router that would
- route to all available Connector for the getAllService call and have an aggregator to aggregate the results from all Connector.
- route to a specific Connector for getService (assuming we can tell which Connector to use by inspecting the id)
Inspired by this post, we decided to build our own dynamic service activator. The router will route to channels with a certain name pattern, <backend service name>.<method name>, e.g. backendA.getAllService. Then we create a bean, DynamicServiceActivator, that will create channels with matching names and call the Connector bean. Details about how to create a channel and send a reply is already covered in the above mentioned post, I'm not repeating here. Since we'll need one instance of DynamicServiceActivator per Connector bean, we get a list of Connector using Gemini's list
<osgi:list interface="Connector">
<osgi:listener bind-method="addConnector" unbind-method="removeConnector" ref="connectorMgr" />
</osgi:list>
<bean id="dynamicServiceActivator" class="DynamicServiceActivator" scope="prototype"/>
and in the addConnector method, all we have to do is applicationContext.getBean("dynamicServiceActivator") and set the Connector to the activator.
there's one little piece is missing from the above picture. Since we are creating a channel per method, service activator is suppose to call one method, when we set the connector to the dynamic service activator, it'll have to inspect all method names and create channels for each one of them. Two ways we can control the method to be exposed, either define in the application context xml, e.g.
<bean id="dynamicServiceActivator" class="DynamicServiceActivator" scope="prototype">
<property name="methods">
<map>
<entry><key>getAllService</key><value>SpEL expression</value></entry>
<entry><key>getService</key><value>SpEL expression</value></entry>
</map>
</property>
</bean>
or annotate the Connector class, so we can find the appropriate method signature to call.
No comments:
Post a Comment