How to inject Feign Client with out using Spring Boot and call a REST Endpoint - spring

I have two Java processes - which get spawned from the same Jar using different run configurations
Process A - Client UI component , Developed Using Spring bean xml based approach. No Spring Boot is there.
Process B - A new Springboot Based component , hosts REST End points.
Now from Process A , on various button click how can I call the REST end points on Process B using Feign Client.
Note - Since Process A is Spring XML based , right at the moment we can not convert that to Spring boot. Hence #EnableFeignClients can not be used to initialise the Feign Clients
So Two questions
1) If the above is possible how to do it ?
2) Till Process A is moved to Spring boot - is Feign still an easier option than spring REST template ?

Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSockets and you can easily use feign without spring boot. And Yes, feign still better option to use because Feign Simplify the HTTP API Clients using declarative way as Spring REST does.
1) Define http methods and endpoints in interface.
#Headers({"Content-Type: application/json"})
public interface NotificationClient {
#RequestLine("POST")
String notify(URI uri, #HeaderMap Map<String, Object> headers, NotificationBody body);
}
2) Create Feign client using Feign.builder() method.
Feign.builder()
.encoder(new JacksonEncoder())
.decoder(customDecoder())
.target(Target.EmptyTarget.create(NotificationClient.class));
There are various decoders available in feign to simplify your tasks.

You are able to just initialise Feign in any code (without spring) just like in the readme example:
public static void main(String... args) {
GitHub github = Feign.builder()
.decoder(new GsonDecoder())
.target(GitHub.class, "https://api.github.com");
...
}
Please take a look at the getting started guide: feign on github

Related

Calling a SOAP Web service using spring integration dsl

I need to call a SOAP Webservice from my REST service. I'm using Spring integration in my project. Currently I'm using xml based configuration to achieve the target. But I want to write code in java dsl. Kindly help me how to call a SOAP service from a REST Service using Spring integration DSL.
One example would be really helpful.
See the documentation: https://docs.spring.io/spring-integration/docs/current/reference/html/ws.html#webservices-dsl
#Bean
IntegrationFlow outboundMarshalled() {
return f -> f.handle(Ws.marshallingOutboundGateway()
.id("marshallingGateway")
.marshaller(someMarshaller())
.unmarshaller(someUnmarshalller()))
...
}
or
.handle(Ws.simpleOutboundGateway(template)
.uri(uri)
.sourceExtractor(sourceExtractor)
.encodingMode(DefaultUriBuilderFactory.EncodingMode.NONE)
.headerMapper(headerMapper)
.ignoreEmptyResponses(true)
.requestCallback(requestCallback)
.uriVariableExpressions(uriVariableExpressions)
.extractPayload(false))
)

Override URL and Authentication configuration of Spring Cloud Feign client

