route url to external rest conroller using apache camel - java

Is there any way to route all request to specific URI to another projects rest controller?
consider the code below:
#Component
public class CamelSportsRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
restConfiguration()
.component("servlet")
.bindingMode(RestBindingMode.auto);
rest().path("/hello").get().route()
.toD("localhost:9080/hello");
}
}
I want to route all request of /hello to another project rest controller endpoint: localhost:9080/hello but without XML it cant be possible.

See matchOnUriPrefix of jetty and undertown components and bridgeEndpoint option of HTTP component.
This is what you need:
from("undertow:http://localhost:8080/hello?matchOnUriPrefix=true")
.to("http4://localhost:8081/hello?bridgeEndpoint=true");
Also see this another answer to more details https://stackoverflow.com/a/67893371/11052487

Related

How #Consume from Apache Camel does the mapping in Spring Boot project?

I'm learning about Apache Camel routes in Spring Boot projects and I have a project that does extension from some endpoints. The endpoints are not in this project, only the extension is done here. The extension is done using #Consume from org.apache.camel in this way:
#Consume(uri = "direct:products.create.validate.interceptor")
public void executeCreate(RequestWrapper<Product> productWrapper) {
...
}
I try to understand how this direct:products.create.validate.interceptor is mapped to an endpoint from another service. Can somebody explain me how this #Consume annotation does the mapping?
Or another example is this:
#Consume(uri = "direct:listAccountsPostHook")
public void executeCreate(RequestWrapper<Account> accountWrapper) {
...
}
Where should I look to understand how they are mapped? In the controller of the other service? I can't find any example with #Consume. Thank you!
The #Consume annotation in Apache Camel is used to subscribe to a Camel endpoint and consume messages from it. The endpoint can be either a direct endpoint or any other type of endpoint such as a JMS queue or a REST endpoint, depending on your use case.
The endpoint URI, which is specified in the uri attribute of the #Consume annotation, determines where the messages are consumed from. In your example, direct:products.create.validate.interceptor and direct:listAccountsPostHook are both direct endpoints.
In Apache Camel, direct endpoints are in-memory endpoints that allow you to send messages directly to another endpoint in the same JVM. The mapping between the endpoint and the method that consumes the messages is done by Camel's routing engine.
More on Camel Direct endpoints you can read here.
To understand how the messages are being consumed, you should look at the Camel routes that are defined in your project. In a Spring Boot project, you can define your Camel routes in a RouteBuilder class. This is where you would specify the mapping between the direct endpoint and the method that will consume the messages.
For example, if you have a RouteBuilder class that looks like this:
public class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() {
from("direct:products.create.validate.interceptor")
.to("bean:myBean?method=executeCreate");
}
}
In this example, the direct endpoint direct:products.create.validate.interceptor is mapped to the executeCreate method in the myBean bean. The ?method=executeCreate part of the to URI tells Camel to call the executeCreate method on the myBean bean when a message is received at the endpoint.
So, in short, you should look for the Camel routes in your project that define the mapping between the endpoint and the method that consumes the messages.

How to set base url and common rest URL from property file in Quarkus?

