Closed ccit-spence closed 9 years ago
So for given this configuration:
instructor-service: /instructors/**
Your spring data rest app produces this url:
http://localhost:8765/instructors/instructors{?page,size,sort}
The first :8765/instructors
is the mapping you gave for zuul to match on. The second: /instructors{?page,size,sort}
comes from spring data rest. It looks funny because they match.
We do something similar in our spring-cloud-samples/customer-stores.
This issue tracked some of our conversation.
Spring should find the appropriate headers and replace the host:port/prefix when creating the links: https://jira.spring.io/browse/SPR-12500
We had to pass headers to Traverson (if your using that) here and here
I am using Traverson, the immediate concern is this would cause problems with CORS and with SSL. Correct?
I am using an old sample of the customer/stores example. Will update to the newer version.
If the javascript tries to access urls on different domains it would be a problem, but the scheme (http[s]), domain and port should be replaced properly
Sounds good, will update the services with the headers fix. Thanks for the answers!
I have tried the headers now and seeing the same behavior with showing the direct URL of the integrated service. Is this actually fixed? I am using the BUILD-SNAPSHOT.
@ccit-spence when I hit the customer-stores-ui proxy here: http://ui.local.spring.io:9900/customers/1
I get the following response
{
"id" : 1,
"firstname" : "Oliver",
"lastname" : "Gierke",
"address" : {
"street" : "625 Avenue of the Americas",
"zipCode" : "10011",
"city" : "New York",
"location" : {
"latitude" : 40.740337,
"longitude" : -73.995146
}
},
"_links" : {
"self" : {
"href" : "http://ui.local.spring.io:9900/customers/1"
},
"stores-nearby" : {
"href" : "http://ui.local.spring.io:9900/stores/search/findByAddressLocationNear?location=40.740337,-73.995146&distance=50"
}
}
}
You'll see both hrefs have the host and port of the proxy.
If I hit the customers service directly here: http://customers.local.spring.io:9000/customers/1 I get
{
"id" : 1,
"firstname" : "Oliver",
"lastname" : "Gierke",
"address" : {
"street" : "625 Avenue of the Americas",
"zipCode" : "10011",
"city" : "New York",
"location" : {
"latitude" : 40.740337,
"longitude" : -73.995146
}
},
"_links" : {
"self" : {
"href" : "http://customers.local.spring.io:9000/customers/1"
},
"stores-nearby" : {
"href" : "http://sgibb-mbp.local:8081/stores/search/findByAddressLocationNear?location=40.740337,-73.995146&distance=50"
}
}
}
Which has the wrong hosts and ports.
Whithout seeing your project, not sure what I can do besides the customer-stores examples.
It will be a little later today, I will put a project up on github.
Finally, got around to getting this uploaded. The example is at: https://github.com/ccit-spence/instructor-crouse-demo I did include my version of Zuul and Eureka incase that makes a difference. They are pretty much straight out of the examples.
Since you are using traverson, you need to configure zuul exactly like the customer-stores demo. You have:
zuul:
routes:
instructor-service: /instructors/**
course-service: /courses/**
Through zuul, you end up with URLs with /instructors/instructors
and traverson doesn't know how to traverse the extra /instructors
.
Customer stores ui application.yml has:
zuul:
routes:
stores:
path: /stores/**
strip-prefix: false
customers:
path: /customers/**
strip-prefix: false
You also need @EnableDiscoveryClient
on the zuul Application.java
Here is what I did to get your app to work
diff --git a/instructors/src/main/java/com/demo/integration/CourseIntegration.java b/instructors/src/main/java/com/demo/integration/CourseIntegration.java
index 50293ba..8289047 100644
--- a/instructors/src/main/java/com/demo/integration/CourseIntegration.java
+++ b/instructors/src/main/java/com/demo/integration/CourseIntegration.java
@@ -45,17 +45,22 @@ public class CourseIntegration {
coursesUri = URI.create(String.format("http://%s:%s", instance.getHost(), instance.getPort()));
}
catch (RuntimeException e) {
- // Eureka not available
+ e.printStackTrace();
}
logger.info("Trying to access the course service at {}…", coursesUri);
- Traverson traverson = new Traverson(coursesUri, MediaTypes.HAL_JSON);
- Link link = traverson.follow("courses", "search", "by-related")
- .withHeaders(headers)
- .withTemplateParameters(parameters).asLink();
-
- logger.info("Found courses link pointing to {}.", link.getHref());
+ Link link = null;
+ try {
+ Traverson traverson = new Traverson(coursesUri, MediaTypes.HAL_JSON);
+ link = traverson.follow("courses", "search", "by-related")
+ .withHeaders(headers)
+ .withTemplateParameters(parameters).asLink();
+
+ logger.info("Found courses link pointing to {}.", link.getHref());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
return link;
diff --git a/zuul/src/main/java/com/demo/Application.java b/zuul/src/main/java/com/demo/Application.java
index a6823f1..8bf176d 100644
--- a/zuul/src/main/java/com/demo/Application.java
+++ b/zuul/src/main/java/com/demo/Application.java
@@ -2,6 +2,7 @@ package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@@ -12,6 +13,7 @@ import org.springframework.stereotype.Controller;
@EnableAutoConfiguration
@Controller
@EnableZuulProxy
+@EnableDiscoveryClient
public class Application {
public static void main(String[] args) {
diff --git a/zuul/src/main/resources/application.yml b/zuul/src/main/resources/application.yml
index 274d103..b3d907f 100644
--- a/zuul/src/main/resources/application.yml
+++ b/zuul/src/main/resources/application.yml
@@ -11,8 +11,12 @@ endpoints:
zuul:
routes:
- instructor-service: /instructors/**
- course-service: /courses/**
+ instructor-service:
+ path: /instructors/**
+ strip-prefix: false
+ course-service:
+ path: /courses/**
+ strip-prefix: false
#remove when spring-boot 1.2.1 is out
security:
Just to be sure I am following this properly. It appears you can't use any thing other than a one level URL.
localhost:8765/instructors -> works localhost:8765/instructor-service/instructors -> fails to proxy findby edit did a clean and restart and it worked (on Zuul)
changing to path: /xyz/instructors/**
produces a 404
I don't see why it wouldn't work, in fact I made a test for it: 8fb85f26eac790195dfc04243b157bac10ccb379
I think the difficulty may come with spring-data-rest
and strip-prefix: false
which means send the prefix to the service you are calling, so /xyz/instructors/**
doesn't work because the instructors service doesn't respond to /xyz/instructors
, just /instructors
. The proxy is not throwing the 404.
In order for it to work with spring-data-rest
what would a solution look like? Is it possible? One thing that seems strange is if I hit the link /instructor-service/instructors
it will display data. If I hit /xyz/instructors
I get the 404. Should I not get it for both?
My diff above is how to get it to work. The /instructor-service/instructors
works because it is automatically added because of eureka (see /routes
) and /instructor-service
is stripped off before forwarding.
Just wanting to be sure this is how it is supposed to work.
Setup: Service A -> instructor-service -> localhost:8080 Service B -> course-service -> localhost:8081 Zuul -> localhost:8765
Zuul route config
zuul: routes: instructor-service: /instructors/** course-service: /courses/**
Calling localhost:8765/instructors will result in the following response
Note the double
/instructors/instructors
is this normal? Do you need to change the context of each of the services to be at root if you want/instructors
Next question which I assume is normal operation due to Eureka and the Ribbon/Discovery. If you follow the rel
"instructors"
this is the result:Note the url for courses is the actual url of the course service
localhost:8081
. My assumption is that since this is based on HAL the link is intended to be followed and not ever directly accessed? We are in an AWS environment and the host could change at anytime.