Save Web Service variable into MuleSoft Message - java

I have an http endpoint redirecting to a REST Java web service.
I am receiving a application/x-www-form-urlencoded request with some attributes embedded within the body of the request.
Inside the web service I would like to update the mule message status with those attributes.
Since RequestContext.getEventContext() is now deprecated and Doc says to implement Callable instead, however seems not working to me.The onCall method is never invoked.
Any idea ?
Below my code:
enter code here
#Path("/restClass")
public class HelloREST implements Callable{
private String industry;
private String lob;
private String nuixlegalentity;
private org.apache.log4j.Logger log = Logger.getLogger(LoadClass.class);
#POST
#Path("/setPayload")
#Consumes("application/x-www-form-urlencoded")
public void setMessage(#FormParam("industry") String industryParam, #FormParam("lob") String lobParam,#FormParam("nuixlegalentity") String nuixlegalentityParam){
log.debug("**************INSIDE SETMESSAGE******************");
industry=industryParam;
lob=lobParam;
nuixlegalentity=nuixlegalentityParam;
}
#Override
public Object onCall(MuleEventContext eventContext) throws Exception{
log.debug("**************INSIDE ONCALL******************");
eventContext.getSession().setProperty("industry","industry");
eventContext.getSession().setProperty("lob",lob);
eventContext.getSession().setProperty("nuixlegalentity",nuixlegalentity);
return eventContext.getMessage();
}
}
}

I assume you're using this class as a resource with the Jersey transport. In that case, Mule will call the JAX-RS annotated methods, based on the incoming request, and thus will not call onCall. Therefore implementing Callable is of no use.
Using RequestContext.getEventContext() is the only way possible to get the EventContext in a Jersey-handled resource.
To this date, MuleSoft hasn't provided a workable replacement for cases like this one so, even if RequestContext.getEventContext() is deprecated, you unfortunately have no other choice than using it.

Related

Use variable between JAX-WS requests