I am trying to leverage Spring Cloud Feign client for declaring rest endpoints(third-party-endpoints) which will be called based on the request that my controller receives.
I have declared a feign client interface like:
#FeignClient(name = "my-client", url = "https://abc.xyz.com", configuration = MyClientConfiguration.class)
public interface MyFeignClient{
}
MyClientConfiguration is an unannotated feign configuration class just exposing BasicAuthRequestInterceptor bean preconfigured with some credential.
public class MyClientConfiguration {
#Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor(){
return new BasicAuthRequestInterceptor("USERID","PWD");
}
}
So, what I have right now is a preconfigured feign client.
I am not sure how do I deal with the requirement that asks for being able to define/override the feign configuration with the url and credentials received in the body of different POST request.
So its not about overriding the feign configuration via properties file(like other somewhat similar SO questions), but instead being able to configure the feign client on the fly based on the url and credentials received in the body of the incoming requests.
I am aware of ways to do it with WebClient and looking for something similar to what WebClient provides via its uri and headers methods. Webclient allows us to override the webClient bean configuration with different uri and different auth credentials,
webClient
.put()
.uri("base-uri", uriBuilder -> uriBuilder.path("/rest").path("/api").path("/2").path("/issue").path("/" + id).build())
.headers(httpHeaders -> {
httpHeaders.setBasicAuth("decrypted-username", "decrypted-pwd");
})
Does Spring Cloud Feign provide any such facility where it is possible to have a generic configuration yet allowing to override those configurations at runtime?
EDIT 1 : START
The closest I got to is implementing via the feign's builder pattern :
MyFeignClient myFeignClient = Feign.builder()
.contract(new SpringMvcContract())
.requestInterceptor(new BasicAuthRequestInterceptor("decrypted-username", "decrypted-pwd")
.target(MyFeignClient.class, myRequestDTO.getBaseUrl());
I was challenged with an exception because I didn't specify which Contract to use. It was using the Default Contract.I then changed to SpringMvcContract as the annotation that I am using are the Spring MVC ones and not feign's default.
Getting DecodeException as of now. Trying to fix it. Will post update when done.
EDIT 1 : END
EDIT 2 : START
I was finally able to get this working. I figured out that the feign-gson does a great job at deserialization with minimal configuration.
My final feign configuration with the Decoder in place looks like :
MyFeignClient myFeignClient = Feign.builder()
.contract(new SpringMvcContract())
.decoder(new GsonDecoder())
.requestInterceptor(new BasicAuthRequestInterceptor("decrypted-username", "decrypted-pwd")
.target(MyFeignClient.class, myRequestDTO.getBaseUrl());
EDIT 2 : END

How to Cache HTTP Requests made with Netflix's Feign library in a Java Spring app

In a spring boot application using Netflix's Feign to make HTTP requests to a service, is there an easy way to cache and return these cached values automatically? The cache should be based on the parameters passed to the request (similar to memoizing a function for X minutes).
I'm looking for something like the #Cache annotation below:
#Component
#FeignClient(value = "facebook", url = "${auth.facebook.url}")
public interface FacebookClient {
#Cache(600) // Something like this.
#RequestMapping(method = RequestMethod.GET, value = "/debug_token?input_token={input_token}&access_token={access_token}")
Map debugToken(#PathVariable("input_token") String inputToken, #PathVariable("access_token") String appToken);
}
Of course I could cache it myself using a decorator around the FacebookClient, I was wondering if there was a quicker/less code way.
Springs #Cacheable does what you need.
Check: Caching Data with Spring
Feign does not support caching. I would prefer the JCache (JSR-107) and maybe use it via the spring-boot-starter-cache described in the spring guide
JCache is an abstraction for the proprietary implementation of EhCache, Hazelcast, ... so it is possible to change the implementation with very less impact on the application. At first I would prefer EhCache 3.
Feign client doesn't support caching.
Another better way would be to create a Service class which calls FeignClient and put up cache on methods of this new Service class.

How to test REST in spring app with spring security

I've got spring web application with jersey rest services. However rest is secured via spring security and login process is very hard to perform from unit test code. I'd like to test rest services with whole spring security disabled. Is it even possible?
One of the advantages of annotation based web services is that you can unit-test them easily.
class WebServiceEndpoint {
#Path("/foo/{fooId}")
#POST
#Produces({ MediaType.APPLICATION_XML })
public Response doFoo(#PathParam("fooId") Integer fooId) {
/// ... web service endpoint implementation
}
}
If you're using Spring's servlet filter for security, then there shouldn't be any security-related code in the doFoo method, so you can just create a new WebServiceEndpoint class and call the method. So that's one way of 'disabling' security.
When you say the login process is 'hard', what do you mean? If you've succeeded in logging in once, then you can just reuse the same code in your other unit tests (e.g. in a #Before method).
Just test it as a pojo. Pass in whatever, return whatever, don't load an app context at all - that would be an integration test.
The ability to easily test functionality without the framework loaded is one of the key advantages of spring.
You don't say what's "hard," so I'm assuming that you've got something in your REST service, i.e. in the java method that you want to test, which requires authentication results. Spring has utilities for mocking the authentication results. For example, you can do the following in a #Before setup method:
Object principal = null; // fix this
Object credentials = null; // fix this
Authentication auth = new org.springframework.security.authentication.TestingAuthenticationToken(principal, credentials);
SecurityContextHolder.getContext().setAuthentication(auth);
But again, you haven't said what problem you're actually trying to solve...

How to consume REST URLs using Spring MVC?

I have developed few RESTful methods and exposed them via Apache Cxf
I'm developing the client side application using Spring MVC and I'm looking for a simple example to demonstrate how to call/consume these REST methods using Spring MVC
I know how to do it using Apache http client but prefer to use Spring MVC in case such this has already been implemented there.
Spring provides simple wrapper to consume RESTful services called RestTemplate. It performs path variable resolution, marshalling and unmarshalling:
Map<String, Integer> vars = new HashMap<String, Integer>();
vars.put("hotelId", 42);
vars.put("roomId", 13);
Room room = restTemplate.getForObject(
"http://example.com/hotels/{hotelId}/rooms/{roomId}",
Room.class, vars);
Assuming Room is a JAXB object which can be understood by The RestTemplate.
Note that this class has nothing to do with Spring MVC. You can use it in MVC application, but also in a standalone app. It is a client library.
See also
REST in Spring 3: RestTemplate
Use path variables to consume REST data. For example:
https://localhost/products/{12345}
This pattern should give you the detail of the product having product id 12345.
#RequestMapping(value="/products/{productId}")
#ResponseBody
public SomeModel doProductProcessing(#PathVariable("productId") String productId){
//do prpcessing with productid
return someModel;
}
If you want to consume Rest Service from another service then have a look at:
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/client/RestTemplate.html
and
http://www.informit.com/guides/content.aspx?g=java&seqNum=546

Resources