Skip to content

Commit

Permalink
feat: Create hexagonal applicant process application
Browse files Browse the repository at this point in the history
  • Loading branch information
Hafflgav committed Nov 29, 2023
1 parent 4e015a4 commit 08b3f60
Show file tree
Hide file tree
Showing 19 changed files with 398 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,76 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

</project>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>io.camunda</groupId>
<artifactId>spring-zeebe-starter</artifactId>
<version>${camunda8.version}</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.4</version>
</dependency>

<!--Kafka -->
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
</dependency>

<!--Miranum-->
<dependency>
<groupId>io.miragon.miranum</groupId>
<artifactId>worker-api</artifactId>
<version>${miranum.version}</version>
</dependency>
<dependency>
<groupId>io.miragon.miranum</groupId>
<artifactId>process-api</artifactId>
<version>${miranum.version}</version>
</dependency>
<dependency>
<groupId>io.miragon.miranum</groupId>
<artifactId>message-api</artifactId>
<version>${miranum.version}</version>
</dependency>
<dependency>
<groupId>io.miragon.miranum</groupId>
<artifactId>worker-adapter-c8</artifactId>
<version>${miranum.version}</version>
</dependency>
<dependency>
<groupId>io.miragon.miranum</groupId>
<artifactId>process-adapter-c8</artifactId>
<version>${miranum.version}</version>
</dependency>
<dependency>
<groupId>io.miragon.miranum</groupId>
<artifactId>message-adapter-c8</artifactId>
<version>${miranum.version}</version>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package applicant.employee.application;