I'm trying to do a web application using JAX -WS. My problem seems to be very simple, however I cannot understand how to resolve it. I have class variables which values I need to use in GET and POST requests. For example, I initiate 'response' in GET methode and I need to use it then in POST methode, but when I call POST api/conversation from js I receive an error because 'response' is still null. How can I save value for variables? Here is my code
import javax.ws.rs.*;
#ApplicationPath("api")
#Path("conversation")
public class Conversation {
private final String conversationWorkspace = "myworkspace";
private final static String CONVERSATION_ID = "myid";
private final static String CONVERSATION_PASS = "mypass";
private MessageRequest request;
private MessageResponse response;
private ConversationService service;
#GET
#Produces("application/text")
public String getInitiatePhrase(){
service = new ConversationService("2017-05-26", CONVERSATION_ID, CONVERSATION_PASS);
response = service.message(conversationWorkspace, null).execute(); //here response gets its value
return response.getText().get(0);
}
#POST
#Produces("application/text")
#Consumes("application/text")
public String getBotAnswer(String userText){
System.out.println("response " + response);
request = new MessageRequest.Builder().inputText(userText).context(response.getContext()).build(); //response must not be null
response = service.message(conversationWorkspace, request).execute();
return response.getText().get(0);
}
}
The Java class in question does not seem to be a container managed bean. When you make a rest service call to the GET and subsequently the POST methods, two separate instances of the Conversation class are created. Hence, the class field response will be null in the second POST call.
There are multiple ways to solve this problem. However, the approach to take depends on answering the question: Should the service really be aware of two separate client requests? Or should the client make one GET call and then provide the subsequent POST with the required information.
I would use approach 1 noted below, unless there is a good reason to use either 2, 3 or 4. (2, 3 and 4 are similar just they are different specifications / frameworks)
The client caches the response of the GET and sends the required information back with the POST request
Use an EE stateful session bean (http://docs.oracle.com/javaee/6/tutorial/doc/gipjg.html)
Use a CDI session scoped bean (http://docs.oracle.com/javaee/6/tutorial/doc/gjbbk.html)
Use spring session scoped bean (http://springinpractice.com/2008/05/08/session-scoped-beans-in-spring / https://tuhrig.de/making-a-spring-bean-session-scoped/)

CXF-Proxy Client and #Suspended AsyncResponse

I recently learned that with JAX-RS 2.0 long running service endpoints can make use of the #Suspended annotation and AsyncResponse to free resources for incoming requests while the actual work is done in the background. All client examples - at least the ones I found so far - are either calling such endpoints directly (plain http-call) or make use of the JAX-RS client API. However I was not able to figure out how to use this with the proxy-based API.
Given a REST endpoint that uses #Suspended:
public interface HeavyLiftingService {
#GET
#Path("/heavylifting")
public void heavyLifting(#Suspended final AsyncResponse aResponse);
}
its implementation using Spring:
#Component
public class HeavyLiftingServiceImpl implements HeavyLiftingService {
#Override
#Async
public void heavyLifting(#Suspended final AsyncResponse aResponse) {
final Result result = doHeavyLifting();
aResponse.resume(result);
}
}
And a proxy-based client, that wants to obtain the result:
HeavyLiftingService proxy = JAXRSClientFactory.create("https://some-server.xyz", HeavyLiftingService.class);
proxy.heavyLifting(null); // what to put in here?
Result result = null; // how can I get the result?
Obviously there are two problems:
What do I need to provide to the heavyLifting method as value for the AsyncResponse parameter?
How can I get the result as the return type of methods using #Suspended has to be void?
And another question is how exceptions in the service method are handled. Will an exception automatically resume the response and return a corresponding error status?

How to use Jersey's internal routing mechanism to extract a class/method reference?

I have a Jersey 1.8 application running. Jersey is running as a Servlet.
I need to write a servlet filter that given a plain request/response, is able to figure out which REST resource/method will respond to the request and extract values from annotations.
For example, imagine I have the following resource:
#Path("/foo")
#MyAnnotation("hello")
public class FooResource {
#GET
#Path("/bar")
#MyOtherAnnotation("world")
public Response bar(){
...
}
}
When a request GET /foo/bar comes in, I need my servlet filter to be able to extract the values "hello" and "world" from MyAnnotation and MyOtherAnnotation before Jersey's own servlet processes the request.
This filter logic should be able to work for all requests and all resources registered.
Is there a way to access Jersey's internal routing mechanism to obtain a class/method reference where Jersey will dispatch the request?
I'm open to other suggestions as well, but ideally nothing like trying to hack my own routing mechanism by reading the #Path annotations myself.
#Provider
#Priority(Priorities.AUTHORIZATION)
public class MyFilter implements ContainerRequestFilter
#Context // request scoped proxy
private ResourceInfo resourceInfo;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
if (resourceInfo.getResourceClass().isAnnotationPresent(MyAnnotationion.class) ||
resourceInfo.getResourceMethod().isAnnotationPresent(MyOtherAnnotation.class)) {
to register the filter use
bind(AuthFilter.class).to(ContainerRequestFilter.class).in(Singleton.class);

Using a SOAPHandler with spring-boot SOAP web service

I have created an application by following the guide on
http://spring.io/guides/gs/producing-web-service/
Executing the webservice 'getCountry' works fine but now I need to intercept the SOAP message somehow before getCountry is executed.
I created a class that implements 'SOAPHandler' but somehow I have to tell spring-boot to use this handler before passing the request to getCountry.
Any idea how to do that?
you need to implement an interceptor like:
public class YourClientInterceptor implements ClientInterceptor{
#Override
public boolean handleRequest(MessageContext messageContext)
{
//here you get your request before it is sending
messageContext.getRequest()
...
return true;
}
}
and when you create your WebServiceTemplate you do:
ClientInterceptor[] interceptors = {new YourClientInterceptor ()};
yourWebServiceTemplate.setInterceptors(interceptors);
They work similar with handler.

How to use two web methods for two different operations using Restful webservices?

I am using Jersey Restful webservices. I have below web method to get the results.
#Path("/persons")
public class PersonWS {
private final static Logger logger = LoggerFactory.getLogger(PersonWS.class);
#Autowired
private PersonService personService;
#GET
#Path("/{id}")
#Produces({MediaType.APPLICATION_XML})
public Person fetchPerson(#PathParam("id") Integer id) {
return personService.fetchPerson(id);
}
#DELETE
#Path("/{id}")
public void deletePerson(#PathParam("id") Integer id) {
return personService.deletePerson(id);
}
}
In above Jersey RESTful webservice, i have two web methods one for get and one more for delete with same number of parameters. In above case will there be any ambiguity? If not what should be the URIs for both of the methods? Thanks!
Thanks!
Jersey decides which method to call based on the HTTP method specified in the request. If you use multiple methods with the same HTTP method like GET, then the choice is made by more Annotations like Consumes or Produces etc.
BTW: If you use the URI /persons/{id} for all endpoints, then you can annotate your class with #Path("/persons/{id}") instead of annotating every method with this sub-URI.
There is no ambiguity as the HTTP Method is different (GET vs DELETE).
The same url would also be used to update the object, using the HTTP method PUT
No ambiguity since the HTTP methods used are different i.e GET and DELETE
And the urls will be same as the param required is "id" for both
IN Jersey client program use GET http method for fetching person info, Use DELETE http method for deleting the person.

Categories