I am trying to accomplish each time when I start my app, to get from the RabbitMQ API, all the queues and exchanges that exist. But unfortunately I get the following error:
org.springframework.web.client.HttpClientErrorException$Unauthorized: 401 Unauthorized: [no body]
My code:
application properties file :
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.addresses=localhost:8080/api/
rabbitmq-api-url = http://localhost:8080/api/
Component that executes each time on startup:
#Component
public class StartupCLass implements ApplicationListener<ApplicationReadyEvent> {
#Value("${rabbitmq-api-url}")
private String endpoint;
#Override
public void onApplicationEvent(ApplicationReadyEvent event) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity(endpoint+"queues",String.class);
}
}
What I am trying to accomplish is the following:
I have some queues and exchanges defined on my RabbitMQ server. I have also exported the definitions json file and modified it with renaming some of the queues/exchanges. I want to check when starting the app, which queue or exchange has been renamed regarding the json file and the current state of the rabbit mq server (that's why I want to get from the API the queues)
401 means unauthorized. So you have to pass username and password in the request.
restTemplate.getInterceptors().add(
new BasicAuthorizationInterceptor("username", "password"));
Read more here:
https://www.baeldung.com/how-to-use-resttemplate-with-basic-authentication-in-spring
Related
I am new to Spring Cloud Gateway and I am struggling to debug a 404. The current gateway flow has our web app sending an HTTP request to our Gateway with a SESSION Cookie value. It takes this cookie value and sends it to micro-service A and micro-service b to have them both authenticate the request. Then once the request is authenticated it makes a request again to micro-service A to obtain the data that requested. This request fails instantly at micro service A with the following error org.springframework.web.serverlet.PageNotFound: No mapping for SES ION=<session cookie value>. It seems that somewhere in the flow the HTTP Request from Spring Cloud Gateway to micro-service A changes from a GET request to the cookie value. Has anyone ran into this before or know how I could debug this?
The Filter:
#Component
public class Filter {
private final AuthFilter authFilter;
public Filter(final AuthFilter authFilter) {
this.authFilter = authFilter;
filters =
f ->
f.filter(authFilter)
.rewritePath(
"/api/v1/(?<segment>.*)",
"/${segment}"
)
}
}
#Component
#RequiredArgsConstructor
public class AuthFilter implements GatewayFilter {
#Override
public Mono<Void> filter(final ServerWebExchange exchange, final GatewayFilterChain chain) {
// user validation request
// just a rest template get and checks for a 200
// permission check
// just a rest template post and checks for a 200 and the response is not null
// requests pass both auth checks
return chain.filter(exchange);
}
I am unsure what other code I can provide as in the other micro-service it does not reach any of our code. Thanks for any help in advance
I am trying to push/get values to salesforce using camel with java. When I try to send data I get the following error :
HTTP protocol violation: Authentication challenge without WWW-Authenticate header
The strange part is that it work like a charm when I subscribe to data with routes /data/AccountChangeEvent
public class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() {
from("salesforce:/data/AccountChangeEvent?replayId=-2")
.bean(clientService, "accountChange");
from("direct:updateSalesforce")
.to("salesforce:createSObject?sObjectName=Account");
}
}
public class SalesforcePublisherService {
#Autowired
CamelContext camelContext;
public void publishToSalesforce(String endpointUri, Object body) {
Map<String, Object> values = new HashMap<>();
// [...] Putting some values
camelContext.createProducerTemplate().requestBody("direct:updateSalesforce", values);
}
}
I found out what the problem was.
First I found out that the error was really different from what was written. In order to investigate on that part I activated Jetty's logs with :
-Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
-Dorg.eclipse.jetty.LEVEL=DEBUG
Then I reproduce the call on my postman and I got the message from this 401 error. After some investigation the problem was related with how I generated my refresh token:
I shouldn't have used the scope "refresh_token" when generating the salesforces token (actually no scope is needed).
I need to send HTTP requests from my Quarkus application. Following this guide, I have this RestClient:
#Path("/v1")
#RegisterRestClient
public interface CountriesService {
#GET
#Path("/name/{name}")
Set<Country> getByName(#PathParam String name);
}
In the Path annotation, I can configure the path. But the domain/url to call is defined in a configuration file, according to this paragraph.
# Your configuration properties
org.acme.rest.client.CountriesService/mp-rest/url=https://restcountries.eu/rest #
org.acme.rest.client.CountriesService/mp-rest/scope=javax.inject.Singleton #
In my case, I need this URL to be defined programmatically at runtime, as I receive it as a callback URL.
Is there a way to do that?
Quarkus Rest Client, and Quarkus Rest Client Reactive, implement the MicroProfile Rest specification and as such allow creating client stubs with RestClientBuilder programmatically, e.g.:
public class SomeService {
public Response doWorkAgainstApi(URI apiUri, ApiModel apiModel) {
RemoteApi remoteApi = RestClientBuilder.newBuilder()
.baseUri(apiUri)
.build(RemoteApi.class);
return remoteApi.execute(apiModel);
}
}
See https://download.eclipse.org/microprofile/microprofile-rest-client-2.0/microprofile-rest-client-spec-2.0.html#_sample_builder_usage
You cannot achieve this with client created with the #RegisterRestClient annotation
I have a Spring Boot REST API written in Java. I am using a Feign client to connect to another REST API. The endpoint uses to header parameters, apikey and serviceName.
I get this error when the endpoint calls the feign client.
feign.FeignException: status 401 reading FacilityViewClient#getFacilities(Map,String,String)\r\n\tat feign.FeignException.errorStatus(FeignException.java:78)
This is how I have implemented the feign client with header parameters:
#GetMapping(path = "/schedule-svc/api/v1/facilities")
FacilitiesViewResponse getFacilities(#RequestHeader Map headers,
#RequestParam("facilityType") String facilityType,
#RequestParam("stateProvinceCode") String stateProvinceCode);
This is the call using the feign client:
Map<String, Object> headerMap = new HashMap<>();
headerMap.put("apikey", "xxxxxxx" );
headerMap.put("SERVICE-NAME", "Location");
FacilitiesViewResponse facilitiesViewResponse = facilityViewClient.getFacilities( headerMap,"RALYD", "PA");
I have also tried to use individual #RequestHeader string parameters and get the same error. Like this:
#RequestHeader("apikey") String apiKey
#RequestHeader("SERVICE-NAME") String serviceName
The same error occurs.
I can hit the service using Postman and the header information looks like this:
Are there other properties that need to be defined in the feign client to successfully set the header parameters
we solved this problem. The url and path were wrong on the FeignClient. The error was misleading us to think it was an unauthorized error when actually it was a 404 error.
Add below code in your feign client configuration (in application.yml file)
feign:
hystrix:
enabled: true
I have a Spring webservice #Controller class with a #MessageMapping annotated method as follows:
#MessageMapping("/trade")
public void executeTrade(MarketOrderRequest trade, Principal principal) {
trade.setUserID(principal.getName());
logger.debug("Trade: " + trade);
this.tradeService.executeTrade(trade);
}
I am sending a JSON string message built using the same MarketOrderRequest POJO as is accepted by the server method. With some Key:Value pairs which are set null (but are still present).
The WebSocketConfig class has configured the following endpoints:
#Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue/", "/topic/");
registry.setApplicationDestinationPrefixes("/app");
}
When i try to send a message to this messagemapping using this code:
MarketOrderRequest request = new MarketOrderRequest();
//{set request variables..}
StompHeaders someHeaders = new StompHeaders();
someHeaders.putAll(sessionHeaders);
someHeaders.setDestination("/app/trade");
session.send(someHeaders, request);
With headers:
{Cookie=[JSESSIONID=8421F536B639126F84F12E655375D790; Path=/spring-websocket-portfolio/; HttpOnly], version=[1.2], heart-beat=[0,0], user-name=[fabrice], destination=[/app/trade]}
The server then prints that a method cannot be found for the request:
Searching methods to handle SEND /app/trade session=397da625042343b4bac1c913b6d8ec22 application/json;charset=UTF-8
payload={"uuid":null,"symbol":"EUR/USD","price":1.10182,"side":"1","qty":50000,"quoteID"...(truncated)
WebSocketAnnotationMethodMessageHandler[DEBUG] - No matching methods.
The server code is lifted from this project and altered slightly to suit my needs: link
I have added some role-based web socket security in an AbstractSecurityWebSocketMessageBrokerConfigurer implementation class as follows:
#Override
protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
messages
.nullDestMatcher().authenticated()
.simpSubscribeDestMatchers("/user/queue/errors").permitAll()
.simpDestMatchers("/app/**").hasAnyRole("roleA", "roleB", "roleC")
//{some more subscribe dest matchers by role which are working}
}
would this possibly effect the WebSocketAnnotationMethodMessageHandler's attempts to map the request? It is pretty much the only change I have made to the config. My subscribe mappings are working perfectly.
To me it seems that there is a problem finding the method due to either the JSON or Principal parameters. I am sending the correct object type so is this possibly a problem with the User principal? Thanks
There was an error in my WebSocketConfig class.
The #componentscan annotation had the wrong package name. I updated the name to the correct value ( the name of my base package eg "com.my.project" ). Now during deployment in the logs, I can see the controller resources being mapped to the methods in my class.
Eg log output for one method:
Mapped "{[/order],messageType=[MESSAGE]}" onto public void com.my.project.web.PortfolioController.executeOrder(tradeObjects.OrderRequest,java.security.Principal)