Using Keycloak 4.3.0.Final with dropwizard 1.3.1 - jersey

I am having a problem with integrating keycloak into dropwizard. Keycloak requires the RestEasy client so i had to use the dependency :
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.26.Final</version>
</dependency>
then I create my httpClient :
RxClient<RxCompletionStageInvoker> httpClient = new JerseyClientBuilder(environment)
.using(configuration.getJerseyClientConfiguration())
.buildRx(getName(), RxCompletionStageInvoker.class);
then i try to use the client, for example :
httpClient
.target(path)
.request()
.get();
and i get the error:
java.lang.ClassCastException: org.jboss.resteasy.client.jaxrs.internal.ClientRequestContextImpl cannot be cast to org.glassfish.jersey.client.ClientRequest
when i remove the dependency I get the JercyClient and all httpRequests works find but Keycloak builder fails, when I use RestEasy dependency keyCloak succeeds but all other http requests fails
Have anyone faced this problem before? is there a way to control when to get the resteasy client and when to get the jersey client?

The solution was to use RestEasy dependency but not using the JersyClientBuilder:
Client httpClient = new ResteasyClientBuilder().build();

Related

Why does OAuth2AuthorizedClientService requires spring-boot-starter-web to autowire?

I am trying to write an OAuth2 Client SpringBoot app that :
Does NOT require a web container ( no Tomcat nor Jetty ) ...
To basically send an Authorization bearer header ( either opaque or JWT bearer token ) in an HTTP request to another SpringBoot app that acts an OAuth2 resource server.
Now looking at the documentation here :
https://docs.spring.io/spring-security/reference/5.7/servlet/oauth2/client/core.html#oauth2Client-client-registration-repo
.. it says that both OAuth2AuthorizedClientService and ClientRegistrationRepository should be auto-wired automatically:
#Autowired
private OAuth2AuthorizedClientService oAuth2AuthorizedClientService;
#Autowired
private ClientRegistrationRepository clientRegistrationRepository;
presumably by just having :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
But it turns out that I also need :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
for the auto-wiring to work. Otherwise, I get :
Field oAuth2AuthorizedClientService in org.example.oauth2client.FeignConfiguration required a bean of type 'org.springframework.security.oauth2.client.OAuth2AuthorizedClientService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'org.springframework.security.oauth2.client.OAuth2AuthorizedClientService' in your configuration.
So question is, why is spring-boot-starter-web needed to have the auto-wiring to work ?
I don't want to add a web container as the OAuth2 client SpringBoot app does not require it ( e.g. command-line app ) but needs to consume a REST service from another SpringBoot app running as an OAuth2 resource server.
OK ... I found the answer, though not what I was expecting.
DefaultOAuth2AuthorizedClientManager is asserting and expecting a HttpServletRequest:
https://github.com/spring-projects/spring-security/blob/5.7.x/oauth2/oauth2-client/src/main/java/org/springframework/security/oauth2/client/web/DefaultOAuth2AuthorizedClientManager.java#L144
So the spring security's OAuth2 client only works in the context of where the client app is running in a web server container.
It looks like I then cannot use spring-boot-starter-oauth2-client for apps that are not running in a web server container. ( e.g. command line or batch application ), but why ???
In this case, what options do we have ?

How to use Spring WebClient without Spring Boot

I have a very limited need to be able to make HTTP request. I see WebClient is the new replacement for RestTemplate. But it seems it is impossible to use WebClient, without dragging in the whole of spring boot; which is not what I want to do. Any way to use WebClient without Spring boot?
You can make asynchronous HTTP request using Reactor Netty HttpClient (docs). Spring WebClient uses it under the hood.
Just add dependency
<dependency>
<groupId>io.projectreactor.netty</groupId>
<artifactId>reactor-netty</artifactId>
<version>0.9.11.RELEASE</version>
</dependency>
and make request
HttpClient.create()
.request(HttpMethod.GET)
.uri("http://example.com/")
.responseContent()
.asString()
.subscribe(System.out::println);
I had the same problem and I solved it doing this.
You need to create a logback.xml file in the src / main / resources folder
and copy this
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<statusListener class="ch.qos.logback.core.status.NopStatusListener" />
</configuration>
If you already have this file just add this statusLIstener inside your configuration.
More info: http://logback.qos.ch/manual/configuration.html

