Skip to content

Instantly share code, notes, and snippets.

@timwhit
Last active April 8, 2016 16:30
Show Gist options
  • Save timwhit/c87e82b43a7bf107d807 to your computer and use it in GitHub Desktop.
Save timwhit/c87e82b43a7bf107d807 to your computer and use it in GitHub Desktop.
Lego Monolith examples
@Configuration
public class Application {
public static final String SPRING_PROFILES_ACTIVE = "lego.profiles.active";
public static final String DEFAULT_PROFILE = "local";
public static void main(String[] args) throws Exception {
SimpleCommandLinePropertySource source = new SimpleCommandLinePropertySource(args);
String profile = Optional.ofNullable(source.getProperty(SPRING_PROFILES_ACTIVE)).orElse(DEFAULT_PROFILE);
start(SalesApplication.class).profiles(profile + ".sales").run(args);
start(SupportApplication.class).profiles(profile + ".support").run(args);
start(ProductApplication.class).profiles(profile + ".product").run(args);
start(QueueApplication.class).profiles(profile + ".queue").web(false).run(args);
}
private static SpringApplicationBuilder start(Object sources) {
return new SpringApplicationBuilder(Application.class).showBanner(false).child(sources);
}
}
{
"productId": 1,
"userId": 1,
"quantity": 1,
"amount": 10.00
}
//product-web:
dependencies {
compile project(':product-vo')
compile project(':product-service')
compile project(':common')
runtime project(':product-service-impl')
}
//product-service:
dependencies {
compile project(':common')
}
//product-service-impl:
dependencies {
compile project(":common")
compile project(":product-service")
compile project(":product-data")
runtime project(":product-data-impl")
compile project(':sales-vo')
}
//product-data:
dependencies {
compile project(':common')
}
//product-data-impl:
dependencies {
compile project(':common')
compile project(':product-data')
}
@Service
@Validated
public class MessageSender {
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private ObjectMapper mapper;
public void sendMessage(Object message, String destination) {
try {
String s = mapper.writeValueAsString(message);
MessageCreator messageCreator = session -> session.createTextMessage(s);
this.jmsTemplate.send(destination, messageCreator);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
apply plugin: 'eclipse-wtp'
apply plugin: 'spring-boot'
dependencies {
compile project(':sales-web')
compile project(':support-web')
compile project(':product-web')
compile project(':queue')
}
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
}
}
springBoot {
mainClass = "com.whitney.parent.Application"
}
bootRun {
// pass command line options from gradle to bootRun
// usage: gradlew bootRun "-Dspring.profiles.active=local,protractor"
if (System.properties.containsKey('spring.profiles.active')) {
systemProperty "spring.profiles.active", System.properties['spring.profiles.active']
}
}
@Configuration
@EnableAutoConfiguration
@EnableJms
@ComponentScan(value = { "com.whitney.product", "com.whitney.common" })
public class ProductApplication extends AnnotationConfigEmbeddedWebApplicationContext {
}
@Repository
public class ProductDAOImpl implements ProductDAO {
private static final String URI = "http://localhost:8083/rest/product/{id}";
@Override
public ProductVO findById(Long productId) {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject(URI, ProductVO.class, productId);
}
}
@Validated
@Transactional
@Service
public class ProductServiceImpl implements ProductService {
//...
@Override
@JmsListener(destination = MessageQueue.SALE_CREATED)
public void processCompletedSale(String data) {
LOG.info("JMS Message Received: {}", data);
SaleVO sale;
try {
sale = this.objectMapper.readValue(data, SaleVO.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
ProductDTO productDTO = this.productDAO.findOne(sale.getProductId());
productDTO.setInventory(productDTO.getInventory() - sale.getQuantity());
this.productDAO.saveAndFlush(productDTO);
LOG.info("Product ID: [{}] inventory reduced to [{}]", productDTO.getId(), productDTO.getInventory());
}
}
subprojects {
apply plugin: 'java'
apply plugin: 'groovy'
apply plugin: 'idea'
apply plugin: 'eclipse'
apply plugin: 'com.github.youribonnaffe.gradle.format'
apply plugin: 'rebel'
apply plugin: 'jacoco'
apply plugin: "info.solidsoft.pitest"
apply plugin: "io.spring.dependency-management"
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
dependencyManagement {
imports {
mavenBom("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
}
}
compileJava.options.debugOptions.debugLevel = "source,lines,vars"
compileTestJava.options.debugOptions.debugLevel = "source,lines,vars"
repositories {
mavenCentral()
maven {
url "http://repo.spring.io/snapshot"
}
maven {
url "http://repo.spring.io/milestone"
}
}
dependencies {
//Spring
compile("org.springframework.boot:spring-boot-starter-web")
compile("org.springframework.boot:spring-boot-starter-data-jpa")
compile("org.springframework.boot:spring-boot-starter-security")
compile("org.springframework:spring-context-support") {
exclude(module: 'quartz')
}
// ...
}
}
@RestController
@RequestMapping("/rest/sales")
public class SalesController {
@Autowired
private SalesService salesService;
@Autowired
private MapperUtils mapper;
@RequestMapping(value = "/{salesId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public SaleVO get(@PathVariable Long salesId) {
return this.mapper.map(this.salesService.get(salesId), SaleVO.class);
}
@RequestMapping(value = "/", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public SaleVO create(@RequestBody SaleVO sale) {
Sale createdSale = this.salesService.create(this.mapper.map(sale, Sale.class));
return this.mapper.map(createdSale, SaleVO.class);
}
}
public interface SalesDAO extends JpaRepository<SaleDTO, Long> {}
@Validated
@Transactional
@Service
public class SalesServiceImpl implements SalesService {
@Autowired
private SalesDAO salesDAO;
@Autowired
private ProductDAO productDAO;
@Autowired
private MapperUtils mapper;
@Autowired
private MessageSender messageSender;
@Override
public Sale get(Long id) {
return this.mapper.map(this.salesDAO.findOne(id), Sale.class);
}
@Override
public Sale create(Sale sale) {
//call product service to check on inventory
ProductVO product = this.productDAO.findById(sale.getProductId());
if (product.getInventory() < sale.getQuantity()) {
throw new RuntimeException("Not enough inventory available for sale.");
}
SaleDTO saleDTO = this.mapper.map(sale, SaleDTO.class);
saleDTO.setCreatedDate(LocalDateTime.now());
saleDTO.setModifiedDate(LocalDateTime.now());
saleDTO.setCreatedUserId(1L);
saleDTO.setModifiedUserId(1L);
SaleDTO savedSale = this.salesDAO.saveAndFlush(saleDTO);
Sale completedSale = this.mapper.map(savedSale, Sale.class);
//send message to queue saying the sale was completed
this.messageSender.sendMessage(completedSale, MessageQueue.SALE_CREATED);
return completedSale;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment