Skip to content

Spring Boot/Kafka/Mongo Microservice, part of a set of microservices for this project

License

Notifications You must be signed in to change notification settings

senchacha/storefront-demo-fulfillment

 
 

Repository files navigation

Kafka Traveler Microservices Demo: Fulfillment

Fulfillment Service

Spring Boot/Kafka/Mongo Microservice, one of a set of microservices for this project. Services use Spring Kafka 2.1.6 to maintain eventually consistent data between their different Customer domain objects.

Originally code based on the post, Spring Kafka - JSON Serializer Deserializer Example, from the CodeNotFound.com Blog.

Development

For Kakfa, use garystafford/kafka-docker project, a clone of the wurstmeister/kafka-docker project. The garystafford/kafka-docker local docker-compose file builds a Kafka, Kafka Manager, ZooKeeper, MongoDB, Eureka Server, and Zuul.

Commands

I develop and debug directly from JetBrains IntelliJ. The default Spring profile will start the three services on different ports.

./gradlew clean build bootRun --args='--spring.profiles.active=local'

Creating Sample Data

Create sample data for each service. Requires Kafka is running. Endpoints for Zuul, when using Docker Swarm/Stack, are different. See this Python script for Zuul endpoints.

# accounts - create sample customer accounts
http http:https://localhost:8085/customers/sample

# orders - add sample orders to each customer
http http:https://localhost:8090/customers/sample/orders

# orders - send approved orders to fulfillment service
http http:https://localhost:8090/customers/sample/fulfill

# fulfillment - change fulfillment requests from approved to processing
http http:https://localhost:8095/fulfillments/sample/process

# fulfillment - change fulfillment requests from processing to shipping
http http:https://localhost:8095/fulfillments/sample/ship

# fulfillment - change fulfillment requests from processing to in transit
http http:https://localhost:8095/fulfillments/sample/in-transit

# fulfillment - change fulfillment requests from in transit to in received
http http:https://localhost:8095/fulfillments/sample/receive

Container Infrastructure

$ docker container ls

CONTAINER ID        IMAGE                                        COMMAND                  CREATED             STATUS              PORTS                                  NAMES
ccf0e9a0637d        garystafford/storefront-fulfillment:latest   "java -jar -Djava.se…"   11 minutes ago      Up 11 minutes       8080/tcp                               storefront_fulfillment.1.0mht01m6nk461q7mt1ey4zsjb
f8a4654183cb        hlebalbau/kafka-manager:latest               "/kafka-manager/bin/…"   11 minutes ago      Up 11 minutes                                              storefront_kafka_manager.1.so9h6c8veemrwlznj5zdk3sdw
fe6579d68846        garystafford/storefront-accounts:latest      "java -jar -Djava.se…"   11 minutes ago      Up 11 minutes       8080/tcp                               storefront_accounts.1.nafdn02w68nixyvmz7l46kzcq
2495802b640b        garystafford/storefront-eureka:latest        "java -jar -Djava.se…"   11 minutes ago      Up 11 minutes       8761/tcp                               storefront_eureka.1.x2tu8vg1dnizx61lwnudrnsml
5afe1e94162f        wurstmeister/kafka:latest                    "start-kafka.sh"         12 minutes ago      Up 11 minutes                                              storefront_kafka.1.n55qrkbqfueg1sgz0fb9h47qu
44a9d4dbdc4b        mongo:latest                                 "docker-entrypoint.s…"   12 minutes ago      Up 11 minutes       27017/tcp                              storefront_mongo.1.tfy3u2zi4bpcmb7372ihdjmbc
23be66801ebc        garystafford/storefront-orders:latest        "java -jar -Djava.se…"   12 minutes ago      Up 11 minutes       8080/tcp                               storefront_orders.1.bo5hfnqb9ijbfd7vp88hcs3vn
bbe4dbe00048        wurstmeister/zookeeper:latest                "/bin/sh -c '/usr/sb…"   12 minutes ago      Up 12 minutes       22/tcp, 2181/tcp, 2888/tcp, 3888/tcp   storefront_zookeeper.1.ipfwro51ob6fpls26bk14lvkt
98b8084f0162        garystafford/storefront-zuul:latest          "java -jar -Djava.se…"   12 minutes ago      Up 12 minutes       8761/tcp                               storefront_zuul.1.u4h4bxp01mcwetyoezk19ljzt

Orders Customer Object in MongoDB

docker exec -it $(docker ps | grep storefront_mongo | awk '{print $NF}') sh
mongo
use fulfillment
db.fulfillment.requests.find().pretty()
db.fulfillment.requests.remove({})
{
	"_id" : ObjectId("5b18878ca8d05609e6ff1851"),
	"timestamp" : NumberLong("1528334218838"),
	"name" : {
		"title" : "Ms.",
		"firstName" : "Susan",
		"lastName" : "Blackstone"
	},
	"contact" : {
		"primaryPhone" : "433-544-6555",
		"secondaryPhone" : "223-445-6767",
		"email" : "[email protected]"
	},
	"address" : {
		"type" : "SHIPPING",
		"description" : "Home Sweet Home",
		"address1" : "33 Oak Avenue",
		"city" : "Nowhere",
		"state" : "VT",
		"postalCode" : "444556-9090"
	},
	"order" : {
		"guid" : "f52e2930-ef31-44db-a53c-b7ba4ae3f5cf",
		"orderStatusEvents" : [
			{
				"timestamp" : NumberLong("1528334457603"),
				"orderStatusType" : "COMPLETED"
			}
		],
		"orderItems" : [
			{
				"product" : {
					"guid" : "d01fde07-7c24-49c5-a5f1-bc2ce1f14c48",
					"title" : "Red Widget"
				},
				"quantity" : 2
			},
			{
				"product" : {
					"guid" : "4efe33a1-722d-48c8-af8e-7879edcad2fa",
					"title" : "Purple Widget"
				},
				"quantity" : 5
			}
		]
	},
	"shippingMethod" : "FedEx",
	"shippingStatusEvents" : [
		{
			"timestamp" : NumberLong("1528334457603"),
			"shippingStatusType" : "SHIPPED"
		},
		{
			"timestamp" : NumberLong("1528334457603"),
			"shippingStatusType" : "IN_TRANSIT"
		},
		{
			"timestamp" : NumberLong("1528334457603"),
			"shippingStatusType" : "RECEIVED"
		}
	],
	"_class" : "com.storefront.model.FulfillmentRequestEvent"
}

Current Results

Output from application, on the orders.order.fulfill topic

