-
1. Re: Bean Component
kcbabo Dec 7, 2010 4:31 PM (in response to kcbabo)Tom - went with your suggestion from IRC to not be cute and use @Service on a separate object instead of directly on the test itself. Both tests pass now. It would be nice if we could inject a bean directly into a test and poke it without sending an exchange. I think this might work with an embedded runtime and Arquillian, but we should also be able to do it in a stand-alone unit test. Is it possible to get at the bean through BeanManager or some other CDI hook?
-
2. Re: Bean Component
tfennelly Dec 8, 2010 6:28 AM (in response to kcbabo)The only way I can imagine it's possible is if we can hook into JUnit and create the Test bean instances for it (via the CDI BeanManager). Weld would then handle all the injection points etc. Perhaps Arquilian does do something lik this, but I'd imagine it would first require the hooks to be there in JUnit. You could prob hack it using interceptors etc, but not sure I'd like the idea of that... would prob run into build-time issues with diff versions of JUnit etc.
I do agree it would be nice though, but only if we could do it without a hack
-
3. Re: Bean Component
kcbabo Dec 8, 2010 7:32 AM (in response to tfennelly)My last post was probably not the clearest. What I was referring to w/r/t BeanManager is that we would still have separate classes for the consumer bean, but we would not have to create an exchange in the test class in order to exercise the methods on that bean. Instead, we could have a method in AbstractCDITest which takes a service name and returns a set of beans which provide that service. You could then call this in your test instead of creating an exchange, e.g.
@Test public void testBeanConsumer() { String response = getServiceBean("HelloWorld").greeting(); }
The test class itself would not have to be a service.
-
4. Re: Bean Component
kcbabo Dec 8, 2010 7:34 AM (in response to kcbabo)BTW, the getServiceBean() method in AbstractCDITest could use BeanManager from WeldContainer or something similar to find the @Service beans.
-
5. Re: Bean Component
kcbabo Dec 8, 2010 7:37 AM (in response to kcbabo)Based on the current implementation and my own crazy thoughts, I have written up some processing rules for Bean Component. Feedback welcome.
- @Service is used to declare that a CDI bean provides one or more services.
- The default value element for the @Service annotation identifies the services provided by the bean. This should be a comma-delimited list of interfaces that are implemented by the bean. We specifically list these so that non-service interfaces (e.g. java.io.Serializable) are not exposed as services within SwitchYard.
- Each interface named in the @Service annotation is registered as an independent service in SwitchYard. The name of the service is equal to the name of the interface (package name excluded).
- @Reference should be used to inject references to SwitchYard services. We are using @Service now and I think this will potentially create confusion and will also constrain what we can use in terms of annotation elements (e.g. is the use of interface names as described above relevant for services which are being injected?).
- @Reference should be used with an interface which is within compile and runtime scope for the bean using the reference. This holds true whether the target service is Java-based or not. We generate a proxy to talk to the target service and map the call details onto an Exchange.
- Transformation between message formats (e.g. Object -> XML) is not part of the proxy handling mentioned above.
- General error handling notes:
- Errors related to @Service registration are reported at bean instantiation time.
- Errors related to @Reference resolution are reported at service invocation time. There is no need to eagerly query for registered services when the reference is injected.
- Errors/faults during service invocation should be reported as exceptions to the calling bean.
- We need to address the case where a bean consumer or provider requires access to context information, particularly message context in case there are headers which are required in the bean's processing logic. We may need to introduce a wrapper interface like Invoker<T> where 'T' represents the service interface and Invoker has additional methods to query/set context information.
-
6. Re: Bean Component
tfennelly Dec 8, 2010 9:06 AM (in response to kcbabo)- The default value element for the @Service annotation identifies the services provided by the bean. This should be a comma-delimited list of interfaces that are implemented by the bean. We specifically list these so that non-service interfaces (e.g. java.io.Serializable) are not exposed as services within SwitchYard.
- Each interface named in the @Service annotation is registered as an independent service in SwitchYard. The name of the service is equal to the name of the interface (package name excluded).
Yep... sounds good. The current impl requires the @Service annotation to be on the interfaces (Vs the impl) for the very reason you mention (i.e. so as to only expose those interfaces that you want exposed) . Changing @Service to list the interfaces would allow it to be done on the service impl itself, which is clearer. Good idea.
I'll have a think about the use case of getting context level info into beans.
-
7. Re: Bean Component
kcbabo Dec 8, 2010 9:10 AM (in response to tfennelly)I can't really take credit for the idea on @Service listing the interfaces as I picked that up from the SCA Java component specification. I was curious about how they defined Java components in SCA so I read the spec. I was quite surprised (pleasantly) to see many similarities between their definition of a component and what we had already been talking about.
-
8. Re: Bean Component
tfennelly Dec 8, 2010 9:14 AM (in response to tfennelly)I think we should be able to define a custom scope(s) in CDI and have weld inject the context info. The scope(s) would be based on our contexts.
-
9. Re: Bean Component
tfennelly Dec 8, 2010 9:17 AM (in response to tfennelly)And of course... could also probably have context info injected as invocation params... that would probably get messy though I think.
-
10. Re: Bean Component
kcbabo Dec 8, 2010 9:18 AM (in response to tfennelly)I agree that this would be the cleanest and most consistent path. This would work well on the service provider side, as it's pretty similar to a request scope for a webapp. On the consumer side, I'm not sure how this will work in terms of (a) passing additional context into an invocation and (b) pulling context out of a response from a service you are consuming.
-
11. Re: Bean Component
kcbabo Dec 10, 2010 10:00 AM (in response to kcbabo)Tom - I pushed in your pull request, so bean component is now hosted in the SwitchYard components repository.
For anyone interested, here's a link:
https://github.com/jboss-switchyard/components/tree/master/bean
-
12. Re: Bean Component
tfennelly Dec 10, 2010 10:36 AM (in response to kcbabo)Oh cool... so there was nothing wrong with the pull request.
Thanks Keith.