Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/eventstore #10

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# msa-ddd-eventsourcing
msa,ddd,eventsourcing java example

## Run application

```$xslt
./run.sh
```
13 changes: 13 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "3.1"

services:
mongodb:
image: mongo:latest
ports:
- 27017:27017

rabbitmq:
image: rabbitmq:3.5.3-management
ports:
- 5672:5672
- 15672:15672
7 changes: 7 additions & 0 deletions run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

# Setup mongodb, rabbitmq
docker-compose up -d

# build & run application
./gradle build && java -jar build/libs/sample-msa-0.0.1.jar
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.itchain.samplemsa.samplemsa.common;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ActiveProfiles;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

@Component
public class AggregateRepository<T extends Aggregate> {

private EventRepository eventRepository;

// change it to eventStorageService on production.
@Autowired
public AggregateRepository(EventRepository eventRepository){
this.eventRepository = eventRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@

public interface Event {
String getID();

}
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.itchain.samplemsa.samplemsa.customer;

import com.itchain.samplemsa.samplemsa.common.AggregateRepository;
import com.itchain.samplemsa.samplemsa.common.Event;
import com.itchain.samplemsa.samplemsa.common.EventRepository;
import com.itchain.samplemsa.samplemsa.customer.domain.CustomerInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ActiveProfiles;

@Component
public class CustomerRepository extends AggregateRepository<CustomerInfo> {

public CustomerRepository(EventRepository eventRepository) {
super(eventRepository);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;

@AllArgsConstructor
@Data
@Getter
public class CustomerInfoDTO {
private String id;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.itchain.samplemsa.samplemsa.customer.domain.CustomerService;
import com.itchain.samplemsa.samplemsa.customer.domain.dto.CustomerInfoDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class CustomerServiceImpl implements CustomerService {
@Autowired
private HttpCustomerAdapter httpCustomerAdapter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.itchain.samplemsa.samplemsa.customer.port.adapter.service;

import com.itchain.samplemsa.samplemsa.customer.domain.dto.CustomerInfoDTO;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.util.Arrays;
import java.util.List;

@Component
public class HttpCustomerAdapter implements CustomerAdapter{
private static final String HOST = "localhost";
private static final String PORT = "8080";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
package com.itchain.samplemsa.samplemsa.customer.web.controller;

import com.itchain.samplemsa.samplemsa.customer.domain.CustomerInfo;
import com.itchain.samplemsa.samplemsa.customer.domain.dto.CustomerInfoDTO;
import com.itchain.samplemsa.samplemsa.customer.application.CustomerApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
public class CustomerController {
@Autowired
private CustomerApplicationService customerService;

@RequestMapping(value = "/customers/{id}", method = RequestMethod.GET)
@ResponseBody
public CustomerInfo getCustomer(@PathVariable("id") String id) {
return customerService.getCustomer(id);
}

@RequestMapping(value = "/customers/register-customer/{customerInfo}", method = RequestMethod.POST)
public void registerCustomer(@RequestParam(required = true) CustomerInfoDTO customerInfo) {
customerService.registerCustomer(customerInfo.getId(), customerInfo.getPw(), customerInfo.getName(), customerInfo.getAddress());
}

@RequestMapping(value = "/customers/remove-customer/{customerInfo}", method = RequestMethod.POST)
public void withdrawCustomer(@RequestParam(required = true) CustomerInfoDTO customerInfo) {
customerService.withdrawCustomer(customerInfo.getId(), customerInfo.getPw());
}

@RequestMapping(value = "/customers/edit-customer/{customerInfo}", method = RequestMethod.POST)
public void updateCustomer(@RequestParam(required = true) CustomerInfoDTO customerInfo) {
customerService.updateCustomer(customerInfo.getId(), customerInfo.getPw(), customerInfo.getName(), customerInfo.getAddress());
}

@RequestMapping(value = "/customers/get-point/{id}", method = RequestMethod.POST)
public int getCustomerPoint(@RequestParam(required = true) String id) {
return customerService.getCustomerPoint(id);
}
}
//package com.itchain.samplemsa.samplemsa.customer.web.controller;
//
//import com.itchain.samplemsa.samplemsa.customer.domain.CustomerInfo;
//import com.itchain.samplemsa.samplemsa.customer.domain.dto.CustomerInfoDTO;
//import com.itchain.samplemsa.samplemsa.customer.application.CustomerApplicationService;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.web.bind.annotation.*;
//
//@RestController
//public class CustomerController {
// @Autowired
// private CustomerApplicationService customerService;
//
// @RequestMapping(value = "/customers/{id}", method = RequestMethod.GET)
// @ResponseBody
// public CustomerInfo getCustomer(@PathVariable("id") String id) {
// return customerService.getCustomer(id);
// }
//
// @RequestMapping(value = "/customers/register-customer/{customerInfo}", method = RequestMethod.POST)
// public void registerCustomer(@RequestParam(required = true) CustomerInfoDTO customerInfo) {
// customerService.registerCustomer(customerInfo.getId(), customerInfo.getPw(), customerInfo.getName(), customerInfo.getAddress());
// }
//
// @RequestMapping(value = "/customers/remove-customer/{customerInfo}", method = RequestMethod.POST)
// public void withdrawCustomer(@RequestParam(required = true) CustomerInfoDTO customerInfo) {
// customerService.withdrawCustomer(customerInfo.getId(), customerInfo.getPw());
// }
//
// @RequestMapping(value = "/customers/edit-customer/{customerInfo}", method = RequestMethod.POST)
// public void updateCustomer(@RequestParam(required = true) CustomerInfoDTO customerInfo) {
// customerService.updateCustomer(customerInfo.getId(), customerInfo.getPw(), customerInfo.getName(), customerInfo.getAddress());
// }
//
// @RequestMapping(value = "/customers/get-point/{id}", method = RequestMethod.POST)
// public int getCustomerPoint(@RequestParam(required = true) String id) {
// return customerService.getCustomerPoint(id);
// }
//}
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//package com.itchain.samplemsa.samplemsa.delivery.controller;
package com.itchain.samplemsa.samplemsa.delivery.controller;//package com.itchain.samplemsa.samplemsa.delivery.controller;
//
//import com.itchain.samplemsa.samplemsa.delivery.domain.Delivery;
//import com.itchain.samplemsa.samplemsa.delivery.domain.TradeStatus;
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
2 changes: 2 additions & 0 deletions src/main/java/com/itchain/samplemsa/samplemsa/delivery/domain/dto/DeliveryDTO.java
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.itchain.samplemsa.samplemsa.delivery.domain.DeliverStatus;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;

@AllArgsConstructor
@Data
@Getter
public class DeliveryDTO {
private String id;
private String productId;
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//package com.itchain.samplemsa.samplemsa.delivery.application;
package com.itchain.samplemsa.samplemsa.delivery.service;//package com.itchain.samplemsa.samplemsa.delivery.application;
//
//import com.itchain.samplemsa.samplemsa.common.AggregateRepository;
//import com.itchain.samplemsa.samplemsa.common.Event;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.itchain.samplemsa.samplemsa.eventstore;

import com.itchain.samplemsa.samplemsa.common.Event;
import com.itchain.samplemsa.samplemsa.common.EventRepository;
import com.itchain.samplemsa.samplemsa.eventstore.domain.EntityWithIdAndEventList;
import com.itchain.samplemsa.samplemsa.eventstore.domain.Store;
import com.itchain.samplemsa.samplemsa.eventstore.exception.EventIDEmptyException;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class EventStorageService implements EventRepository {
private Store store;

public EventStorageService(Store store) {
this.store = store;
}

@Override
public void save(Event event) {
if (isEventIDEmpty(event)) {
throw new EventIDEmptyException();
}

store.save(event.getID(), event);
}

private boolean isEventIDEmpty(Event event) {
String eventID = event.getID();
return eventID == null || eventID.isEmpty();
}

@Override
public List<Event> load(String id) {
EntityWithIdAndEventList entity = store.load(id);
return entity.getEventList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.itchain.samplemsa.samplemsa.eventstore;

import com.itchain.samplemsa.samplemsa.common.Event;
import com.itchain.samplemsa.samplemsa.eventstore.domain.EntityWithIdAndEventList;
import com.itchain.samplemsa.samplemsa.eventstore.domain.Store;
import com.itchain.samplemsa.samplemsa.eventstore.domain.MongoClient;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Component
@Transactional
public class MongodbStore implements Store {
@Autowired
MongoClient client;

@Override
public EntityWithIdAndEventList save(String aggregateID, Event event) {
EntityWithIdAndEventList entity = load(aggregateID);
if (entity == null) {
entity = new EntityWithIdAndEventList();
}

entity.addEvent(event);

return client.save(entity);
}

@Override
public EntityWithIdAndEventList load(String aggregateID) {
Optional<EntityWithIdAndEventList> option = client.findById(aggregateID);
if (!option.isPresent()) {
return null;
}
return option.get();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.itchain.samplemsa.samplemsa.eventstore.domain;

import com.itchain.samplemsa.samplemsa.common.Event;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.ArrayList;
import java.util.List;

@Document(collection="event_entity")
@NoArgsConstructor
@ToString
@Getter
@Setter
public class EntityWithIdAndEventList {
@Id
private String id;

private List<Event> eventList = new ArrayList<>();

public void addEvent(Event event) {
this.eventList.add(event);
}

public void appendEventList(List<Event> eventList) {
this.eventList.addAll(eventList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.itchain.samplemsa.samplemsa.eventstore.domain;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;

@Repository
public interface MongoClient extends MongoRepository<EntityWithIdAndEventList, String> {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.itchain.samplemsa.samplemsa.eventstore.domain;

import com.itchain.samplemsa.samplemsa.common.Event;

public interface Store {
EntityWithIdAndEventList save(String aggregateID, Event event);
EntityWithIdAndEventList load(String aggregateID);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.itchain.samplemsa.samplemsa.eventstore.exception;

public class EventIDEmptyException extends EventStoreException{
public EventIDEmptyException() {
super("Event ID is empty");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.itchain.samplemsa.samplemsa.eventstore.exception;

public class EventStoreException extends RuntimeException {
public EventStoreException() {
super();
}

public EventStoreException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.itchain.samplemsa.samplemsa.pubsub;

import com.itchain.samplemsa.samplemsa.common.Event;
import lombok.*;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Getter
@Setter
@NoArgsConstructor
public class Publisher<T extends Event> {
@Autowired
private RabbitTemplate rabbitTemplate;

public void publish(String topic, T event) {
this.rabbitTemplate.convertAndSend(topic, event);
}
}
Loading