Mule EJB endpoint for dynamic method call - ejb

I am doing an integration poc to invoke a remote EJB servcie by ejb:connector and ejb:outbound-endpoint in component binding.
It works perfectly fine if I define methodArgumentTypes and method properties in ejb outbound endpoint
<flow name="ExternalServiceFlow" doc:name="ExternalServiceFlow">
<vm:inbound-endpoint exchange-pattern="request-response" path="serviceInput" doc:name="VM"/>
<ejb:outbound-endpoint connector-ref="weblogicEjbConnector" methodArgumentTypes="java.lang.String,com.fusa.ssg.datatype.Date,java.lang.String,com.fusa.ssg.datatype.AuditInfo" method="readAccountDetail" address="${external.ejb.service.address}"/>
</flow>
However, since I need to invoke other APIs in the same component binding, how can reuse the ExternalServiceFlow to invoke other methods besides readAccountDetail? I tried to remove the methodArgumentTypes and method properties, but the application started with exceptions
Element ejb:outbound-endpoint{address=${external.ejb.service.address}, connector-ref=weblogicEjbConnector, name=.ExternalServiceFlow:outbound-endpoint.32, protocol=ejb} must have all attributes for one of the sets: [ref] [method]
Please advise how I can reuse the same vm flow with different remote APIs call.

Related

Camel to route external REST web service

I'm working on spring MVC and using Apache camel to integrate external services.
I wanted to use Apache Camel route to make a Webservice call.
Like my local REST service (http://localhostsmiliex.xx:8080/users) fetching data from external REST service (http://xxx:000/users) and wanted routing to fetch external data.
Which Apache component would be suitable for a web-service route such as Jetty or producer template?
Have you tried HTTP4 or HTTP ?
http://camel.apache.org/http4.html
Use ProducerTemplate, it works like a charm for calling external endpoints REST, DB, SOAP etc..
You can either autowire it
#Autowired
ProducerTempalete prodcuerTemplate
prodcuerTemplate.sendBody("http://xyz...", "<hello>world!</hello>");
or
ProducerTemplate template = exchange.getContext().createProducerTemplate();
// send to default endpoint
template.sendBody("<hello>world!</hello>");
// send to a specific queue
template.sendBody("http://xyz...", "<hello>world!</hello>");

How to pass an Object from a Servlet to JSR-356 WebSocket

I have a JSP-type servlet that registers a WebSocket Endpoint with the Servlet container.
I want to pass a reference of that servlet, and/or some of its objects, to the WebSocket Endpoint, so that I can use the code from that servlet, e.g. for Authentication or Session management (the servlet has its own non-Java EE Session management).
I was hoping that I could set some attribute somewhere when I call addEndpoint() on ServerContainer, because at that point I have access to the objects that I want to use later, but none of the classes that I've seen at that point have an attribute collection, e.g.
objectThatWillBeAvailableAtWebSocket.addAttribute("some.custom.object", someObject);
By the time my code reaches an ServletRequestListener, ServerEndpointConfig.Configurator, or the registered Endpoint, I do not have any reference to the original servlet that added the Endpoint.
How can I pass an Object to the WebSocket servlet? I'm running my test code in Embedded Jetty, but I'm aiming for Container-agnostic code.

Which context should websocket config go into?

As most people, I have a root and servlet contexts. I need to enable websocket Stomp. I also need to send messages from the Service layer. So how do I configure?
If I put websocket:message-broker into the servlet config, then SimpMessagingTemplate is not autowired in the service layer. If I put it into the root, then it doesn't work at all, it isn't registered as an HTTP handler (even though logs say it does). If I put everything into the dispatcher context, then there is a
java.lang.IllegalStateException: No WebApplicationContext found: no ContextLoaderListener registered?
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:252
For now I am going to work around it by calling SimpMessaging from Controller, and not Service, but I'd rather a better solution.

Mule: Migrating to the New HTTP Connector

I've upgraded from Mule 3.5.x to 3.6.x and since the old http transport is deprecated in 3.6.x I wanted to migrate to the new HTTP connector.
Here is the original code for calling my webservice:
<http:outbound-endpoint ref="OrderEndpoint" doc:name="GetApprovedOrder">
<cxf:jaxws-client serviceClass="com.acme.orders.IOrderServiceBean"
port="OrderServiceBean_v2_0Port"
operation="getApprovedOrderOp" />
</http:outbound-endpoint>
The point I have got to with the new connector is as follows:
<cxf:jaxws-client serviceClass="com.acme.orders.v2_0.IOrderServiceBean" port="OrderServiceBean_v2_0Port" operation="getApprovedOrderOp" />
<http:request config-ref="http.request.config" path="acme-services/OrderServiceBean_v2_0" method="POST" />
The issue that I have is that with the old version of the code, after calling the web service, the payload would be the response [java] object. With the new version of the code the payload is a org.glassfish.grizzly.utils.BufferInputStream containing the soap xml.
I could use a combination of xpath and a jaxb-xml-object-transformer to convert the contents of the stream to the response object, this just seems like a backwards step though.
I have looked into using the jaxws-client without the request and also at the ws-consumer, but my following requirements seems to rule these options out (unless I'm just misunderstanding how to use them).
I need to use the contract first method for calling the web services, see above where I have specified serviceClass rather than wsdl.
The web services use basic auth, therefore I need to specify a username and password.
I need to be able to specify the host and port (or at least the address) of the web service.
The solution is: wrap your element into a processor-chain
As follows:
<processor-chain>
<cxf:jaxws-client serviceClass="com.acme.orders.v2_0.IOrderServiceBean" port="OrderServiceBean_v2_0Port" operation="getApprovedOrderOp" />
<http:request config-ref="http.request.config" path="acme-services/OrderServiceBean_v2_0" method="POST" />
</processor-chain>
This is because cxf is intercepting, so after the processor chain you would have the same object as you had in your previous solution.

Muel-esb: Testing Choice Router

Is there a way to test a choice router for the following scenario which is based on the http.status? I am seeking a way to test the first condition of the router
<flow>
<choice>
<when expression="#[message.inboundProperties['http.status'] !=201">
......
<otherwise>
.....
</otherwise>
</choice>
</flow>
I want to verify that a javax.ws.rs.core.Response with can be correctly handled by the HTTP endpoint.
The flow doesn't have an inbound endpoint (thus it's a private flow) so to test it
create a test flow in a test XML config file that you will load side by side with your other Mule configuration XML files,
add an inbound VM endpoint to this test flow and make it call the private flow you want to test,
in your functional test case, use the Mule Client to dispatch a test message over the VM endpoint, setting properties on this test message that will end-up as inbound properties in the private flow.

Resources