Event driven microservices tutorial (#15646)
* even driven microservices tutorial * restructure the project * remove mvn files * formatting
This commit is contained in:
+28
@@ -0,0 +1,28 @@
|
||||
package io.orkes.demo.banking;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.netflix.conductor.common.config.ObjectMapperProvider;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
@AllArgsConstructor
|
||||
@SpringBootApplication
|
||||
@ComponentScan(basePackages = { "io.orkes" })
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
// ObjectMapper instance used for JSON serialization - can be modified to configure additional modules
|
||||
@Bean
|
||||
public ObjectMapper getObjectMapper() {
|
||||
return new ObjectMapperProvider().getObjectMapper();
|
||||
}
|
||||
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package io.orkes.demo.banking.controller;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
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.RestController;
|
||||
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import io.orkes.demo.banking.service.FraudCheckService;
|
||||
import io.orkes.demo.banking.service.WorkflowService;
|
||||
import io.orkes.demo.banking.workers.FraudCheckResult;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@RestController
|
||||
public class APIController {
|
||||
|
||||
private final FraudCheckService fraudCheckService;
|
||||
|
||||
private final WorkflowService workflowService;
|
||||
|
||||
@PostMapping(value = "/triggerDeposit", produces = "application/json")
|
||||
public ResponseEntity<FraudCheckResult> triggerDeposit(@RequestBody DepositDetail depositDetail) {
|
||||
log.info("Checking for fraud: {}", depositDetail);
|
||||
return ResponseEntity.ok(fraudCheckService.checkForFraud(depositDetail));
|
||||
}
|
||||
|
||||
// docs-marker-start-1
|
||||
@PostMapping(value = "/checkForFraud", produces = "application/json")
|
||||
public Map<String, Object> checkForFraud(@RequestBody DepositDetail depositDetail) throws Exception {
|
||||
log.info("Checking if fraud check is required for: {}", depositDetail);
|
||||
return workflowService.executeWorkflow(depositDetail);
|
||||
}
|
||||
|
||||
// docs-marker-end-1
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.orkes.demo.banking.pojos;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class DepositDetail {
|
||||
|
||||
private String accountId;
|
||||
private BigDecimal amount;
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package io.orkes.demo.banking.service;
|
||||
|
||||
import static io.orkes.demo.banking.workers.FraudCheckResult.Result.FAIL;
|
||||
import static io.orkes.demo.banking.workers.FraudCheckResult.Result.PASS;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import io.orkes.demo.banking.workers.FraudCheckResult;
|
||||
|
||||
@Service
|
||||
public class FraudCheckService {
|
||||
|
||||
public FraudCheckResult checkForFraud(DepositDetail depositDetail) {
|
||||
FraudCheckResult fcr = new FraudCheckResult();
|
||||
if (depositDetail.getAmount()
|
||||
.compareTo(BigDecimal.valueOf(100000)) > 0) {
|
||||
fcr.setResult(FAIL);
|
||||
fcr.setReason("Amount too large");
|
||||
} else {
|
||||
fcr.setResult(PASS);
|
||||
fcr.setReason("All good!");
|
||||
}
|
||||
return fcr;
|
||||
}
|
||||
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package io.orkes.demo.banking.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.netflix.conductor.common.metadata.workflow.StartWorkflowRequest;
|
||||
|
||||
import io.orkes.conductor.client.WorkflowClient;
|
||||
import io.orkes.conductor.common.model.WorkflowRun;
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
@Service
|
||||
public class WorkflowService {
|
||||
|
||||
private final WorkflowClient workflowClient;
|
||||
|
||||
/**
|
||||
* Starts the workflow execution asynchronously
|
||||
* @param depositDetail
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Object> startDepositWorkflow(DepositDetail depositDetail) {
|
||||
StartWorkflowRequest request = new StartWorkflowRequest();
|
||||
request.setName("microservice_orchestration");
|
||||
Map<String, Object> inputData = new HashMap<>();
|
||||
inputData.put("amount", depositDetail.getAmount());
|
||||
inputData.put("accountId", depositDetail.getAccountId());
|
||||
request.setInput(inputData);
|
||||
|
||||
String workflowId = workflowClient.startWorkflow(request);
|
||||
log.info("Workflow id: {}", workflowId);
|
||||
return Map.of("workflowId", workflowId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the workflow, waits for it to complete and returns the output of the workflow
|
||||
* @param depositDetail
|
||||
* @return
|
||||
* @throws ExecutionException
|
||||
* @throws InterruptedException
|
||||
* @throws TimeoutException
|
||||
*/
|
||||
public Map<String, Object> executeWorkflow(DepositDetail depositDetail) throws ExecutionException, InterruptedException, TimeoutException {
|
||||
StartWorkflowRequest request = new StartWorkflowRequest();
|
||||
request.setName("microservice_orchestration");
|
||||
request.setVersion(1);
|
||||
Map<String, Object> inputData = new HashMap<>();
|
||||
inputData.put("amount", depositDetail.getAmount());
|
||||
inputData.put("accountId", depositDetail.getAccountId());
|
||||
request.setInput(inputData);
|
||||
|
||||
CompletableFuture<WorkflowRun> workflowRun = workflowClient.executeWorkflow(request, UUID.randomUUID()
|
||||
.toString(), 10);
|
||||
log.info("Workflow id: {}", workflowRun);
|
||||
|
||||
return workflowRun.get(10, TimeUnit.SECONDS)
|
||||
.getOutput();
|
||||
}
|
||||
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
package io.orkes.demo.banking.workers;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.netflix.conductor.sdk.workflow.task.InputParam;
|
||||
import com.netflix.conductor.sdk.workflow.task.WorkerTask;
|
||||
|
||||
import io.orkes.demo.banking.pojos.DepositDetail;
|
||||
import io.orkes.demo.banking.service.FraudCheckService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@AllArgsConstructor
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ConductorWorkers {
|
||||
|
||||
private final FraudCheckService fraudCheckService;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param amount
|
||||
* @return Given the amount, the service check if the fraud check should done before executing the transaction
|
||||
*/
|
||||
@WorkerTask(value = "fraud-check-required")
|
||||
public FraudCheckResult simpleWorker(@InputParam("amount") BigDecimal amount) {
|
||||
DepositDetail dd = new DepositDetail();
|
||||
dd.setAmount(amount);
|
||||
return fraudCheckService.checkForFraud(dd);
|
||||
}
|
||||
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package io.orkes.demo.banking.workers;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FraudCheckResult {
|
||||
|
||||
public enum Result {
|
||||
PASS,
|
||||
FAIL;
|
||||
}
|
||||
|
||||
private Result result;
|
||||
private String reason;
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
# swagger-ui custom path
|
||||
springdoc.swagger-ui.path=/swagger-ui.html
|
||||
management.endpoints.enabled-by-default=false
|
||||
management.endpoint.info.enabled=false
|
||||
server.port=8081
|
||||
# If you want to use Orkes Playground, then change the server url to https://play.orkes.io/api/
|
||||
# Obtain key and secret by logging into
|
||||
# and navigating to applications menu, create an application and generate key/secret
|
||||
conductor.security.client.key-id=CHANGE_ME
|
||||
conductor.security.client.secret=CHANGE_ME
|
||||
conductor.server.url=https://play.orkes.io/api/
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package io.orkes.demo.banking;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class ApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user