2018-06-06 21:20:57.519  INFO [-,46fcaf5802394709,46fcaf5802394709,false] 2534 --- [nio-8095-exec-2] c.storefront.handler.AfterSaveListener   : onAfterSave event='org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent[source=FulfillmentRequest(id=5b18878ba8d05609e6ff1849, timestamp=1528334218543, name=Name(title=Mr., firstName=John, middleName=S., lastName=Doe, suffix=Jr.), contact=Contact(primaryPhone=555-666-7777, secondaryPhone=555-444-9898, [email protected]), address=Address(type=SHIPPING, description=My home address, address1=123 Oak Street, address2=null, city=Sunrise, state=CA, postalCode=12345-6789), order=Order(guid=ef8572ad-1e21-41ed-9f4d-7a908c0d0b9b, orderStatusEvents=[OrderStatusEvent(timestamp=1528334457507, orderStatusType=COMPLETED, note=null)], orderItems=[OrderItem(product=Product(guid=7f3c9c22-3c0a-47a5-9a92-2bd2e23f6e37, title=Green Widget), quantity=5), OrderItem(product=Product(guid=f3b9bdce-10d8-4c22-9861-27149879b3c1, title=Orange Widget), quantity=3), OrderItem(product=Product(guid=4efe33a1-722d-48c8-af8e-7879edcad2fa, title=Purple Widget), quantity=5)]), shippingMethod=FedEx, shippingStatusEvents=[ShippingStatusEvent(timestamp=1528334457507, shippingStatusType=SHIPPED, note=null), ShippingStatusEvent(timestamp=1528334457507, shippingStatusType=IN_TRANSIT, note=null), ShippingStatusEvent(timestamp=1528334457507, shippingStatusType=RECEIVED, note=null)])]'
2018-06-06 21:20:57.520  INFO [-,46fcaf5802394709,46fcaf5802394709,false] 2534 --- [nio-8095-exec-2] com.storefront.kafka.Sender              : sending payload='OrderStatusEventChange(guid=ef8572ad-1e21-41ed-9f4d-7a908c0d0b9b, orderStatusEvent=OrderStatusEvent(timestamp=1528334457507, orderStatusType=COMPLETED, note=null))' to topic='fulfillment.order.change'
2018-06-06 21:20:57.524  INFO [-,46fcaf5802394709,46fcaf5802394709,false] 2534 --- [nio-8095-exec-2] c.storefront.handler.AfterSaveListener   : onAfterSave event='org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent[source=FulfillmentRequest(id=5b18878ba8d05609e6ff184a, timestamp=1528334218805, name=Name(title=Ms., firstName=Mary, middleName=null, lastName=Smith, suffix=null), contact=Contact(primaryPhone=456-789-0001, secondaryPhone=456-222-1111, [email protected]), address=Address(type=SHIPPING, description=Home Sweet Home, address1=1234 Main Street, address2=null, city=Anywhere, state=NY, postalCode=45455-66677), order=Order(guid=6d8a81e5-23dc-4ec5-8488-c7519c890ae1, orderStatusEvents=[OrderStatusEvent(timestamp=1528334457521, orderStatusType=COMPLETED, note=null)], orderItems=[OrderItem(product=Product(guid=b506b962-fcfa-4ad6-a955-8859797edf16, title=Black Widget), quantity=2), OrderItem(product=Product(guid=f3b9bdce-10d8-4c22-9861-27149879b3c1, title=Orange Widget), quantity=4)]), shippingMethod=FedEx, shippingStatusEvents=[ShippingStatusEvent(timestamp=1528334457521, shippingStatusType=SHIPPED, note=null), ShippingStatusEvent(timestamp=1528334457521, shippingStatusType=IN_TRANSIT, note=null), ShippingStatusEvent(timestamp=1528334457521, shippingStatusType=RECEIVED, note=null)])]'
2018-06-06 21:20:57.525  INFO [-,46fcaf5802394709,46fcaf5802394709,false] 2534 --- [nio-8095-exec-2] com.storefront.kafka.Sender              : sending payload='OrderStatusEventChange(guid=6d8a81e5-23dc-4ec5-8488-c7519c890ae1, orderStatusEvent=OrderStatusEvent(timestamp=1528334457521, orderStatusType=COMPLETED, note=null))' to topic='fulfillment.order.change'
2018-06-06 21:20:57.534  INFO [-,46fcaf5802394709,46fcaf5802394709,false] 2534 --- [nio-8095-exec-2] c.storefront.handler.AfterSaveListener   : onAfterSave event='org.springframework.data.mongodb.core.mapping.event.AfterSaveEvent[source=FulfillmentRequest(id=5b18878ca8d05609e6ff184b, timestamp=1528334218806, name=Name(title=Ms., firstName=Susan, middleName=null, lastName=Blackstone, suffix=null), contact=Contact(primaryPhone=433-544-6555, secondaryPhone=223-445-6767, [email protected]), address=Address(type=SHIPPING, description=Home Sweet Home, address1=33 Oak Avenue, address2=null, city=Nowhere, state=VT, postalCode=444556-9090), order=Order(guid=ffe75116-f72b-40c8-b819-b3cc0ad60b47, orderStatusEvents=[OrderStatusEvent(timestamp=1528334457525, orderStatusType=COMPLETED, note=null)], orderItems=[OrderItem(product=Product(guid=b506b962-fcfa-4ad6-a955-8859797edf16, title=Black Widget), quantity=2), OrderItem(product=Product(guid=f3b9bdce-10d8-4c22-9861-27149879b3c1, title=Orange Widget), quantity=2), OrderItem(product=Product(guid=d01fde07-7c24-49c5-a5f1-bc2ce1f14c48, title=Red Widget), quantity=5)]), shippingMethod=FedEx, shippingStatusEvents=[ShippingStatusEvent(timestamp=1528334457525, shippingStatusType=SHIPPED, note=null), ShippingStatusEvent(timestamp=1528334457525, shippingStatusType=IN_TRANSIT, note=null), ShippingStatusEvent(timestamp=1528334457525, shippingStatusType=RECEIVED, note=null)])]'

Output from Kafka container using the following command.

kafka-console-consumer.sh \
  --bootstrap-server localhost:9092 \
  --from-beginning --topic orders.order.fulfill

Kafka Consumer Output

