Spring Cloud gateway do not invoke the origin service - java

Im using the the spring cloud gateway for the first time. my service endpoint is http://localhost:8080/student/getlist
Problem is that when im trying to invoke my service using the cloud gateway it's giving me 404. the eureka is showing the service URL correctly
my gateway properties are below
spring.application.name=gateway
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka
server.port=8085
management.endpoints.web.exposure.include=*
spring.cloud.gateway.discovery.locator.enabled=true
spring.cloud.gateway.routes.id=student-service
spring.cloud.gateway.routes.uri=lb://student-service
spring.cloud.gateway.routes.predicates.Path=/student/**
below is the actuator routes in gateway
[{"route_id":"CompositeDiscoveryClient_GATEWAY","route_definition":{"id":"CompositeDiscoveryClient_GATEWAY","predicates":[{"name":"Path","args":{"pattern":"/GATEWAY/**"}}],"filters":[{"name":"RewritePath","args":{"regexp":"/GATEWAY/(?<remaining>.*)","replacement":"/${remaining}"}}],"uri":"lb://GATEWAY","order":0},"order":0},{"route_id":"CompositeDiscoveryClient_STUDENT-SERVICE","route_definition":{"id":"CompositeDiscoveryClient_STUDENT-SERVICE","predicates":[{"name":"Path","args":{"pattern":"/STUDENT-SERVICE/**"}}],"filters":[{"name":"RewritePath","args":{"regexp":"/STUDENT-SERVICE/(?<remaining>.*)","replacement":"/${remaining}"}}],"uri":"lb://STUDENT-SERVICE","order":0},"order":0}]
im trying to invoke the service endpoint trough the gateway via
http://localhost:8085/student/getlist
above URL but this not working.
What am i doing wrong. there is no context path to any microservices.
sample code is under
https://github.com/ojith97/sample.git

Try change your properties to
spring.cloud.gateway.routes[0].id=student-service
spring.cloud.gateway.routes[0].uri=lb://student-service
spring.cloud.gateway.routes[0].predicates[0]=Path=/student/**

You must make the gateway aware of the eureka server with this
eureka.client.service-url.defaultZone=http://user:pass#localhost:8761/eureka
And then make prevent the gateway register to eureka
eureka.client.register-with-eureka=false
The second option is important as it causes 404 errors with loadbalancing using lb:servicename structure.

Related

Make Spring SAML SP work with other port than 8080

I'm using this sample project from vdenotaris as the SP, and I'm building a POC of an IDP using spring boot. I ran into an issue which was answerered by the repo owner here
However I don't need to register yet my SP on the IDP (since the IDP isn't implemented) but my end project needs to run on the port 8080, and that's causing me conflicts with the Service Provider (sample project), how can I make it work for another port?
Vincenzo states in the issue the following:
The application is pre-registered on SSO Circle, with localhost:8080 as endpoint (static).
If you would like to use another port, you need to:
change the default EntityId
make a brand-new registration on SSO Circle (or any other IdP)
But I don't understand how to change the default EntityId
What have I tried so far? adding server.port=9090 to the application.properties, and I'm able to run his project just fine, but when I send the assertion back from the IDP => SP I keep getting a 404..
I'm kinda new into Java and Spring so any help will be great, I'm stuck in here.

Zuul Gateway Server is not showing any routes

I am have created an Gateway Server and registered it with Eureka. Below it is the bootstrap class:
#SpringBootApplication
#EnableZuulServer
#EnableDiscoveryClient
public class GatewayServerApplication {
...
}
I have integrated Zuul Gateway Server with Eureka Server. Everything is going OK. Eureka is starting successfully and the also the Gateway Server is starting successfully.
Nevertheless, I am having trouble accessing the routes. Below is the link that i am trying to access:
https://localhost:5555/actuator/routes
Please, help me with this issue.
Thanks in advance.
P.S my configuration information for gateway server in application.properties file:
#Application
server.port=5555
#Eureka
cloud.config.enabled=true
eureka.instance.preferIpAddress=true
eureka.client.registerWithEureka=true
eureka.client.fetchRegistry=true
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka-server/
#Actuator
management.endpoints.web.exposure.include=*
management.security.enabled=false
Change the #EnableZuulServer to #EnableZuulProxy, like below:
#SpringBootApplication
#EnableZuulProxy
#EnableDiscoveryClient
public class GatewayServerApplication {
...
}
You have two option for creating Zuul Gateway Server:
The first one is to use #EnableZuulServer annotation. This annotation creates a Zuul Server but doesn't offer the Zuul pre-built routing capabilities. You use this annotation when you want to build your own routing service.
The second option is to use the #EnableZuulProxy annotation. This annotation creates Zuul Server, loads the Zuul Reverse Proxy Filters, and automatically uses Eureka Server to lookup services by their service IDs and then use Netflix Ribbon to do client-side load balancing of requests from within Zuul.
I think in your case is more suited to use #EnableZuulProxy annotation because you don't want to build your own custom service.

Spring Cloud - Configuration client caching properties

When I change a value from my properties repository and restart the Spring Cloud Config Server, the changes do not reflect on it's consumers.
my-microservice/application.properties:
spring.application.name=my-service
spring.cloud.config.uri=http://localhost:8888
MyServiceController.java
#RestController
public class MyServiceController {
#Autowired
private Configuration configuration;
#GetMapping("/my-service")
public MyServiceBean retrieveMyServiceProperties() {
// show propertie's values
return new MyServiceBean(configuration.getPropertie1(), configuration.getPropertie2());
}
}
spring-cloud-config-server/application.properties
server.port=8888
spring.application.name=spring-cloud-config-server
spring.cloud.config.server.git.uri=file://path
Git repo
my-service.properties
my-service.propertie1=1
my-service.propertie2=2
When I send a GET request to localhost:8080/my-service, that's the result I got:
{
"propertie1":1,
"propertie2":2
}
Fine, that's OK!
But, if I change the my-service.properties and restart my Spring Cloud Config Server, the changes do not reflect MyServiceController. I do need to restart my-microservice application, for changes to take effect.
Is this the normal behavior? I mean, if this is remote, then, it should be configured whether to cache or not.
In order to update the configurations, I sent a POST request to localhost:8080/actuator/refresh.
By default, /refresh isn't exposed in actuator endpoints.
I did exposed with the following line in application.properties:
management.endpoints.web.exposure.include=*
Then, sent a POST request with no body to the endpoint above.
To update your client application, It's better to use a message broker like RabbitMQ or Apache Kafka.
This process has three levels:
The client application and config server subscribe to a specific topic (/refresh) in the message broker.
The config server sends refresh event to that topic (/refresh), as soon as it gets updated. (for example application.properties file gets updated in git).
All client applications are listening to refresh event, when they get refresh message, they will be updated
In brief, we can use the pub-sub model for updating our client applications.
Config Server using Spring Cloud Config and Apache Kafka

Spring Cloud: How to define default fallback for Hystrix in Zuul gateway?

I am using Spring Cloud Brixton.M3 and Spring Boot 1.3.0.RELEASE. I am sort of new in this (especially in Spring Cloud). I have created Registry Server (i.e. Eureka instance), Config server and Gateway.
As per my requirement I am intercepting each request hitting the gateway in one of my Filter to extract required information from Header and based upon that I am throwing exception or forwarding / verifying that request using Feign Client. Some time hystrix throw HystrixRuntimeException when it couldn't reach out to respective services or because of any other issues.
So What I want is:
Provide default fallback method for every forwarding request, so that I can read and process it accordingly.
Global Exception handling other than #ControllerAdvice since I am not providing any custom #HystrixCommand and Controller to call services (AOP based solution ?).
Is it possible to intercept every failed request and retry them for certain number of times ? Internally it might be happening but can I override this functionality and handle each failed request either because of TimedOutException or because of HttpConnectionPool exception ?
Update
Is it a good practice to provide own routing in Zuul gateway ? using #RestController and #HystrixCommand together ? (I think its a bad idea, because over the period of time we will end up with lots of controllers and hence actual use of intelligent routing wouldn't work as expected)
Currently there is an open issue for fallbacks with feign. There is also an open issue for fallbacks with zuul.

How can I get the Discovery Client working when using spring-cloud together with netflix Eureka?

I'm trying to make a basic project using spring cloud with the netflix addons such as Hystrix, Eureka and Ribbon to learn how this works. The project I'm trying to make is a simple message server that will keep messages. And a message-client that will just ask the server for a message, and I want to use the auto discovery client for this, or the RestTemplate discovery. But I can't get either to work.
I have the following structure:
message-client (eureka client)
message-server (eureka client)
configuration-service (config server)
discovery-service (eureka server)
What I currently do is I start up the configuration-service, and expose the application.yml details to all of these "apps/clients" when they are connecting by the following structure:
config-service\src\main\resources\config\appname.yml
app\src\main\resources\bootstrap.yml (contains the appname and url to cloud config)
This is working just fine, and my apps start up on the port they receive from the config server, as well as they all connect to my eureka server, and all of them are visible there. As well as the Hystrix failover is also working, not that it is related to this but it tells me that it can't be completely wrong then.
But here comes my confusion...
When using the #Autowired annotation in my service class (#Service annotated) inside my client module, I get a discoveryClient object, but I am unable to find any other services using that one.
Message Client - boot class:
#EnableAutoConfiguration
#EnableHystrix
#EnableEurekaClient
#ComponentScan("cloud.rest.resources, spring.cloud.client")
public class ClientBoot {
public static void main(String[] args) {
SpringApplication.run(ClientBoot.class, args);
}
}
Message Client - REST Resource:
#RestController
public class MessageResource {
#Autowired
private MessageClient messageClient;
#RequestMapping(value = "/message/{client}", method = RequestMethod.GET)
public Message getMessage(#PathVariable String client) {
return messageClient.getMessage(client);
}
}
Message Client - MessageClient:
#Service
public class RestMessageClient implements MessageClient {
#Autowired
private DiscoveryClient discoveryClient;
#Autowired
private RestTemplate restTemplate;
#Override
public Message getMessage(String client) {
return restTemplate.getForObject(String.format("http://message-server/message/%s", client), Message.class);
}
}
My message server boot class that is holding the messages has the same annotations as my client one.
And as I said, my service class are unable to find anything..
Which leads me to all of my questions:
What is required to actually use ribbon load balancer?
Do I have to use ribbon to be able to use the "auto discovery", I thought not but now I'm just confused.
From what I've understood, when using EnableEurekaClient I should not need to use the EnableDiscoveryClient as well?
Can I change the yml files on my config-server for the clients in runtime and just have to reboot the client?
How much configuration is really meant to be shared by the config-server, because currently all of my clients just contain a super basic bootstrap.yml file.
Does anyone have a good link to where I can read more about all the properties that is being set in my yml files? Both a documentation of what the properties that exists actually do as well as some documentation on how I can use them in combination with spring cloud?
Do I need specific properties to enable my apps/clients to find other apps/clients?
Edited information
Thank you for your quick and excellent reply, I've gone through this over and over today and I finally got my application working..
The problem (I can't understand why and was hoping you could help me understand that) is that my discovery service contains yml files for each of my other clients where I specify things like port and eureka information.. What I specified here as well was:
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka
So, when I set this value it seems to override something that makes my service discovery not working.. Even tho I can see all my applications in the eureka server, they were unable to find each other when I had this value set.
I set this value by having a message-server.yml file in my configuration service that is sent out to my message-server application after bootstrap..
So then I have two new questions.
How do I override this eureka server property?
Why does my discovery client stop working when I set this value, what is it that it actually does?
What is required to actually use ribbon load balancer?
The ribbon-loadbalancer must be on the classpath (e.g. via "spring-cloud-starter-ribbon"). Then you can inject one as a LoadBalancerClient or you can inject a RestTemplate (it will be load-balancer aware if you have a LoadBalancerClient).
Do I have to use ribbon to be able to use the "auto discovery", I thought not but now I'm just confused.
What is "auto discovery"? You don't need to use Ribbon to use the DiscoveryClient (Ribbon is a load balancer, not a service registry).
From what I've understood, when using EnableEurekaClient I should not need to use the EnableDiscoveryClient as well?
Correct. #EnableEurekaClient is annotated with #EnableDiscoveryClient so it is only there to express a preference.
Can I change the yml files on my config-server for the clients in runtime and just have to reboot the client?
Yes. Or you can use the /refresh or /restart endpoints (a full reboot is probably best in production, at least periodically).
How much configuration is really meant to be shared by the config-server, because currently all of my clients just contain a super basic bootstrap.yml file.
As much as you want. How long is a piece of string? If I were you I would try and keep the central config to a minimum (only the things that change between environments, or at runtime).
Does anyone have a good link to where I can read more about all the properties that is being set in my yml files? Both a documentation of what the properties that exists actually do as well as some documentation on how I can use them in combination with spring cloud?
Spring Boot and Spring Cloud have autogenerated metadata for externalized properties. The new generation of IDEs understands them (so get STS 3.6.4 or IDEA 14.1), and they are listed in the user guide (for Spring Boot at least) under http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#common-application-properties
Do I need specific properties to enable my apps/clients to find other apps/clients?
You need to be able to locate your service registry (Eureka in this case). If you are using Eureka and your clients have registered then that is enough.

Categories