Skip to content

Commit

Permalink
Add gateway (#28)
Browse files Browse the repository at this point in the history
* Add gateway setup.

* Fix gateway setup. Temporarily comment-out zuul config to run tests.

* Add gateway setup for feign calls. Add logic to use gateway for SLEUTH
tests and zuul for other tests.

* Fix bug in test.

* Fix build setup for gateway and sleuth tests.

* Add info in readme. Improve test run script setup.
  • Loading branch information
OlgaMaciaszek committed Nov 2, 2018
1 parent 0b3aa81 commit e9612db
Show file tree
Hide file tree
Showing 36 changed files with 266 additions and 66 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ Brewing service contains the following functionalities:
#### Aggregating

- Service contains a warehouse ("database") where is stores the ingredients
- Basing on the order placed it will contact the Zuul proxy to fetch ingredients **(3)**
- Basing on the order placed it will contact a proxy to fetch ingredients. If `whattotest` flag is set to `SLEUTH`,
Spring Cloud Gateway will be used as proxy. If not, Zuul will be used **(3)**
- Once the ingredients have been received an event is emitted **(7)**
- You have to have all 4 ingredients reach their threshold (1000) to start maturing the beer
- Once the brewing has been started an event is emitted **(7)**
Expand Down Expand Up @@ -70,12 +71,13 @@ Brewing service contains the following functionalities:

- Listens to events and stores them in the "database"

### Zuul proxy
### Proxy (Spring Cloud Gateway or Zuul)

- Proxy over the "adapters" to external world to fetch ingredients
- Routes all requests to the respective "ingredient adapter" **(4)**
- For simplicity we have one ingredient adapter called "ingredients" that returns a stubbed quantity
- Returns back the ingredients to the aggregating **(6)**
- If `whattotest` flag is set to `SLEUTH`, Spring Cloud Gateway will be used as proxy. If not, Zuul will be used

## Project structure

Expand All @@ -94,7 +96,7 @@ Brewing service contains the following functionalities:
├── reporting (service that listens to events)
├── zipkin-server (Zipkin Server for Sleuth Stream tests)
├── zookeeper (embedded zookeeper)
└── zuul (Zuul proxy that forwards requests to ingredients)
└── proxy (Spring Cloud Gateway or Zuul proxy that forwards requests to ingredients)
```

## How to build it?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public void should_successfully_brew_the_beer_via_rest_template_and_service_disc
// when:
presenting_service_has_been_called(requestEntity);
// then:
beer_has_been_brewed_for_process_id(SpanUtil.idToHex(new Random().nextLong()));
beer_has_been_brewed_for_process_id(referenceProcessId);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ abstract class AbstractBreweryAcceptance {
public static final String SPAN_ID_HEADER_NAME = "X-B3-SpanId"
public static final Logger log = LoggerFactory.getLogger(AbstractBreweryAcceptance)

protected static final List<String> APP_NAMES = ['presenting', 'brewing', 'zuul']
protected static final List<String> APP_NAMES = ['presenting', 'brewing', 'proxy']
protected static final List<String> SPAN_NAMES = [
'inside_presenting_maturing_feed',
'inside_presenting_bottling_feed',
Expand Down Expand Up @@ -159,13 +159,13 @@ abstract class AbstractBreweryAcceptance {
}
log.info("Presenting should be a parent of brewing.")
assert parentsAndChildren['presenting']?.contains('brewing')
// log.info("Brewing should have 3 children - zuul, reporting and presenting")
// assert parentsAndChildren['brewing']?.containsAll(['zuul', 'reporting', 'presenting'])
// log.info("Brewing should have 3 children - proxy, reporting and presenting")
// assert parentsAndChildren['brewing']?.containsAll(['proxy', 'reporting', 'presenting'])
// TODO: FIX THIS!!
log.info("Brewing should have 3 children - zuul, reporting and presenting but has only 2 for now")
assert parentsAndChildren['brewing']?.containsAll(['zuul', 'presenting'])
log.info("Zuul should be calling ingredients")
assert parentsAndChildren['zuul']?.contains('ingredients')
log.info("Brewing should have 3 children - proxy, reporting and presenting but has only 2 for now")
assert parentsAndChildren['brewing']?.containsAll(['proxy', 'presenting'])
log.info("Proxy should be calling ingredients")
assert parentsAndChildren['proxy']?.contains('ingredients')
log.info("Zipkin tracing is working! Sleuth is working! Let's be happy!")
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
package io.spring.cloud.samples.brewery.aggregating;

class Collaborators {
public static final String ZUUL = "zuul";
public static final String PROXY = "proxy";
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,37 +38,37 @@ List<Ingredient> collectIngredients(Order order, String processId) {
}

private List<Ingredient> callViaFeign(Order order, String processId) {
callZuulAtNonExistentUrl( () -> ingredientsProxy.nonExistentIngredients(processId, FEIGN.name()));
callProxyAtNonExistentUrl( () -> ingredientsProxy.nonExistentIngredients(processId, FEIGN.name()));
return order.getItems()
.stream()
.map(item -> ingredientsProxy.ingredients(item, processId, FEIGN.name()))
.collect(Collectors.toList());
}

private List<Ingredient> callViaRestTemplate(Order order, String processId) {
callZuulAtNonExistentUrl( () -> callZuul(processId, "api/someNonExistentUrl"));
callProxyAtNonExistentUrl( () -> callProxy(processId, "api/someNonExistentUrl"));
return order.getItems()
.stream()
.map(item ->
callZuul(processId, item.name())
callProxy(processId, item.name())
)
.collect(Collectors.toList());
}

private Ingredient callZuul(String processId, String name) {
private Ingredient callProxy(String processId, String name) {
return restTemplate.exchange(requestEntity()
.processId(processId)
.serviceName(Collaborators.ZUUL)
.serviceName(Collaborators.PROXY)
.url("/ingredients/" + name)
.httpMethod(HttpMethod.POST)
.build(), Ingredient.class).getBody();
}

private Object callZuulAtNonExistentUrl(Callable<Object> runnable) {
private Object callProxyAtNonExistentUrl(Callable<Object> runnable) {
try {
return runnable.call();
} catch (Exception e) {
log.error("Exception occurred while trying to call Zuul. We're doing it deliberately!", e);
log.error("Exception occurred while trying to call Proxy. We're doing it deliberately!", e);
return "";
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import static io.spring.cloud.samples.brewery.common.TestConfigurationHolder.TEST_COMMUNICATION_TYPE_HEADER_NAME;

@FeignClient(Collaborators.ZUUL)
@FeignClient(Collaborators.PROXY)
interface IngredientsProxy {

@RequestMapping(value = "/ingredients/{ingredient}", method = RequestMethod.POST)
Expand Down
4 changes: 2 additions & 2 deletions brewing/src/main/resources/application-deps.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ spring.cloud.zookeeper:
dependencies:
presenting:
path: dependency/presenting
zuul:
path: technical/zuul
proxy:
path: technical/proxy
3 changes: 3 additions & 0 deletions brewing/src/main/resources/bootstrap.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
spring:
application:
name: brewing
12 changes: 8 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def commonZipkinProject = project(':common-zipkin')
def acceptanceTestsProject = project(':acceptance-tests')
def eurekaProject = project(':eureka')
def configServerProject = project(':config-server')
def gateway = project(':gateway')
def servers = [eurekaProject, configServerProject]
def techProjects = [commonProject, commonZipkinProject, acceptanceTestsProject,
eurekaProject, configServerProject]
Expand Down Expand Up @@ -161,7 +162,7 @@ logger.lifecycle("WHAT_TO_TEST is: System prop: [${project.gradle.startParameter
logger.lifecycle("CLOUD_FOUDRY set: [${System.getenv("CLOUD_FOUNDRY")}]")
logger.lifecycle("BOM_VERSION is: [${getProp("BOM_VERSION")}]")

configure(subprojects - acceptanceTestsProject - servers) {
configure(subprojects - gateway - acceptanceTestsProject - servers) {

dependencies {
compile 'org.projectlombok:lombok:1.18.2'
Expand Down Expand Up @@ -210,19 +211,22 @@ if (hasProperty("docker")) {
}
}

configure(subprojects - commonProject - servers) {
configure(subprojects - commonProject - servers - gateway) {
dependencies {
compile(commonProject)
}
}

configure(subprojects - techProjects - commonZipkinProject) {

configure(subprojects - techProjects - commonZipkinProject - gateway) {
dependencies {
if (whatToTest('SLEUTH')) {
compile commonZipkinProject
}
}
}

configure(subprojects - techProjects - commonZipkinProject) {
dependencies {
compile "org.springframework.boot:spring-boot-starter-actuator"
compile 'com.fasterxml.jackson.core:jackson-databind'
if (!cloudFoundrySet() && !whatToTest('CONSUL') && !whatToTest('EUREKA') && !whatToTest('SCS')) {
Expand Down
10 changes: 8 additions & 2 deletions cloud-foundry-SCS.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ set -e
root=`pwd`
export CLOUD_PREFIX="scsbrewery"

if [[ "${WHAT_TO_TEST}" == "SLEUTH" ]] ; then
export PROXY_DIR="gateway"
else
export PROXY_DIR="zuul"
fi

if [[ -z "${SKIP_DEPLOYMENT}" ]] ; then
# ====================================================
if [[ -z "${DEPLOY_ONLY_APPS}" ]] ; then
Expand Down Expand Up @@ -73,8 +79,8 @@ if [[ -z "${SKIP_DEPLOYMENT}" ]] ; then
deploy_app_with_name "presenting" "${CLOUD_PREFIX}-presenting" &
echo "Starting brewing"
deploy_app_with_name "brewing" "${CLOUD_PREFIX}-brewing" &
echo "Starting zuul"
deploy_app_with_name "zuul" "${CLOUD_PREFIX}-zuul" &
echo "Starting proxy"
deploy_app_with_name "${PROXY_DIR}" "${CLOUD_PREFIX}-proxy" &
echo "Starting ingredients"
deploy_app_with_name "ingredients" "${CLOUD_PREFIX}-ingredients" &
echo "Starting reporting"
Expand Down
10 changes: 8 additions & 2 deletions cloud-foundry-SLEUTH.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ set -e

root=`pwd`

if [[ "${WHAT_TO_TEST}" == "SLEUTH" ]] ; then
export PROXY_DIR="gateway"
else
export PROXY_DIR="zuul"
fi

if [[ -z "${SKIP_DEPLOYMENT}" ]] ; then
# ====================================================
if [[ -z "${DEPLOY_ONLY_APPS}" ]] ; then
Expand Down Expand Up @@ -107,8 +113,8 @@ if [[ -z "${SKIP_DEPLOYMENT}" ]] ; then
deploy_app_with_name "presenting" "${CLOUD_PREFIX}-presenting" &
echo "Starting brewing"
deploy_app_with_name "brewing" "${CLOUD_PREFIX}-brewing" &
echo "Starting zuul"
deploy_app_with_name "zuul" "${CLOUD_PREFIX}-zuul" &
echo "Starting proxy"
deploy_app_with_name "${PROXY_DIR}" "${CLOUD_PREFIX}-proxy" &
echo "Starting ingredients"
deploy_app_with_name "ingredients" "${CLOUD_PREFIX}-ingredients" &
echo "Starting reporting"
Expand Down
3 changes: 3 additions & 0 deletions gateway/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
compile 'org.springframework.cloud:spring-cloud-starter-gateway'
}
17 changes: 17 additions & 0 deletions gateway/manifest-brewery.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
applications:
- name: brewery-proxy
memory: 1024M
instances: 1
host: brewery-proxy
path: build/libs/gateway-1.0.0.jar
services:
- brewery-rabbitmq
- brewery-discovery
- brewery-config-server
env:
SPRING_PROFILES_ACTIVE: cloud
DEBUG: "true"
JAVA_OPTS: -Djava.security.egd=file:///dev/urandom
SPRING_ZIPKIN_SENDER_TYPE: web
SPRING_ZIPKIN_BASE_URL: http://brewery-zipkin-server.cfapps.io
17 changes: 17 additions & 0 deletions gateway/manifest-docsbrewing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
applications:
- name: docsbrewing-proxy
memory: 1024M
instances: 1
host: docsbrewing-proxy
path: build/libs/gateway-1.0.0.jar
services:
- docsbrewing-rabbitmq
- docsbrewing-discovery
- docsbrewing-config-server
env:
SPRING_PROFILES_ACTIVE: cloud,cloud-docsbrewing
DEBUG: "true"
JAVA_OPTS: -Djava.security.egd=file:///dev/urandom
SPRING_ZIPKIN_SENDER_TYPE: web
SPRING_ZIPKIN_BASE_URL: http://docsbrewing-zipkin-server.cfapps.io
17 changes: 17 additions & 0 deletions gateway/manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
applications:
- name: brewery-proxy
memory: 1024M
instances: 1
host: brewery-proxy
path: build/libs/gateway-1.0.0.jar
services:
- brewery-rabbitmq
- brewery-discovery
- brewery-config-server
env:
SPRING_PROFILES_ACTIVE: cloud
DEBUG: "true"
JAVA_OPTS: -Djava.security.egd=file:///dev/urandom
SPRING_ZIPKIN_SENDER_TYPE: web
SPRING_ZIPKIN_BASE_URL: http://brewery-zipkin-server.cfapps.io
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.spring.cloud.samples.brewery.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.Configuration;

/**
* @author Olga Maciaszek-Sharma
*/
@Configuration
@SpringBootApplication
@EnableDiscoveryClient
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
9 changes: 9 additions & 0 deletions gateway/src/main/resources/application-cloud-docsbrewing.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
spring.rabbitmq.addresses: ${vcap.services.docsbrewing-rabbitmq.credentials.uri}

eureka:
client:
serviceUrl:
defaultZone: ${vcap.services.docsbrewing-discovery.credentials.uri:http://127.0.0.1:8761}/eureka/
instance:
hostname: ${APPLICATION_DOMAIN}
nonSecurePort: 80
9 changes: 9 additions & 0 deletions gateway/src/main/resources/application-cloud.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
spring.rabbitmq.addresses: ${vcap.services.brewery-rabbitmq.credentials.uri}

eureka:
client:
serviceUrl:
defaultZone: ${vcap.services.brewery-discovery.credentials.uri:http://127.0.0.1:8761}/eureka/
instance:
hostname: ${APPLICATION_DOMAIN}
nonSecurePort: 80
1 change: 1 addition & 0 deletions gateway/src/main/resources/application-consul.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
spring.cloud.consul.discovery.preferIpAddress: true
7 changes: 7 additions & 0 deletions gateway/src/main/resources/application-eureka.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
eureka:
instance:
preferIpAddress: true

ribbon:
eureka:
enabled: true
22 changes: 22 additions & 0 deletions gateway/src/main/resources/application-kafka.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
spring:
cloud:
stream:
kafka:
binder:
zkNodes: localhost
brokers: localhost
# The X- are for Sleuth 1.0.x and 1.1.x compatibility
headers:
- X-B3-TraceId
- X-B3-SpanId
- X-B3-Sampled
- X-B3-ParentSpanId
- X-Span-Name
- X-Process-Id
- spanId
- spanSampled
- spanProcessId
- spanParentSpanId
- spanTraceId
- spanName
- messageSent
Loading

0 comments on commit e9612db

Please sign in to comment.