I am working on Quarkus application and what I want to do is to set the global path from application.properties file for all rest rest, my application is working but while calling rest request it is giving not found 404.
#ApplicationScoped
public class ABC {
#POST
#javax.ws.rs.Path("/callit")
public Uni<Response> deleteNoti()
{
//whatever logic
}
}
#ApplicationScoped
public class PAR {
#POST
#javax.ws.rs.Path("/callitPar")
public Uni<Response> addNoti()
{
//whatever logic
}
}
And in application.properties file I am configuring below properties:
quarkus.resteasy.path=/rest/*
quarkus.rest.path=/rest/*
quarkus.http.root-path=/myapp
but when I am calling rest request from front-end it is not working, my rest request should be as below:
http://localhost:8080/myapp/rest/callit
http://localhost:8080/myapp/rest/callitPar
What I want is every rest request should start with "/rest/*" and my application base URL should be "/myapp", Let me know how can we achieve it?
Try to annotate your resource classes with #Path("/") and set quarkus.resteasy.path=/rest.
This should result in your described behaviour.
quarkus.rest.path can be removed.

How to validate headers using producerApiDoc property of restConfiguration in Camel REST DSL

I am setting up a validation framework for REST endpoint using Camel REST DSL. I came across RestConfiguration property "producerApiDoc". I have a swagger/openAPI YAML file and trying to pass it as the argument for doing the request validation but the validation doesn't happen. Below is the code for making this configuration.
Here's the Camel REST DSL documentation link!
public class EmployeeRouterConfig extends RouteBuilder {
#Override
public void configure() throws Exception {
// Rest and Swagger configuration
restConfiguration().bindingMode(RestBindingMode.json).producerApiDoc("C:\\project\\workspace\\employee-management\\schema\\Employee-system-services-api-35.yaml")
.component("servlet")
.dataFormatProperty("prettyPrint", "true")
.dataFormatProperty("json.in.enableFeatures",
"FAIL_ON_NUMBERS_FOR_ENUMS,USE_BIG_DECIMAL_FOR_FLOATS" +
",FAIL_ON_UNKNOWN_PROPERTIES,ADJUST_DATES_TO_CONTEXT_TIME_ZONE")
.dataFormatProperty("json.in.disableFeatures", "FAIL_ON_EMPTY_BEANS")
.enableCORS(true).port(env.getProperty("server.port", "8080"))
.contextPath(contextPath.substring(0, contextPath.length() -
2)).apiContextPath("/api-doc") .apiProperty("api.title","Employee Management").apiProperty("api.version", "1.0.0").clientRequestValidation(true);
I'm expecting a validation to take place based on the yaml file specified and to thrown Bad request exception, but actually the validation is not happening and the flow continues with success OK message

Camel With Cxf and Routing

I was doing some research on Camel - CXf integration and am confused about the below scenario.
So i implemented a Rest Endpoint
#Path("/authenticate")
public interface Sample {
#GET
#Path("/handshake")
#Produces(MediaType.TEXT_PLAIN)
public Response handshake();
#POST
#Path("/login")
#Consumes({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML})
#Produces(MediaType.APPLICATION_JSON)
public Response login(LoginRequest request) throws JsonGenerationException, JsonMappingException, IOException;
}
And the implementation as below
public class SampleImpl implements Sample{
#Context
private HttpHeaders headers;
#Autowired
CamelContext context;
public Response handshake()
{
System.out.println("HandShake Executed Successfully");
return Response.status(Status.OK).entity("This is a Message after Routing").build();
}
public Response login(LoginRequest request) throws JsonGenerationException, JsonMappingException, IOException {
System.out.println("The Rquest objecr is Received "+request);
return Response.status(Status.OK).entity(mapper.writeValueAsString(request)).build();
}
}
The Route
<camel:from uri="cxfrs:bean:SampleRestEndPoint?bindingStyle=SimpleConsumer"></camel:from>
routes it into the implementation. But since the implementation returns a response object am confused how to build the routes around this.
Once the call comes into the implementation how can I execute the
other routes and sent a response back?.In this case the implementation returns a custom object.
How are the other routes attached to a CXF route?.
Should my CXF Implemenation always return a void type?. As i see
that, to get access to Exchange object camel need the return type to
be void
Do I completely ignore the implementation and go with the "to" steps
and modify it in exchange body for the required response?.
Any pointers will be appreciated.
Dude, take a look at this - http://bushorn.com/camel-cxf-geocoder-example/
The above example is not REST though, but usage of CXF with Camel route is same.
I will do these mandatory steps:
Avoid beans/custom classes - try to use the camel framework capabilities.
Use XML - Spring/Blueprint DSL
Please look at the following thread.
Apache Camel and web services
I have successfully implemented web service consumption using camel and Apache CXF. If you have doubts, I can help you out.
Thanks,
Gautham
#GauthamHonnavara - that is an implementation of a JS webservice with an assosiated processor however it doesnt assosiate any direct route to the endpoint.Also my question was specific to JAX-RS where you cannot generate a service class from wsdl.
Assume this use case that u need a customer to invoke the endpoint and then go through say another 5 steps, reach out to another webservice etc and then sent a response back. The above implementation sents a response back in the webservice implementation bean itself.
So to avoid this create a simple interface with the producer consumer etc, just like in my question and then make each method void if you want to inject the Exchange( if needed. ) and use below configuration
<!-- Created the CXF End Point For the Calls to Come IN -->
<cxf:rsServer id="RestEndPoint" address="/rest"
serviceClass="com.poc.camel.cxf.service.incoming.xxx"
loggingFeatureEnabled="true" loggingSizeLimit="20">
<cxf:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" >
<!-- <constructor-arg ref="customObjectMapper" type="org.codehaus.jackson.map.ObjectMapper"/> -->
</bean>
</cxf:providers>
</cxf:rsServer>
Trick is to use the service class tag. If the interface is provided there then it doesn't need a concrete implementation from CXF.
Hope this helps. Let me know

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);

Categories