Expose metrics from spring application to prometheus without using spring-boot actuator

I have been trying to collect micrometer metrics in a non springboot application and expose them to prometheus.I have added the following dependency and the test method for the same.I would like to know how to proceed and expose the collected metrics to prometheus from my non spring boot application(traditional spring application).
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
<version>1.2.0</version>
</dependency>
public string testmetrics(){
private PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
registry.counter("ws metric collection","tktdoc metrics");
String metricsInfo = registry.scrape();
return metricsInfo;
}
You practically have to expose an HTTP endpoint and configure Prometheus with it; the HTTP endpoint will supply the data for the scrapes.
An example showing how to add the HTTP endpoint by starting up an HTTP Server (your application may already be using one) is here.

Issue in consuming Restful webserive using apache camel reslet framework

I have a Camel Project which runs in 8080 port to consume external restful web service which is a SpringBoot project which runs in port 8082, toproduce employee information based on the end point call. Here I'm trying to consume ResetFul webservice using Apache Camel Restlet. While consuming the webservice every alternative call is failing.
Restlet operation failed invoking http://localhost:8082/employeeController/getEmployeeDetails/12?wsdl with statusCode: 400 /n responseBody:<html><body><h1>400 Bad request</h1>Your browser sent an invalid request.</body></html>
This is the error i'm getting on every alternative call.
Restlet code to consume which is written inside Camel Context.
<to id="getEmployeeDetails" pattern="InOut" uri="restlet:http://localhost:8082/employeeManager/getEmployeeDetails/{employeeId}?restletMethod=GET"/>
SpringBoot code which produces webservice,
#Controller
#RequestMapping(value="employeeController")
public class EmployeeController{
#RequestMapping(value="/getEmployeeDetails/{employeeId}", method=RequestMethod.GET,produces=MediaType.APPLICATION_XML_VALUE)
#ResponseBody
public String getEmployeeDetails(#PathVariable("employeeId") int employeeId) {
//getting the employee information from DB
}
}
The Camel Resetlet dependency added in pom.xml is
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-restlet</artifactId>
<version>2.24.1</version>
</dependency>>
Do i need add any other maven dependency in order to work for every endpoint call? Could you please help me here.
The easiest way to consume Restlet Resources is to use the Restlet HTTP Client:
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>org.restlet.jse</groupId>
<artifactId>org.restlet.ext.httpclient</artifactId>
<version>2.4.0</version>
</dependency>
With a code similar to this:
Component c = new Component();
Client client = c.getClients().add(Protocol.HTTP);
client.getContext().getParameters().add ( "socketTimeout", "1000" );
Response resp = client.handle(new Request(Method.GET, "https://swapi.co/api/people/1/"));
System.out.println("Output: " + resp.getEntity().getText());

Spring-Social-facebook + Spring MVC integration

I am trying to access facebook data via spring social facebook integration using the instructions provided at http://spring.io/guides/gs/accessing-facebook.
But currently i am facing 2 type of problem
When i run example as mentioned in tutorial i get following error
No matching bean of type [org.springframework.social.facebook.api.Facebook] found for dependency
When i run this with #Configuration on FacebookConfig class, i get below mentioned error
A ConnectionFactory for provider 'facebook' has already been registered
Is there a workaround to it?
I have kept the war file with source code at https://skydrive.live.com/redir?resid=EA49CD7184E0E40!168&authkey=!AIkoKKx5-Um8AQE
What version are you using?
Try using the version 1.1.0.RELEASE
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-facebook</artifactId>
<version>1.1.0.RELEASE</version>
</dependency>
If it not works, please try post the stacktrace printed.
You need to create a the beans to your class, please post more information like your pom.xml and your spring context configuration.
Ihad the same problem. Spring Social Facebook will automatically add connection factory based on the configuration in application.properties. This auto-configured connection factory is clashing with the one that you're trying to add. Try just to remove your connection factory you add through addConnectionFactories.
Try to use different setting to load your custom connection factory...
E.g. Instead of using OOTB keys use different keys:
#Facebook Social App Details:
# Commented below 2 OOTB Keys & Bingo it worked.
#spring.social.facebook.appId=APP_ID
#spring.social.facebook.appSecret=APP_SECRET
facebook.app.id=APP_ID
facebook.app.secret=APP_SECRET
This will resolve your problem.

Resources