Skip to content

Commit

Permalink
Lots of changes.
Browse files Browse the repository at this point in the history
  • Loading branch information
Castyr committed Mar 20, 2018
1 parent 16ecd71 commit 0a777ea
Show file tree
Hide file tree
Showing 23 changed files with 435 additions and 17 deletions.
Binary file removed .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,5 @@ nbbuild/
dist/
nbdist/
.nb-gradle/

\.DS_Store
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# trip-management-query

Trip Management Query serves all the views of trip. It is the query service in CQRS for trip.

## Features
* Query Trips
* Query by Trip ID
* Query all trips
* Query by User ID
* Query by User ID and status

# Demo
To run this project from docker:
* Make sure that the Docker daemon is installed and running.
* Assemble this project.
* Run ```docker-compose up --build``` from the root project.
* On another terminal run ```docker ps``` to see which ports were assigned.

# Development

## Requirements
* Docker 17.xx.x
* JDK 1.8
* IntelliJ 2018
* Mongo 3.4

To run this project from docker:
* Make sure that the Docker daemon is installed and running.
* Assemble this project.
* Run ```docker-compose up --build -f docker-compose-dev.yml``` from the root project.
* Run the Gradle task 'application/bootrun' from IntelliJ.
11 changes: 11 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ group = 'org.aitesting.microservices'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

ext {
springCloudVersion = 'Edgware.SR2'
}

repositories {
mavenCentral()
}
Expand All @@ -53,6 +57,7 @@ dependencies {
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-aop')
compile('org.springframework.cloud:spring-cloud-starter-eureka')

testCompile('au.com.dius:pact-jvm-provider-junit_2.11:3.5.13')
testCompile('org.springframework.boot:spring-boot-starter-test')
Expand All @@ -62,6 +67,12 @@ dependencies {
testCompile("org.springframework.boot:spring-boot-starter-test:${springBootVersion}")
}

dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}

