-
1. Re: Leveraging CDI
kcbabo Nov 17, 2010 9:34 PM (in response to tfennelly)This is super interesting. I looked over the code and see a number of detail-level things that I want to talk about (e.g. fault handling, whether multiple parameters are supported, etc.). I know from your post and comments in the code that you are aware of most of these, so I'll just roll them up in a list and post it back to the forum when I get back.
A few higher-level questions/comments:
Now that we've seen the provider side, it would be great to see the consumer side. I assume this will happen via injection, which can also be handled through the CDI Extension. The question in my mind is what gets injected? Injecting an exchange is a one-shot deal - it can't be used for multiple invocations. Even if we work around this with a factory-ish kind of solution, I'm not sure that the raw exchange API is the right level of interface for beans. Let's assume that every service registered in SwitchYard has an interface. A proxy to that interface could then be injected into the CDI bean and the proxy would handle creating the exchange and handling the invocation. Might be worth playing around with.
I'm a bit curious about the startup ordering of CDI and where it sits relative to SwitchYard. I would guess that CDI can come up first, followed by SwitchYard, followed by annotation scanning in CDI to discover and bootstrap bean instances. Does that sound right?
After we get the consumer and provider side sorted, I would like to mock up a simple a->b->c service invocation scenario, where [a-c] are services hosted in SwitchYard. The invocation pipeline from a->b->c could be done inside a single method in the CDI bean. I would like to play with that some to see how easy it is to create that code, whether we can add some additional APIs to make it easier, and whether generating that code as a result of user input/config is doable. My thinking here is that the user could declaratively define this service chain and we could create a bean which handles the invocation. If the user is cool with the default implementation, they never look at the class. If they want to do more, they can pop it open and have at it. Not sure if this will end up as a good or bad idea, but I think it's worth exploring.
-
2. Re: Leveraging CDI
kcbabo Nov 17, 2010 9:36 PM (in response to kcbabo)BTW, when I say above that "every service has an interface", I mean interface as in the service's contract (e.g. portType or Java interface).
-
3. Re: Leveraging CDI
tfennelly Nov 22, 2010 9:10 AM (in response to kcbabo)Checked in some code experimenting with creation of an injectable client proxy bean in an effort explore the a -> b -> c style use case. I have some weld issues at the moment creating the InjectionTarget instance for use in the client proxt bean instance. Still trying ot fix that.
-
4. Re: Leveraging CDI
tfennelly Nov 23, 2010 10:33 AM (in response to tfennelly)Have the basic injectable client side proxy working now: https://github.com/tfennelly/switchyard-cdi-experimental
This means we can inject a remote interface (client side proxy) for a Service into another Service i.e. the Service invocation will be done through the ESB Exchange mechansim. I have an example of this in the tests and it looks like this…
@ESBService public class WithProductsOrderManagementService { @Inject private ProductService productService; public OrderResponse createOrder(OrderRequest request) { OrderResponse orderResponse = new OrderResponse(request.orderId); orderResponse.product = productService.getProduct(request.productId); return orderResponse; } }
In the above code, the ProductService implementation is also an @ESBService bean. The reference that gets @Inject 'ed however, is just a proxy that does all the ESB invocation magic. Pete suggested that we make the remote aspect more explicit i.e. that the code would need a qualifier annotation if a proxy is to be added, otherwise a contextual reference to the actual @ESBService implementation bean is injected (i.e. normal CDI). Maybe something like the following if you want a proxied reference to be injected...
@Inject @Remote private ProductService productService;
-
5. Re: Leveraging CDI
tfennelly Nov 23, 2010 10:44 AM (in response to tfennelly)Or we could just have 2 simple rules as follows…
Inject actual service bean instance (Normal CDI Injection):
@Inject private ProductService productService;
Inject remote/proxied service bean instance:
@ESBService private ProductService productService;
-
6. Re: Leveraging CDI
kcbabo Nov 23, 2010 10:58 PM (in response to tfennelly)Nice! A few comments/questions:
- Could you elaborate on the @Remote suggestion? Your understanding of CDI magic is beyond mine now and I didn't get the signficance of a "contextual reference" being injected. If the idea is that the life cycle of the injected service is independent of the entity into which it's being injected, then I agree with that.
- You are putting operation name in the message context, but this should be in the exchange context, no?
- Generally speaking, I think we should start thinking about this as a "bean component" instead of just CDI integration. Reason being that I think we can replace user-implemented actions in ESB 4.9 with CDI beans in SwitchYard. In fact, we may even port the existing action classes (the ones that make sense) as CDI beans. It would be interesting to see how that plays out.
- We are using the same annotation for declaring that a bean implementation is a service as we are for declaring an interface as a consumer reference. I haven't thought through the ins and out of this, but that may end up being a problem later on. Then again, maybe not. :-)
I think the declaration of a service provider and the injection of a consumer reference are slick as all get out. My next concern is how this scales beyond the straightforward CDI<->CDI case. A few challenges that I see:
- How do we plan on dealing with non-object payloads (e.g. XML, JSON, etc.)? Obviously this can be handled through handlers or other services, but my point is how would this be expressed easily by the developer that is adding the @Service annotation to provide or consume a service from a bean?
- How will this work in an environment where Weld and SwitchYard are deployed as indpedent services? Lifecycle and classloading are two sticky points that need to be resolved.
-
7. Re: Leveraging CDI
kcbabo Nov 24, 2010 10:04 AM (in response to kcbabo)I goofed and branched Tom's reply on this thread while trying to split up the conversation into separate threads. Here's the first of those: