Skip to content

Commit

Permalink
Completed most of the doc
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolaferraro committed Jun 1, 2018
1 parent c625c39 commit b1ca4d4
Show file tree
Hide file tree
Showing 39 changed files with 102,113 additions and 193 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ The final result of the workshop is a "Plush Shop Demo".

## Requirements

**TODO: WRITE REQUIREMENTS**

- HTTPie
- Java 8
- Maven 3.5.0
- Your favourite IDE
- HTTPie (to test endpoints)

## Let's start

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public synchronized void add(Payment payment) {
}

if (current - payment.getAmount() < 0) {
payment.setActive(false);
payments.put(payment.getReference(), payment);
throw new IllegalStateException("Insufficient credit!");
}

Expand All @@ -43,10 +45,10 @@ public synchronized void remove(String ref) {
if (payments.containsKey(ref) && payments.get(ref).isActive()) {
Payment payment = payments.get(ref);
int current = accounts.get(payment.getUser());
accounts.put(payment.getUser(), current - payment.getAmount());
accounts.put(payment.getUser(), current + payment.getAmount());
// set inactive for subsequent cancellations
payment.setActive(false);
} else {
} else if (!payments.containsKey(ref)) {
// prevents subsequent creation of the payment
Payment dummy = new Payment();
dummy.setReference(ref);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
package org.apache.camel.workshop.gateway;

import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.caffeine.CaffeineConstants;
import org.apache.camel.http.common.HttpMethods;
import org.apache.camel.impl.saga.InMemorySagaService;
import org.apache.camel.model.dataformat.JsonLibrary;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

@SpringBootApplication
public class GatewayApplication {
Expand All @@ -20,120 +10,4 @@ public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}

@Component
public static class CamelRoutes extends RouteBuilder {

@Override
public void configure() throws Exception {

restConfiguration().component("servlet").enableCORS(true);
getContext().addService(new InMemorySagaService(), true);

/*
* Items
*/

rest().get("/items")
.route()
.to("undertow:http://{{inventory.host}}:{{inventory.port}}/api/items")
.unmarshal().json(JsonLibrary.Jackson, Catalog.class)
.enrichWith("direct:recommendationHystrix").body(Catalog.class, List.class, GatewayApplication::recommend)
.marshal().json(JsonLibrary.Jackson);

/*
* Recommendations
*/

from("direct:recommendationHystrix")
.hystrix()
.to("direct:recommendation")
.setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT))
.to("caffeine-cache:global?key=recommendation")
.onFallback()
.setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_GET))
.to("caffeine-cache:global?key=recommendation")
.choice()
.when(header("CamelCaffeineActionHasResult").isNotEqualTo(true))
.setBody(constant(Collections.emptyList()))
.end()
.end();

from("direct:recommendation")
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
.to("undertow:http://{{recommendation.host}}:{{recommendation.port}}/api/recommendations")
.unmarshal().json(JsonLibrary.Jackson, List.class);


/*
* Orders
*/

rest().post("/orders")
.type(Order.class)
.route()
.saga()
.compensation("direct:cancelOrder")
.option("order", simple("${body}"))
.unmarshal().json(JsonLibrary.Jackson, Order.class)
.to("bean-validator:validateOrder")
.setHeader("reference", simple("${body.reference}"))
.multicast().parallelProcessing()
.pipeline()
.setBody().body(Order.class, GatewayApplication::createPayment)
.marshal().json(JsonLibrary.Jackson)
.to("undertow:http://{{payment.host}}:{{payment.port}}/api/payments")
.end()
.split().simple("${body.items}").parallelProcessing()
.toD("undertow:http://{{inventory.host}}:{{inventory.port}}/api/purchases/${header.reference}/items/${body.id}?amount=${body.amount}")
.end()
.end()
.marshal().json(JsonLibrary.Jackson)
.end();


from("direct:cancelOrder")
.setBody(header("order")).convertBodyTo(String.class)
.unmarshal().json(JsonLibrary.Jackson, Order.class)
.setHeader("order", simple("${body.reference}"))
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.DELETE))
.multicast().parallelProcessing()
.toD("undertow:http://{{payment.host}}:{{payment.port}}/api/payments/${header.order}")
.toD("undertow:http://{{inventory.host}}:{{inventory.port}}/api/purchases/${header.order}");

/*
* Proxied requests
*/

rest().get("/purchases")
.route()
.to("undertow:http://{{inventory.host}}:{{inventory.port}}/api/purchases");

rest().get("/payments")
.route()
.to("undertow:http://{{payment.host}}:{{payment.port}}/api/payments");


}
}

private static Payment createPayment(Order order) {
Payment payment = new Payment();
payment.setUser(order.getUser());
payment.setReference(order.getReference());
payment.setAmount(order.getPrice());
return payment;
}

private static Catalog recommend(Catalog catalog, List<String> recomm) {
if (recomm != null && catalog != null && catalog.getItems() != null) {
for (String recommItem : recomm) {
Item item = catalog.getItems().get(recommItem);
if (item != null) {
item.setRecommended(true);
}
}
}
return catalog;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package org.apache.camel.workshop.gateway;

import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.caffeine.CaffeineConstants;
import org.apache.camel.http.common.HttpMethods;
import org.apache.camel.impl.saga.InMemorySagaService;
import org.apache.camel.model.dataformat.JsonLibrary;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

@Component
public class GatewayRoutes extends RouteBuilder {



@Override
public void configure() throws Exception {

restConfiguration()
.component("servlet")
.enableCORS(true);


getContext().addService(new InMemorySagaService(), true);

/*
* Proxied requests
*/

rest().get("/payments")
.route()
.to("undertow:http://{{credit.service}}/api/payments");

rest().get("/purchases")
.route()
.to("undertow:http://{{inventory.service}}/api/purchases");

/*
* Items
*/

rest().get("/items")
.route()
.to("undertow:http://{{inventory.service}}/api/items")
.unmarshal().json(JsonLibrary.Jackson, Catalog.class)
.enrichWith("direct:recommendationHystrix")
.body(Catalog.class, List.class, this::recommend)
.marshal().json(JsonLibrary.Jackson);

/*
* Recommendations
*/

from("direct:recommendationHystrix")
.hystrix()
.to("direct:recommendation")
.setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_PUT))
.to("caffeine-cache:global?key=recommendation")
.onFallback()
.setHeader(CaffeineConstants.ACTION, constant(CaffeineConstants.ACTION_GET))
.to("caffeine-cache:global?key=recommendation")
.choice()
.when(header("CamelCaffeineActionHasResult").isNotEqualTo(true))
.setBody(constant(Collections.emptyList()))
.end()
.end();

from("direct:recommendation")
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.GET))
.to("undertow:http://{{recommendation.service}}/api/recommendations")
.unmarshal().json(JsonLibrary.Jackson, List.class);


/*
* Orders
*/

rest().post("/orders")
.type(Order.class)
.route()
.saga()
.compensation("direct:cancelOrder")
.option("order", simple("${body}"))
.unmarshal().json(JsonLibrary.Jackson, Order.class)
.to("bean-validator:validateOrder")
.multicast().parallelProcessing()
.to("direct:payOrder")
.to("direct:purchaseOrderItems")
.end()
.marshal().json(JsonLibrary.Jackson)
.end();

from("direct:payOrder")
.setBody().body(Order.class, this::createPayment)
.marshal().json(JsonLibrary.Jackson)
.to("undertow:http://{{credit.service}}/api/payments");


from("direct:purchaseOrderItems")
.setHeader("reference", simple("${body.reference}"))
.split().simple("${body.items}").parallelProcessing()
.toD("undertow:http://{{inventory.service}}/api/purchases/${header.reference}/items/${body.id}?amount=${body.amount}")
.end();


from("direct:cancelOrder")
.setBody(header("order")).convertBodyTo(String.class)
.unmarshal().json(JsonLibrary.Jackson, Order.class)
.setHeader(Exchange.HTTP_METHOD, constant(HttpMethods.DELETE))
.multicast().parallelProcessing()
.toD("undertow:http://{{credit.service}}/api/payments/${body.reference}")
.toD("undertow:http://{{inventory.service}}/api/purchases/${body.reference}");


}

private Payment createPayment(Order order) {
Payment payment = new Payment();
payment.setUser(order.getUser());
payment.setReference(order.getReference());
payment.setAmount(order.getPrice());
return payment;
}

private Catalog recommend(Catalog catalog, List<String> recomm) {
if (recomm != null && catalog != null && catalog.getItems() != null) {
for (String recommItem : recomm) {
Item item = catalog.getItems().get(recommItem);
if (item != null) {
item.setRecommended(true);
}
}
}
return catalog;
}
}
10 changes: 6 additions & 4 deletions app/gateway/src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
camel.component.servlet.mapping.context-path=/api/*


inventory.host=localhost
inventory.port=8081
inventory.service=${inventory.host}:${inventory.port}

payment.host=localhost
payment.port=8082
credit.host=localhost
credit.port=8082
credit.service=${credit.host}:${credit.port}

recommendation.host=localhost
recommendation.port=8083
recommendation.port=8083
recommendation.service=${recommendation.host}:${recommendation.port}
Loading

0 comments on commit b1ca4d4

Please sign in to comment.