-
1. Re: Routing to Switchyard service with multiple methods
igarashitm Dec 5, 2012 3:45 PM (in response to kostas_papag)I could see orderServiceOp was in camel message header and your operation selector successfully got it. It just fails to retrieve SupportService instance from CDIMixIn. I'm not sure if it's possible though.
-
2. Re: Routing to Switchyard service with multiple methods
kostas_papag Dec 5, 2012 4:33 PM (in response to igarashitm)Hello Tomohisa,
when you say that the CDIMixIn fails to retrieve the instance, you mean this part of the code : SupportService service = mixin.getObject(SupportService.class); ?
The List where I store the messages is static, so even if CDIMixIn fails to retrieve the proper instance of the service, the message should be there anyway.Moreover I get no log message that the message has been received from the Bean Service...
Running the test in log level = DEBUG , i noticed the following messages :
...
22:07:21,782 DEBUG [org.switchyard.internal.ExchangeImpl] Sending IN Message (979726925) on IN_ONLY Exchange (1513306926) for Service '{urn:switchyard-quickstart:camel-jms-example:0.1.0}CustomerService', operation 'null'. Exchange state: OK
....
22:07:21,804 DEBUG [org.switchyard.internal.ExchangeImpl] Sending IN Message (190331520) on IN_ONLY Exchange (1298706257) for Service '{urn:switchyard-quickstart:camel-jms-example:0.1.0}SupportService', operation 'null'. Exchange state: OK...
.....
22:07:21,812 DEBUG [org.switchyard.internal.ExchangeImpl] Sending OUT Message (1614453842) on IN_ONLY Exchange (1298706257) for Service '{urn:switchyard-quickstart:camel-jms-example:0.1.0}SupportService', operation 'null'. Exchange state: FAULT
.....
Seems that although the operation selector is picking the operation name , still the Exchange somehow doesn't contain the proper operation....
-
3. Re: Routing to Switchyard service with multiple methods
igarashitm Dec 5, 2012 5:38 PM (in response to kostas_papag)I think I got the root cause. operation name is lost since you're using interface.esb for the reference to the SupportService. If you use interface.java instead, and enable setHeader in the OrderRouteBuilder you're now commenting out, then works fine.
-
4. Re: Routing to Switchyard service with multiple methods
ibek Dec 6, 2012 3:51 AM (in response to kostas_papag)Hi Kostas,
I recommend to use the Camel route filtering instead. (http://camel.apache.org/message-filter.html). As a <from> and <to> locations , you can use "switchyard://YourComponentName" so it will look like:
<component name="DirectProductOrder">
<camel:implementation.camel>
<route xmlns="http://camel.apache.org/schema/spring">
<from uri="switchyard://FromTheService"/>
.choice()
.when(header("orderServiceOp").isEqualTo("Hello")).to("switchyard://HelloComponentRef")
.when(header("orderServiceOp").isEqualTo("Bye")).to("switchyard://ByeComponentRef").stop()
.otherwise().to("switchyard://OtherComponentRef")
.end()
<to uri="switchyard://ResultComponentRef"/>
</route>
</camel:implementation.camel>
... your references and service
</component>
-
5. Re: Routing to Switchyard service with multiple methods
kostas_papag Dec 6, 2012 5:06 AM (in response to igarashitm)Tomohisa your proposal works indded!
I was guessing that switchyard would pick the reference interface , after resolving the service name but seems that not the case. I will use your solution, thanks!
Seems though I'm now running in a new problem. When building the jar of this example and trying to deploy on Switchyard 0.6.0.Final , i get a strange exception :
[org.jboss.modules] (MSC service thread 1-6) Failed to define class com.example.order.OrderOperationSelector in Module "deployment.camel-jms-example.jar:main" from Service Module Loader: java.lang.LinkageError: Failed to link com/example/order/OrderOperationSelector (Module "deployment.camel-jms-example.jar:main" from Service Module Loader)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:396)
at org.jboss.modules.ModuleClassLoader.loadClassLocal(ModuleClassLoader.java:243)
at org.jboss.modules.ModuleClassLoader$1.loadClassLocal(ModuleClassLoader.java:73)
at org.jboss.modules.Module.loadModuleClass(Module.java:517)
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:182)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
at org.jboss.as.weld.WeldModuleResourceLoader.classForName(WeldModuleResourceLoader.java:68) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.weld.bootstrap.BeanDeployer.loadClass(BeanDeployer.java:98) [weld-core-1.1.6.Final.jar:2012-03-21 18:52]
at org.jboss.weld.bootstrap.BeanDeployer.addClass(BeanDeployer.java:77) [weld-core-1.1.6.Final.jar:2012-03-21 18:52]
at org.jboss.weld.bootstrap.BeanDeployer.addClasses(BeanDeployer.java:123) [weld-core-1.1.6.Final.jar:2012-03-21 18:52]
at org.jboss.weld.bootstrap.BeanDeployment.createBeans(BeanDeployment.java:184) [weld-core-1.1.6.Final.jar:2012-03-21 18:52]
at org.jboss.weld.bootstrap.WeldBootstrap.deployBeans(WeldBootstrap.java:349) [weld-core-1.1.6.Final.jar:2012-03-21 18:52]
at org.jboss.as.weld.WeldContainer.start(WeldContainer.java:82) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.as.weld.services.WeldService.start(WeldService.java:76) [jboss-as-weld-7.1.1.Final.jar:7.1.1.Final]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) [rt.jar:1.6.0_35]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) [rt.jar:1.6.0_35]
at java.lang.Thread.run(Thread.java:662) [rt.jar:1.6.0_35]
Caused by: java.lang.NoClassDefFoundError: org/switchyard/component/common/selector/OperationSelector
at java.lang.ClassLoader.defineClass1(Native Method) [rt.jar:1.6.0_35]
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631) [rt.jar:1.6.0_35]
at java.lang.ClassLoader.defineClass(ClassLoader.java:615) [rt.jar:1.6.0_35]
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) [rt.jar:1.6.0_35]
at org.jboss.modules.ModuleClassLoader.doDefineOrLoadClass(ModuleClassLoader.java:327)
at org.jboss.modules.ModuleClassLoader.defineClass(ModuleClassLoader.java:391)
... 21 more
Caused by: java.lang.ClassNotFoundException: org.switchyard.component.common.selector.OperationSelector from [Module "deployment.camel-jms-example.jar:main" from Service Module Loader]
at org.jboss.modules.ModuleClassLoader.findClass(ModuleClassLoader.java:190)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassUnchecked(ConcurrentClassLoader.java:468)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:456)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:423)
at org.jboss.modules.ConcurrentClassLoader.performLoadClassChecked(ConcurrentClassLoader.java:423)
at org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:398)
at org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:120)
... 27 more
... in my pom file i have the following dependency :
<dependency>
<groupId>org.switchyard.components</groupId>
<artifactId>switchyard-component-common</artifactId>
<scope>provided</scope>
</dependency>
Shouldn't the dependency be picked up by the container?
-
6. Re: Routing to Switchyard service with multiple methods
kostas_papag Dec 6, 2012 6:25 AM (in response to ibek)Hello Ivo,
Indeed this solution works if there is a single operation per service.
In my case though, I'm trying to direct the payload to the appropriate operation of one given service, not splitting the payload among different services.
OperationSelector seem to be needed for such a case, so I decided to use my own java implementation of the selector to be able tomake the selection dynamically.
Regards,
Kostas
-
7. Re: Routing to Switchyard service with multiple methods
igarashitm Dec 6, 2012 12:15 PM (in response to kostas_papag)1 of 1 people found this helpfulCould you try again with adding this dependency to the SwitchYard module def on AS7? Probably it's the one I should have added...
--- modules/org/switchyard/main/module.xml.orig 2012-12-06 12:08:18.539496142 -0500 +++ modules/org/switchyard/main/module.xml 2012-12-06 11:53:56.209081840 -0500 @@ -57,6 +57,7 @@ <module name="org.switchyard.runtime"/> <module name="org.switchyard.serial"/> <module name="org.switchyard.security" export="true"/> + <module name="org.switchyard.component.common" export="true"/> <module name="org.switchyard.component.http"/> <module name="org.switchyard.component.remote"/> <module name="org.switchyard.component.resteasy"/>
-
8. Re: Routing to Switchyard service with multiple methods
splatch Dec 6, 2012 6:44 PM (in response to kostas_papag)Specify header org.switchyard.operationName in camel router. It might be calculated, glued or whatever you would like to do. :-)
-
9. Re: Routing to Switchyard service with multiple methods
kostas_papag Dec 7, 2012 6:31 AM (in response to igarashitm)Tomohisa, with this last fix I'm able to succesfully deploy my example.
Seemed that it was a configuration issue, but now Im sure, thx!
Regards,
Kostas
-
10. Re: Routing to Switchyard service with multiple methods
kostas_papag Dec 7, 2012 7:26 AM (in response to igarashitm)Tomohisa igarashi wrote:
I think I got the root cause. operation name is lost since you're using interface.esb for the reference to the SupportService. If you use interface.java instead, and enable setHeader in the OrderRouteBuilder you're now commenting out, then works fine.
This solution worked indeed for my example.
However, seems that we can run into a different problem here :
By defining the services in the following way in switchyard.xml :
<component name="OrderRouteBuilder">
<implementation.camel xmlns="urn:switchyard-component-camel:config:1.0">
<java class="com.example.order.OrderRouteBuilder"/>
</implementation.camel>
<service name="OrderService">
<interface.java interface="com.example.order.OrderService"/>
</service>
<reference name="SupportService">
<interface.java
interface="com.example.order.SupportService"/>
</reference>
</component>
<component name="SupportService">
<implementation.bean xmlns="urn:switchyard-component-bean:config:1.0"
class="com.example.order.SupportServiceImpl"/>
<service name="SupportService">
<interface.java
interface="com.example.order.SupportService"/>
</service>
</component>
, in a bit more complex example where transformers would be needed( OrderService and SupportService consuming different type of payload),
transfomation wouldn't kick in.
From my undestanding , currently switchyard checks the consumer and provider input type from the exchange contract and identifies what kind of transformation is needed. In the above case, the contract input types are the same!
There is a workaround that I see, to define "dummy" interfaces and provide them as a reference interface.
As I see it, maybe it would make sense that in the TransfomerHandler , the tranformation is based on the actual message content, and not on the contract.
In any case , I attach this "enhanced" example , with the workaround desribed above.
-
camel-jms-example.zip 12.6 KB
-
-
11. Re: Routing to Switchyard service with multiple methods
kcbabo Dec 7, 2012 8:40 AM (in response to kostas_papag)There are actually two forms of transformation available to you in SwitchYard. Declarative transformation is the type you are referring to in your last post. The purpose of declarative transformation is to resolve incompatible message types between services, which is a very common problem. If the message types are the same, then declarative transformation is not as good a fit. As you mentioned, you could create a separate interface to force a transformation to occur if you really want to use declarative transformation.
The other type of transformation would be the classic procedural transformation where you explicitly invoke a transformation from application logic. The most common example of this would be to create a camel routing service and from within that route you can explicitly invoke a transformation processor (XSLT, data format, etc.).
Ultimately, the flexibility is there to go with whatever suits you best. Personally, I feel that declarative transformation is a good fit for reconciling messages which have the same information, but in different formats. Procedural transformation is appropriate when you want to introduce business logic to inform the transformation - things like enrichment, code lookups, data cleansing, etc.
-
12. Re: Routing to Switchyard service with multiple methods
kostas_papag Dec 11, 2012 7:05 AM (in response to kostas_papag)Based on the findings of this topic, I created two tickets , https://issues.jboss.org/browse/SWITCHYARD-1209 and https://issues.jboss.org/browse/SWITCHYARD-1210 .
-
13. Re: Routing to Switchyard service with multiple methods
igarashitm Dec 11, 2012 9:24 AM (in response to kostas_papag)Hi Kostas,
Thanks for raising it! I'll fix SWITCHYARD-1210 for sure. However, I have rejected SWITCHYARD-1209. interface.esb is only used for single operation one. That's by design.