{"timestamp":1528001014137,"name":{"title":"Mr.","firstName":"John","middleName":"S.","lastName":"Doe","suffix":"Jr."},"contact":{"primaryPhone":"555-666-7777","secondaryPhone":"555-444-9898","email":"[email protected]"},"address":{"type":"SHIPPING","description":"My home address","address1":"123 Oak Street","address2":null,"city":"Sunrise","state":"CA","postalCode":"12345-6789"},"order":{"guid":"617e9b8f-970c-487d-b4b7-faad870090c7","orderStatusEvents":[{"timestamp":1527996053859,"orderStatusType":"APPROVED","note":null}],"orderItems":[{"product":{"id":null,"guid":"f3b9bdce-10d8-4c22-9861-27149879b3c1","title":"Orange Widget","description":"Opulent Orange Widget","price":9.99},"quantity":3},{"product":{"id":null,"guid":"7f3c9c22-3c0a-47a5-9a92-2bd2e23f6e37","title":"Green Widget","description":"Gorgeous Green Widget","price":11.99},"quantity":4}]}}
{"timestamp":1528001014321,"name":{"title":"Ms.","firstName":"Mary","middleName":null,"lastName":"Smith","suffix":null},"contact":{"primaryPhone":"456-789-0001","secondaryPhone":"456-222-1111","email":"[email protected]"},"address":{"type":"SHIPPING","description":"Home Sweet Home","address1":"1234 Main Street","address2":null,"city":"Anywhere","state":"NY","postalCode":"45455-66677"},"order":{"guid":"d51113cd-fbc1-45b3-b3e9-53b78d22b5bf","orderStatusEvents":[{"timestamp":1527996053859,"orderStatusType":"APPROVED","note":null}],"orderItems":[{"product":{"id":null,"guid":"a9d5a5c7-4245-4b4e-b1c3-1d3968f36b2d","title":"Yellow Widget","description":"Amazing Yellow Widget","price":5.99},"quantity":1},{"product":{"id":null,"guid":"4efe33a1-722d-48c8-af8e-7879edcad2fa","title":"Purple Widget","description":"Pretty Purple Widget","price":7.99},"quantity":4},{"product":{"id":null,"guid":"a9d5a5c7-4245-4b4e-b1c3-1d3968f36b2d","title":"Yellow Widget","description":"Amazing Yellow Widget","price":5.99},"quantity":4}]}}
{"timestamp":1528001014339,"name":{"title":"Ms.","firstName":"Susan","middleName":null,"lastName":"Blackstone","suffix":null},"contact":{"primaryPhone":"433-544-6555","secondaryPhone":"223-445-6767","email":"[email protected]"},"address":{"type":"SHIPPING","description":"Home Sweet Home","address1":"33 Oak Avenue","address2":null,"city":"Nowhere","state":"VT","postalCode":"444556-9090"},"order":{"guid":"05f3d73c-df01-4b31-87b0-3b65065222bd","orderStatusEvents":[{"timestamp":1527996053859,"orderStatusType":"APPROVED","note":null}],"orderItems":[{"product":{"id":null,"guid":"d01fde07-7c24-49c5-a5f1-bc2ce1f14c48","title":"Red Widget","description":"Reliable Red Widget","price":3.99},"quantity":4}]}}

The fulfillment.order.change sends fulfilled order notifications back to orders, via topic

kafka-topics.sh --create \
  --zookeeper zookeeper:2181 \
  --replication-factor 1 --partitions 1 \
  --topic fulfillment.order.change

kafka-console-consumer.sh \
  --bootstrap-server localhost:9092 \
  --from-beginning --topic fulfillment.order.change

Output from application, on the fulfillment.order.change topic

{"guid":"5f900d92-e2a2-484f-8e9c-7e0a24b093fd","orderStatusEvent":{"timestamp":1528334452755,"orderStatusType":"PROCESSING","note":null}}
{"guid":"f52e2930-ef31-44db-a53c-b7ba4ae3f5cf","orderStatusEvent":{"timestamp":1528334452800,"orderStatusType":"PROCESSING","note":null}}
{"guid":"ef8572ad-1e21-41ed-9f4d-7a908c0d0b9b","orderStatusEvent":{"timestamp":1528334457507,"orderStatusType":"COMPLETED","note":null}}
{"guid":"6d8a81e5-23dc-4ec5-8488-c7519c890ae1","orderStatusEvent":{"timestamp":1528334457521,"orderStatusType":"COMPLETED","note":null}}
{"guid":"ffe75116-f72b-40c8-b819-b3cc0ad60b47","orderStatusEvent":{"timestamp":1528334457525,"orderStatusType":"COMPLETED","note":null}}

References

About

Spring Boot/Kafka/Mongo Microservice, part of a set of microservices for this project

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 98.6%
  • Shell 1.4%