import io.camunda.zeebe.spring.client.annotation.Deployment;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@Deployment(resources = "classpath*:**/restaurant-miranum.bpmn")
public class Applicant2EmployeeApplication {
public static void main(String[] args) {
SpringApplication.run(Applicant2EmployeeApplication.class, args);
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package applicant.employee.application.adapter.in.rest;

import applicant.employee.application.adapter.in.rest.dtos.PlaceApplicationRequestDto;
import applicant.employee.application.adapter.in.rest.dtos.PlaceApplicationResponseDto;
import applicant.employee.application.application.port.in.PlaceApplicationInCommand;
import applicant.employee.application.application.port.in.PlaceApplicationUseCase;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
@AllArgsConstructor
public class ApplicationController {
private final PlaceApplicationUseCase placeApplicationUseCase;

@PostMapping
@RequestMapping("/order")
public ResponseEntity<PlaceApplicationResponseDto> placeOrder(@RequestBody PlaceApplicationRequestDto placeApplicationRequestDto) {
var placeApplicationInCommand = new PlaceApplicationInCommand(placeApplicationRequestDto);
String applicationId = placeApplicationUseCase.placeApplication(placeApplicationInCommand);
String message = String.format("Thanks for submitting the request! We'll work on hiring %s for the position %s!",
placeApplicationRequestDto.getApplicantName(),
placeApplicationRequestDto.getPosition());

log.info("[{}] {}", applicationId, message);
return new ResponseEntity<>(new PlaceApplicationResponseDto(applicationId, message), HttpStatus.CREATED);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package applicant.employee.application.adapter.in.rest.dtos;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class PlaceApplicationRequestDto {
private String applicantName;
private String applicantAddress;
private String applicantPhone;
private String position;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package applicant.employee.application.adapter.in.rest.dtos;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class PlaceApplicationResponseDto {
private String applicationId;
private String message;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package applicant.employee.application.adapter.out.camunda;

import applicant.employee.application.application.port.out.placeApplication.PlaceApplicationOutCommand;
import applicant.employee.application.application.port.out.placeApplication.PlaceApplicationOutPort;
import io.miragon.miranum.connect.message.api.CorrelateMessageCommand;
import io.miragon.miranum.connect.message.api.MessageApi;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@AllArgsConstructor
@Component
public class MessageAdapter implements PlaceApplicationOutPort {
private final MessageApi messageApi;
private static final String MESSAGE_REFERENCE = "Message_offer_made";

@Override
public void placeApplication(PlaceApplicationOutCommand placeApplicationOutCommand) {
Map<String, Object> variables = new HashMap<>();
variables.put("applicationId", placeApplicationOutCommand.getApplication().getApplicationId());
variables.put("applicantName", placeApplicationOutCommand.getApplication().getApplicantName());
variables.put("applicantPhone", placeApplicationOutCommand.getApplication().getApplicantPhone());
variables.put("applicantAddress", placeApplicationOutCommand.getApplication().getApplicantAddress());
variables.put("applicantCity", placeApplicationOutCommand.getApplication().getPosition());

messageApi.correlateMessage(new CorrelateMessageCommand(
MESSAGE_REFERENCE,
placeApplicationOutCommand.getApplication().getApplicationId(),
variables));
log.info("[{}] Sent '{}'-Message to Process Engine.",
placeApplicationOutCommand.getApplication().getApplicationId(),
MESSAGE_REFERENCE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package applicant.employee.application.adapter.out.websocket;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

@Configuration
@EnableWebSocketMessageBroker
public class WebsocketConfig implements WebSocketMessageBrokerConfigurer {

@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
}

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/application").withSockJS();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package applicant.employee.application.adapter.out.websocket;

import applicant.employee.application.application.port.out.formFeedback.FormFeedbackOutCommand;
import applicant.employee.application.application.port.out.formFeedback.FormFeedbackOutPort;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.messaging.simp.SimpMessageSendingOperations;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@AllArgsConstructor
public class WebsocketNotificator implements FormFeedbackOutPort {

private SimpMessageSendingOperations messagingTemplate;

@Override
public void propagateFeedback(FormFeedbackOutCommand formFeedbackOutCommand) {
log.info("[{}] Notifying Customer: {}", formFeedbackOutCommand.getApplicationId(), formFeedbackOutCommand.getMessage());
messagingTemplate.convertAndSend(String.format("/topic/message/%s", formFeedbackOutCommand.getApplicationId()), formFeedbackOutCommand.getMessage());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package applicant.employee.application.application.port.in;

import applicant.employee.application.adapter.in.rest.dtos.PlaceApplicationRequestDto;
import lombok.Getter;

@Getter
public class PlaceApplicationInCommand {
private final String applicantName;
private final String applicantAddress;
private final String applicantPhone;
private final String position;

public PlaceApplicationInCommand(PlaceApplicationRequestDto placeApplicationInCommand) {
this.applicantName = placeApplicationInCommand.getApplicantName();
this.applicantAddress = placeApplicationInCommand.getApplicantAddress();
this.applicantPhone = placeApplicationInCommand.getApplicantPhone();
this.position = placeApplicationInCommand.getPosition();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package applicant.employee.application.application.port.in;

public interface PlaceApplicationUseCase {
String placeApplication(PlaceApplicationInCommand placeApplicationInCommand);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package applicant.employee.application.application.port.out.formFeedback;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class FormFeedbackOutCommand {
private String applicationId;
private String message;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package applicant.employee.application.application.port.out.formFeedback;

public interface FormFeedbackOutPort {
void propagateFeedback(FormFeedbackOutCommand formFeedbackOutCommand);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package applicant.employee.application.application.port.out.placeApplication;

import applicant.employee.application.domain.Application;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class PlaceApplicationOutCommand {
private Application application;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package applicant.employee.application.application.port.out.placeApplication;

public interface PlaceApplicationOutPort {

void placeApplication(PlaceApplicationOutCommand placeApplicationOutCommand);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package applicant.employee.application.application.service;

import applicant.employee.application.application.port.in.PlaceApplicationInCommand;
import applicant.employee.application.application.port.in.PlaceApplicationUseCase;
import applicant.employee.application.application.port.out.placeApplication.PlaceApplicationOutCommand;
import applicant.employee.application.application.port.out.placeApplication.PlaceApplicationOutPort;
import applicant.employee.application.domain.Application;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
public class PlaceApplicationService implements PlaceApplicationUseCase {
private final PlaceApplicationOutPort placeApplicationPort;

@Override
public String placeApplication(PlaceApplicationInCommand placeApplicationInCommand) {
var application = new Application(placeApplicationInCommand);
var placeOrderOutCommand = new PlaceApplicationOutCommand(application);
placeApplicationPort.placeApplication(placeOrderOutCommand);
return application.getApplicationId();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package applicant.employee.application.domain;

import applicant.employee.application.application.port.in.PlaceApplicationInCommand;
import lombok.Getter;

import java.time.LocalDateTime;

@Getter
public class Application {
private final String applicantName;
private final String applicantAddress;
private final String applicantPhone;
private final String position;
private final String applicationId;

public Application(PlaceApplicationInCommand placeApplicationInCommand) {
this.applicantName = placeApplicationInCommand.getApplicantName();
this.applicantAddress = placeApplicationInCommand.getApplicantAddress();
this.applicantPhone = placeApplicationInCommand.getApplicantPhone();
this.position = placeApplicationInCommand.getPosition();
this.applicationId = String.format("order-%s-%s", placeApplicationInCommand.getApplicantName().toLowerCase().replaceAll("\\s", ""), LocalDateTime.now());;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
server:
port: 8883

application:
kafka:
enabled: true

zeebe.client:
broker:
gateway-address: localhost:26500
security:
plaintext: true

spring.kafka.producer:
bootstrap-servers: localhost:9092
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
Loading

0 comments on commit 08b3f60

Please sign in to comment.