contracts {
baseClassMappings {
baseClassMapping(".*tripmanagement.*", "org.aitesting.microservices.tests.provider.TripContractBase")
Expand Down
36 changes: 36 additions & 0 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
version: '3'
services:

mongo:
image: 'mongo:3.4.1'
container_name: 'mongo'
ports:
- '27017:27017'
volumes:
- 'mongo:/data/db'
rabbitmq:
image: rabbitmq:management
container_name: 'rabbitmq'
ports:
- "5672:5672"
- "15672:15672"
trip-management-cmd:
image: aista/trip-management-cmd
container_name: 'trip-management-cmd'
environment:
- RABBIT_HOST=rabbitmq
- MONGO_HOST=mongo
ports:
- "8080"
depends_on:
- rabbitmq
- mongo
- discovery-service
discovery-service:
image: springcloud/eureka
ports:
- "8761:8761"
container_name: eureka-server

volumes:
mongo:
7 changes: 7 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,12 @@ services:
- rabbitmq
- mongo
- trip-management-cmd
- discovery-service
discovery-service:
image: springcloud/eureka
ports:
- "8761:8761"
container_name: eureka-server

volumes:
mongo:
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.retry.annotation.EnableRetry;
import org.springframework.retry.annotation.Retryable;

@EnableRetry
@EnableDiscoveryClient
@SpringBootApplication
public class TripManagementQueryApplication {
@Retryable(value = IllegalArgumentException.class, maxAttempts = 5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,36 @@ public TripEventHandler() {}

@EventHandler
public void on(TripCreatedEvent event) {
LOG.info("Trip created: {}", event.getId());
LOG.trace("Creating trip: {}", event.getId());
tripRepository.save(new Trip(event.getId(), event.getUserId(),
event.getOriginAddress(), event.getDestinationAddress(), TripStatus.CREATED));
LOG.info("Trip created: {}", event.getId());
}

@EventHandler
public void on(TripCanceledEvent event) {
LOG.info("Trip canceled: {}", event.getId());
LOG.trace("Cancelling Trip: {}", event.getId());
Trip trip = tripRepository.findOne(event.getId());
trip.setStatus(TripStatus.CANCELED);
tripRepository.save(trip);
LOG.info("Trip canceled: {}", event.getId());
}

@EventHandler
public void on(TripStartedEvent event) {
LOG.info("Trip started: {}", event.getId());
LOG.trace("Starting trip: {}", event.getId());
Trip trip = tripRepository.findOne(event.getId());
trip.setStatus(TripStatus.STARTED);
tripRepository.save(trip);
LOG.info("Trip started: {}", event.getId());
}

@EventHandler
public void on(TripCompletedEvent event) {
LOG.info("Trip completed: {}", event.getId());
LOG.trace("Completing trip: {}", event.getId());
Trip trip = tripRepository.findOne(event.getId());
trip.setStatus(TripStatus.COMPLETED);
tripRepository.save(trip);
LOG.info("Trip completed: {}", event.getId());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,73 @@

import java.util.List;
import java.util.UUID;

import org.aitesting.microservices.tripmanagement.common.events.TripStatus;
import org.aitesting.microservices.tripmanagement.common.exceptions.NotFoundException;
import org.aitesting.microservices.tripmanagement.query.domain.models.Trip;
import org.aitesting.microservices.tripmanagement.query.service.repositories.TripRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("api")
@RequestMapping("api/v1")
public class TripManagementController {

private static final Logger logger = LoggerFactory.getLogger(TripManagementController.class);

@Autowired
private TripRepository tripRepository;

@GetMapping("trips")
public List<Trip> getTrips() {
return tripRepository.findAll();
public ResponseEntity<List<Trip>> getTrips() {
logger.info(String.format("Request all trips"));
return new ResponseEntity<>(tripRepository.findAll(), HttpStatus.OK);
}

@GetMapping("trip/{id}")
public Trip getTrip(@PathVariable("id") UUID id) throws NotFoundException {
public ResponseEntity<Trip> getTrip(@PathVariable("id") UUID id) {
logger.info(String.format("Request for trip by ID: %s", id));
Trip trip = tripRepository.findOne(id);
if (trip != null) {
return trip;
logger.trace(String.format("Found trip by ID: %s", id));
return new ResponseEntity<>(trip, HttpStatus.OK);
}
logger.trace(String.format("No trips found by ID: %s", id));
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

@GetMapping("trip/user/{userId}")
public ResponseEntity<List<Trip>> getTripByUser(@PathVariable("userId") UUID userId) {
logger.info(String.format("Request for trips from user: %s", userId));
List<Trip> trips = tripRepository.findByUserId(userId);
if (trips != null && trips.size() > 0) {
logger.trace(String.format("Found trip for user: %s", userId));
return new ResponseEntity<>(trips, HttpStatus.OK);
}
logger.trace(String.format("No trips found for user: %s", userId));
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}

@GetMapping("trip/user/{userId}/status/{status}")
public ResponseEntity<List<Trip>> getTripByUserAndStatus(@PathVariable("userId") UUID userId, @PathVariable("status") String status) {
logger.info(String.format("Request for trips from user: %s with status: %s", userId, status));
TripStatus tripStatus;
try {
tripStatus = TripStatus.valueOf(status.toUpperCase());
} catch(IllegalArgumentException e) {
logger.trace(String.format("Bad argument status: %s", status));
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
List<Trip> trips = tripRepository.findByUserIdAndStatus(userId, tripStatus);
if (trips != null && trips.size() > 0) {
logger.trace(String.format("Found trip for user: %s with status: %s", userId, status));
return new ResponseEntity<>(trips, HttpStatus.OK);
}
throw new NotFoundException();
logger.trace(String.format("No trips found for user: %s with status: %s", userId, status));
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
package org.aitesting.microservices.tripmanagement.query.service.repositories;

import java.util.List;
import java.util.UUID;

import org.aitesting.microservices.tripmanagement.common.events.TripStatus;
import org.aitesting.microservices.tripmanagement.query.domain.models.Trip;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface TripRepository extends MongoRepository<Trip, UUID> {
List<Trip> findByUserId(UUID userId);

List<Trip> findByUserIdAndStatus(UUID userId, TripStatus status);
}
6 changes: 6 additions & 0 deletions src/main/resources/application-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
spring:
application:
name: trip-management-query

server:
port: ${APP_PORT:8080}
6 changes: 6 additions & 0 deletions src/main/resources/application-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
spring:
application:
name: trip-management-query

server:
port: ${APP_PORT:8080}
15 changes: 14 additions & 1 deletion src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ spring:
username: guest
password: guest

eureka:
client:
serviceUrl:
defaultZone: http://eureka-service:8761/eureka/

server:
port: ${APP_PORT:8080}

Expand All @@ -35,4 +40,12 @@ logging:
hibernate: DEBUG
apache:
commons:
dbcp2: DEBUG
dbcp2: DEBUG

---
spring:
profiles: test

eureka:
client:
enabled: false
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class TestConstants {
public static final UUID TRIP_ID1 = UUID.fromString("f849769e-2534-84a6-d475-5c2d701343ab");
public static final UUID TRIP_ID2 = UUID.fromString("5b842415-9447-4b9b-85c6-2e1075214cc4");
public static final UUID TRIP_ID3 = UUID.fromString("7a7d1e99-4823-4aa5-9d3b-2307e88cee0d");
public static final UUID TRIP_ID4 = UUID.fromString("7a7d1e99-4823-4aa5-9d3b-2307e88cee08");
public static final UUID USER_ID = UUID.fromString("123e4567-e89b-12d3-a456-426655440000");
public static final String FROM = "from some place over there";
public static final String TO = "to this other place";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Profile;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringRunner.class)
@Profile("test")
@SpringBootTest(classes = TripManagementQueryApplication.class)
public abstract class TripContractBase {

Expand All @@ -32,6 +34,7 @@ public void setup() {
tripRepository.save(new Trip(TRIP_ID1, USER_ID, FROM, TO, TripStatus.STARTED));
tripRepository.save(new Trip(TRIP_ID2, USER_ID, FROM, TO, TripStatus.CREATED));
tripRepository.save(new Trip(TRIP_ID3, USER_ID, FROM, TO, TripStatus.COMPLETED));
tripRepository.save(new Trip(TRIP_ID4, USER_ID, FROM, TO, TripStatus.CANCELED));
}

@After
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.aitesting.microservices.tests.unit;

import static org.aitesting.microservices.tests.helpers.TestConstants.TRIP_ID1;
import static org.aitesting.microservices.tests.helpers.TestConstants.USER_ID;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.aitesting.microservices.tripmanagement.common.events.TripStatus;
import org.aitesting.microservices.tripmanagement.common.exceptions.NotFoundException;
import org.aitesting.microservices.tripmanagement.query.service.controllers.TripManagementController;
import org.aitesting.microservices.tripmanagement.query.service.repositories.TripRepository;
Expand Down Expand Up @@ -33,8 +35,8 @@ public void onGetTripsCall_FindAllIsCalled() {
verify(tripRepository, times(1)).findAll();
}

@Test(expected = NotFoundException.class)
public void onGetTripCall_FindOneIsCalled() throws NotFoundException {
@Test
public void onGetTripCall_FindOneIsCalled() {
//arrange

//act
Expand All @@ -43,4 +45,26 @@ public void onGetTripCall_FindOneIsCalled() throws NotFoundException {
//assert
verify(tripRepository, times(1)).findOne(TRIP_ID1);
}

@Test
public void ongetTripByUser_FindByUserIdCalled() {
//arrange

//act
tripManagementController.getTripByUser(USER_ID);

//assert
verify(tripRepository, times(1)).findByUserId(USER_ID);
}

@Test
public void ongetTripByUserAndStatus_FindByUserIdAndStatusIsCalled() {
//arrange

//act
tripManagementController.getTripByUserAndStatus(USER_ID, "completed");

//assert
verify(tripRepository, times(1)).findByUserIdAndStatus(USER_ID, TripStatus.COMPLETED);
}
}
Loading

0 comments on commit 0a777ea

Please sign in to comment.