mirror of
https://github.com/HWienhold/indu-reboot.git
synced 2026-02-07 00:07:44 +00:00
added some basic moduls: appliance, site, gateway, discovery, task
This commit is contained in:
commit
2e18519fc1
50
appliance-service/pom.xml
Normal file
50
appliance-service/pom.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.indu</groupId>
|
||||
<artifactId>indu-flow-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>appliance-service</artifactId>
|
||||
<name>appliance-service</name>
|
||||
<description>Appliance Service</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-webflux</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,12 @@
|
||||
package com.indu.applianceservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ApplianceServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ApplianceServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,98 @@
|
||||
package com.indu.applianceservice.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.indu.applianceservice.dto.ApplianceRequest;
|
||||
import com.indu.applianceservice.dto.ApplianceResponse;
|
||||
import com.indu.applianceservice.dto.SiteResponse;
|
||||
import com.indu.applianceservice.exception.SiteNotFoundException;
|
||||
import com.indu.applianceservice.service.ApplianceService;
|
||||
import com.indu.applianceservice.utils.ApplianceState;
|
||||
|
||||
import jakarta.persistence.EntityNotFoundException;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@RestController
|
||||
@Slf4j
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/appliances")
|
||||
public class ApplianceController {
|
||||
private final ApplianceService service;
|
||||
|
||||
@GetMapping(path = "/{appliance_id}")
|
||||
public ResponseEntity<ApplianceResponse> getAppliance(@PathVariable Long appliance_id) {
|
||||
try {
|
||||
ApplianceResponse app = service.fetchById(appliance_id);
|
||||
return new ResponseEntity<ApplianceResponse>( app, HttpStatus.OK);
|
||||
} catch (EntityNotFoundException e) {
|
||||
log.warn("Could not find appliance with id \"{}\"", appliance_id);
|
||||
return new ResponseEntity<ApplianceResponse>(HttpStatus.NOT_FOUND);
|
||||
} catch (Exception e) {
|
||||
log.error("Unknown Exception: {}", e.getMessage());
|
||||
return new ResponseEntity<ApplianceResponse>(HttpStatus.INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping(path ="/site")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public List<ApplianceResponse> getAppliancesForSiteCode(@RequestParam(value="objectNumber") String object_number) {
|
||||
return service.getAppliancesForObject(object_number);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public List<ApplianceResponse> getAllAppliances() {
|
||||
return service.getAllAppliances();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<ApplianceResponse> createAppliance(@Valid @RequestBody ApplianceRequest applianceRequest) {
|
||||
SiteResponse[] siteOfAppliance = service.getSiteByCode(applianceRequest.getObjectNumber());
|
||||
if(siteOfAppliance.length == 0) {
|
||||
throw new SiteNotFoundException(applianceRequest.getObjectNumber());
|
||||
}
|
||||
return new ResponseEntity<ApplianceResponse>(service.createApplianceAndRegister(applianceRequest, siteOfAppliance[0].getId()), HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
//whatev....
|
||||
@GetMapping(path = "/{appliance_id}/site")
|
||||
public ResponseEntity<SiteResponse> getSite(@PathVariable Long appliance_id) {
|
||||
SiteResponse[] sites = service.getSiteOfId(appliance_id);
|
||||
if ( sites.length == 0) {
|
||||
log.warn("Found appliance with id " + appliance_id + " w/o site");
|
||||
return new ResponseEntity<SiteResponse>(HttpStatus.NOT_FOUND);
|
||||
} else if ( sites.length > 1 ) {
|
||||
log.warn("Found appliance with id " + appliance_id + " with " + sites.length + " sites");
|
||||
return new ResponseEntity<SiteResponse>(HttpStatus.CONFLICT);
|
||||
}
|
||||
return new ResponseEntity<SiteResponse>(sites[0] ,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PutMapping(path ="/{appliance_id}/state")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ApplianceResponse setState(@PathVariable Long appliance_id, ApplianceState state) {
|
||||
return service.setState(appliance_id, state);
|
||||
}
|
||||
|
||||
@GetMapping(path ="/{appliance_id}/state")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public ApplianceState setState(@PathVariable Long appliance_id) {
|
||||
return service.fetchById(appliance_id).getState();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.indu.applianceservice.dto;
|
||||
|
||||
import com.indu.applianceservice.utils.ApplianceState;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
public class ApplianceRequest {
|
||||
@NotNull
|
||||
private String qrCode;
|
||||
private String serialNumber;
|
||||
@NotNull
|
||||
private String objectNumber;
|
||||
private String applianceClass;
|
||||
private String applianceType;
|
||||
private ApplianceState state;
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.indu.applianceservice.dto;
|
||||
|
||||
import com.indu.applianceservice.utils.ApplianceState;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Getter
|
||||
@Setter
|
||||
public class ApplianceResponse {
|
||||
private Long id;
|
||||
private String qrCode;
|
||||
private String serialNumber;
|
||||
private String objectNumber;
|
||||
private String applianceClass;
|
||||
private String applianceType;
|
||||
private ApplianceState state;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.indu.applianceservice.dto;
|
||||
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
public class SiteResponse {
|
||||
|
||||
private String id;
|
||||
private String siteAddress;
|
||||
private String siteZip;
|
||||
private String siteCity;
|
||||
@NotNull
|
||||
private String code;
|
||||
private String description;
|
||||
private String state;
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.indu.applianceservice.exception;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import com.indu.applianceservice.model.ErrorMessage;
|
||||
|
||||
|
||||
@RestControllerAdvice
|
||||
public class ApplianceExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
@ExceptionHandler(value= {SiteNotFoundException.class} )
|
||||
public ResponseEntity<Object> handleSiteDuplicateException(Exception ex, WebRequest request) {
|
||||
String errorMessage = ex.getLocalizedMessage();
|
||||
if ( errorMessage == null) {
|
||||
errorMessage = ex.toString();
|
||||
}
|
||||
return new ResponseEntity<>(new ErrorMessage(new Date(), errorMessage), new HttpHeaders(), HttpStatus.CONFLICT);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.indu.applianceservice.exception;
|
||||
|
||||
public class SiteNotFoundException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static String errorMessage(String code) {
|
||||
return "No site with code " + code + " could be found. It is not allowed to add Aplliances w/o existing site";
|
||||
}
|
||||
|
||||
public SiteNotFoundException(String code) {
|
||||
super(errorMessage(code));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.indu.applianceservice.model;
|
||||
import com.indu.applianceservice.utils.ApplianceState;
|
||||
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.GeneratedValue;
|
||||
import jakarta.persistence.GenerationType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Entity
|
||||
@Table(name = "appliances")
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Appliance {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
private String qrCode;
|
||||
private String serialNumber;
|
||||
private String objectNumber;
|
||||
private String applianceClass;
|
||||
private String applianceType;
|
||||
private ApplianceState state;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.indu.applianceservice.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class ErrorMessage {
|
||||
Date timestamp;
|
||||
String errorMessage;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.indu.applianceservice.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.indu.applianceservice.model.Appliance;
|
||||
|
||||
@Service
|
||||
public interface ApplianceRepository extends JpaRepository<Appliance, Long>{
|
||||
|
||||
@Override
|
||||
public <S extends Appliance> S save(S appliance);
|
||||
|
||||
List<Appliance> findByObjectNumber(String objectNumber);
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
package com.indu.applianceservice.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
|
||||
import com.indu.applianceservice.dto.ApplianceRequest;
|
||||
import com.indu.applianceservice.dto.ApplianceResponse;
|
||||
import com.indu.applianceservice.dto.SiteResponse;
|
||||
import com.indu.applianceservice.model.Appliance;
|
||||
import com.indu.applianceservice.repository.ApplianceRepository;
|
||||
import com.indu.applianceservice.utils.ApplianceState;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class ApplianceService {
|
||||
private final ApplianceRepository repository;
|
||||
private final WebClient.Builder webClientBuilder;
|
||||
|
||||
public ApplianceResponse createApplianceAndRegister(ApplianceRequest request, String site_id) {
|
||||
Appliance app = Appliance.builder()
|
||||
.qrCode(request.getQrCode())
|
||||
.applianceClass(request.getApplianceClass())
|
||||
.applianceType(request.getApplianceType())
|
||||
.objectNumber(request.getObjectNumber())
|
||||
.serialNumber(request.getSerialNumber())
|
||||
.state(request.getState() == null ? ApplianceState.INITIAL : request.getState())
|
||||
.build();
|
||||
|
||||
repository.save(app);
|
||||
log.info("Added {} to db", app.getId());
|
||||
registerAppliance(app, site_id);
|
||||
return mapApplianceToResponse(app);
|
||||
}
|
||||
|
||||
public ApplianceResponse fetchById(long id) {
|
||||
Appliance app = repository.getReferenceById(id);
|
||||
return mapApplianceToResponse(app);
|
||||
}
|
||||
|
||||
private void registerAppliance(Appliance app, String site_id) {
|
||||
webClientBuilder.build().patch()
|
||||
.uri("http://localhost:8080/api/sites/" + site_id + "/register",
|
||||
uri-> uri.queryParam("id", app.getId()).build()
|
||||
).retrieve()
|
||||
.bodyToMono(SiteResponse.class)
|
||||
.doOnNext(res->log.info("Registered successfully app " + app.getId() + " to site " + site_id + " " + res))
|
||||
.doOnError(res->log.error("Registration of app " + app.getId() + " to site " + site_id + " failed " + res))
|
||||
.subscribe();
|
||||
}
|
||||
|
||||
public List<ApplianceResponse> getAppliancesForObject(String object_number) {
|
||||
List<Appliance> appliances = repository.findByObjectNumber(object_number);
|
||||
return appliances.stream().map(this::mapApplianceToResponse).toList();
|
||||
}
|
||||
|
||||
public List<ApplianceResponse> getAllAppliances() {
|
||||
List<Appliance> appliances = repository.findAll();
|
||||
log.info("Fetched appliances. Found {}", appliances.size());
|
||||
return appliances.stream().map(this::mapApplianceToResponse).toList();
|
||||
}
|
||||
|
||||
private ApplianceResponse mapApplianceToResponse(Appliance app) {
|
||||
return ApplianceResponse.builder()
|
||||
.serialNumber(app.getSerialNumber())
|
||||
.id(app.getId())
|
||||
.applianceClass(app.getApplianceClass())
|
||||
.applianceType(app.getApplianceType())
|
||||
.qrCode(app.getQrCode())
|
||||
.objectNumber(app.getObjectNumber())
|
||||
.state(app.getState())
|
||||
.build();
|
||||
}
|
||||
|
||||
public SiteResponse[] getSiteOfId(long id) {
|
||||
Appliance app = repository.getReferenceById(id);
|
||||
return getSiteByCode(app.getObjectNumber());
|
||||
}
|
||||
|
||||
public SiteResponse[] getSiteByCode(String code) {
|
||||
SiteResponse[] sites = webClientBuilder.build().get()
|
||||
.uri("http://localhost:8080/api/sites",
|
||||
uri->uri.queryParam("code", code).build()
|
||||
).retrieve()
|
||||
.bodyToMono(SiteResponse[].class)
|
||||
.block();
|
||||
return sites;
|
||||
}
|
||||
|
||||
public ApplianceResponse setState(Long id, ApplianceState new_state) {
|
||||
Appliance app = repository.getReferenceById(id);
|
||||
app.setState(new_state);
|
||||
repository.save(app);
|
||||
return mapApplianceToResponse(app);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
package com.indu.applianceservice.utils;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum ApplianceState {
|
||||
ACTIVE("active"),
|
||||
LOST("lost"),
|
||||
DELETED("deleted"),
|
||||
INACTIVE("inactive"),
|
||||
INITIAL("initial");
|
||||
|
||||
|
||||
private final String state;
|
||||
private ApplianceState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public ApplianceState of(String value) {
|
||||
for (ApplianceState state : values()) {
|
||||
if(state.getValue() == value) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
package com.indu.applianceservice.utils;
|
||||
|
||||
import jakarta.persistence.AttributeConverter;
|
||||
import jakarta.persistence.Converter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@Converter(autoApply = true)
|
||||
@Slf4j
|
||||
public class StateConverter implements AttributeConverter<ApplianceState, String>{
|
||||
|
||||
@Override
|
||||
public String convertToDatabaseColumn(ApplianceState attribute) {
|
||||
if (attribute== null) {
|
||||
return null;
|
||||
}
|
||||
log.info(attribute.getValue());
|
||||
return attribute.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApplianceState convertToEntityAttribute(String dbData) {
|
||||
if(dbData == null) {
|
||||
return null;
|
||||
}
|
||||
for (ApplianceState state : ApplianceState.values()) {
|
||||
if (state.getValue().equals(dbData)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
18
discovery-server/pom.xml
Normal file
18
discovery-server/pom.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.indu</groupId>
|
||||
<artifactId>indu-flow-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>discovery-server</artifactId>
|
||||
<name>discovery-server</name>
|
||||
<description>Inuducing Flow Discovery Server</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,15 @@
|
||||
package com.indu.discoveryservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableEurekaServer
|
||||
public class DiscoveryServiceApplication {
|
||||
|
||||
public static void main(String[] arg) {
|
||||
SpringApplication.run(DiscoveryServiceApplication.class, arg);
|
||||
}
|
||||
|
||||
}
|
||||
32
indu-gateway/pom.xml
Normal file
32
indu-gateway/pom.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.indu</groupId>
|
||||
<artifactId>indu-flow-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>indu-gateway</artifactId>
|
||||
<name>indu-api-gateway</name>
|
||||
<description>Api Gateway for InducingFlow</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-gateway</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,13 @@
|
||||
package com.indu.apigateway;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class ApiGatewayApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ApiGatewayApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
47
pom.xml
Normal file
47
pom.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.indu</groupId>
|
||||
<artifactId>indu-flow-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Inducing Flow3</name>
|
||||
<description>Container for induflow</description>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.0.8</version>
|
||||
</parent>
|
||||
<modules>
|
||||
<module>discovery-server</module>
|
||||
<module>appliance-service</module>
|
||||
<module>indu-gateway</module>
|
||||
<module>site-service</module>
|
||||
<module>task-service</module>
|
||||
<module>workflow-service</module>
|
||||
</modules>
|
||||
<properties>
|
||||
<org.mapstruct.version>1.5.5.Final</org.mapstruct.version>
|
||||
<spring-cloud.version>2022.0.3</spring-cloud.version>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
<scope>provided</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
47
site-service/pom.xml
Normal file
47
site-service/pom.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.indu</groupId>
|
||||
<artifactId>indu-flow-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>site-service</artifactId>
|
||||
<name>site-service</name>
|
||||
<description>Site Service</description>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@ -0,0 +1,12 @@
|
||||
package com.indu.siteservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SiteServiceApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SiteServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package com.indu.siteservice.configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.mongodb.core.convert.MongoCustomConversions;
|
||||
|
||||
import com.indu.siteservice.utils.ReadingStateConverter;
|
||||
import com.indu.siteservice.utils.WritingStateConverter;
|
||||
|
||||
@Configuration
|
||||
public class MongoDBConfiguration {
|
||||
|
||||
@Bean
|
||||
public MongoCustomConversions customConversion() {
|
||||
List<Converter<?,?>> converterList = new ArrayList<>();
|
||||
converterList.add(new ReadingStateConverter());
|
||||
converterList.add(new WritingStateConverter());
|
||||
return new MongoCustomConversions(converterList);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,67 @@
|
||||
package com.indu.siteservice.controller;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.indu.siteservice.dto.RestAddress;
|
||||
import com.indu.siteservice.dto.RestSite;
|
||||
import com.indu.siteservice.exceptions.SiteDuplicateException;
|
||||
import com.indu.siteservice.exceptions.SiteNotFoundException;
|
||||
import com.indu.siteservice.service.SiteService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/site")
|
||||
public class SiteController {
|
||||
private final SiteService service;
|
||||
|
||||
@PostMapping
|
||||
public ResponseEntity<RestSite> createAppliance(@Valid @RequestBody RestSite siteRequest) {
|
||||
if(service.findByCode(siteRequest).isPresent()) {
|
||||
throw new SiteDuplicateException(siteRequest.getCode());
|
||||
}
|
||||
return new ResponseEntity<>(service.createSite(siteRequest), HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@GetMapping(params= "code")
|
||||
public ResponseEntity<RestSite > getSiteByCode(@NotNull @RequestParam(value="code") String code) {
|
||||
Optional<RestSite> site = service.findByCode(code);
|
||||
if ( site.isEmpty()) {
|
||||
throw new SiteNotFoundException("code", code);
|
||||
}
|
||||
return new ResponseEntity<>(site.get(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping(path="/{site_id}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public RestSite getSiteById(@PathVariable String site_id) {
|
||||
return service.findById(site_id);
|
||||
}
|
||||
|
||||
@GetMapping(path="/{site_id}/address")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public RestAddress getAddressofSite(@PathVariable String site_id) {
|
||||
return service.getAddressbySiteId(site_id);
|
||||
}
|
||||
|
||||
@PutMapping(path="/{site_id}")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public RestSite updateSiteById(@Valid @RequestBody RestSite updateData, @PathVariable String site_id) {
|
||||
return service.updateById(site_id, updateData);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,42 @@
|
||||
package com.indu.siteservice.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.indu.siteservice.dto.RestSite;
|
||||
import com.indu.siteservice.service.SiteListService;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/sites")
|
||||
public class SiteListController {
|
||||
private final SiteListService service;
|
||||
|
||||
@GetMapping(params= "code")
|
||||
public ResponseEntity<List<RestSite> > getSiteByCode(@NotNull @RequestParam(value="code") String code) {
|
||||
return new ResponseEntity<>(service.findByCode(code), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
public ResponseEntity<List<RestSite> > getSitesAll() {
|
||||
return new ResponseEntity<>(service.findAll(), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PatchMapping(path="/{site_id}/register")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public RestSite registerAppliance(@PathVariable String site_id, @NotNull @RequestParam(value="id") long app_id){
|
||||
return service.registerAppliance(site_id, app_id);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
package com.indu.siteservice.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@Getter
|
||||
@NoArgsConstructor
|
||||
public class RestAddress {
|
||||
private String address;
|
||||
private String zip;
|
||||
private String city;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.indu.siteservice.dto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.indu.siteservice.utils.SiteState;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
public class RestSite {
|
||||
private String id;
|
||||
private String siteAddress;
|
||||
private String siteZip;
|
||||
private String siteCity;
|
||||
private String code;
|
||||
private String description;
|
||||
private SiteState state;
|
||||
private List<Long> applianceIds;
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.indu.siteservice.exceptions;
|
||||
|
||||
public class SiteCodeIdConflictException extends RuntimeException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static String errormessage(String id, String code, String correctCode) {
|
||||
return "The combination of id "+ id + " and code " + code+" is invalid. The expected code for this id is "+ correctCode;
|
||||
}
|
||||
|
||||
public SiteCodeIdConflictException(String id, String code, String correctCode) {
|
||||
super(errormessage(id, code, correctCode));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.indu.siteservice.exceptions;
|
||||
|
||||
public class SiteDuplicateException extends RuntimeException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static String errormessage(String code) {
|
||||
return "There already is a site with code "+code+". This value is expected to be unique";
|
||||
}
|
||||
|
||||
public SiteDuplicateException(String code) {
|
||||
super(errormessage(code));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.indu.siteservice.exceptions;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import com.indu.siteservice.model.ErrorMessage;
|
||||
|
||||
@ControllerAdvice
|
||||
public class SiteExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler(value= {SiteDuplicateException.class, SiteCodeIdConflictException.class, SiteNotFoundException.class} )
|
||||
public ResponseEntity<Object> handleSiteDuplicateException(Exception ex, WebRequest request) {
|
||||
String errorMessage = ex.getLocalizedMessage();
|
||||
if ( errorMessage == null) {
|
||||
errorMessage = ex.toString();
|
||||
}
|
||||
return new ResponseEntity<>(new ErrorMessage(new Date(), errorMessage), new HttpHeaders(), HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.indu.siteservice.exceptions;
|
||||
|
||||
public class SiteNotFoundException extends RuntimeException{
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static String errormessage(String field, String code) {
|
||||
return "Site with " + field + " "+code+" not found";
|
||||
}
|
||||
|
||||
public SiteNotFoundException(String field, String code) {
|
||||
super(errormessage(field, code));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.indu.siteservice.model;
|
||||
|
||||
import jakarta.validation.constraints.Pattern;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class Address {
|
||||
|
||||
@Size(min=3)
|
||||
private String city;
|
||||
@Size(min=4, max=6)
|
||||
@Pattern(regexp = "[1-9][0-9]+", message = "zip code may only contain numbers")
|
||||
private String zip;
|
||||
private String address;
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.indu.siteservice.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class ErrorMessage {
|
||||
private Date timestamp;
|
||||
private String message;
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.indu.siteservice.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Document(value= "seq")
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class Sequence {
|
||||
@Id
|
||||
private String id;
|
||||
@Builder.Default
|
||||
@NotNull
|
||||
private int humanReadableId = 1;
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.indu.siteservice.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import com.indu.siteservice.utils.SiteState;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Document(value= "site")
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class Site {
|
||||
@Id
|
||||
private String id;
|
||||
private Address address;
|
||||
@NotNull
|
||||
private String code;
|
||||
private String description;
|
||||
private SiteState state;
|
||||
@NotNull
|
||||
@Builder.Default
|
||||
private List<Long > appliances = new ArrayList<Long>();
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
package com.indu.siteservice.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
import com.indu.siteservice.model.Sequence;
|
||||
|
||||
public interface SeqRepository extends MongoRepository<Sequence, String>{
|
||||
|
||||
default public int getNextSequence() {
|
||||
List<Sequence> docs = findAll();
|
||||
if(docs.size() == 0) {
|
||||
Sequence sequence = new Sequence();
|
||||
save(sequence);
|
||||
return 1;
|
||||
}
|
||||
Sequence sequence = docs.get(docs.size()-1);
|
||||
sequence.setHumanReadableId(sequence.getHumanReadableId()+1);
|
||||
save(sequence);
|
||||
return sequence.getHumanReadableId();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
package com.indu.siteservice.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
import com.indu.siteservice.model.Site;
|
||||
|
||||
public interface SiteRepository extends MongoRepository<Site, String>{
|
||||
List<Site> findByCode(String code);
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.indu.siteservice.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.indu.siteservice.dto.RestSite;
|
||||
import com.indu.siteservice.model.Site;
|
||||
import com.indu.siteservice.repository.SiteRepository;
|
||||
import com.indu.siteservice.utils.SiteRestConverter;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SiteListService {
|
||||
private final SiteRepository repository;
|
||||
|
||||
public List<RestSite> findByCode(RestSite siteRequest) {
|
||||
return findByCode(siteRequest.getCode());
|
||||
}
|
||||
|
||||
public List<RestSite> findByCode(String code) {
|
||||
List<Site> sites = repository.findByCode(code);
|
||||
return sites.stream().map(SiteRestConverter::convert).toList();
|
||||
}
|
||||
|
||||
public List<RestSite> findAll() {
|
||||
List<Site> sites = repository.findAll();
|
||||
return sites.stream().map(SiteRestConverter::convert).toList();
|
||||
}
|
||||
|
||||
public RestSite registerAppliance(String site_id, long app_id) {
|
||||
Site site = repository.findById(site_id).get();
|
||||
site.getAppliances().add(app_id);
|
||||
repository.save(site);
|
||||
return SiteRestConverter.convert(site);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,77 @@
|
||||
package com.indu.siteservice.service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.indu.siteservice.dto.RestAddress;
|
||||
import com.indu.siteservice.dto.RestSite;
|
||||
import com.indu.siteservice.exceptions.SiteCodeIdConflictException;
|
||||
import com.indu.siteservice.exceptions.SiteNotFoundException;
|
||||
import com.indu.siteservice.model.Site;
|
||||
import com.indu.siteservice.repository.SeqRepository;
|
||||
import com.indu.siteservice.repository.SiteRepository;
|
||||
import com.indu.siteservice.utils.SiteRestConverter;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SiteService {
|
||||
private final SiteRepository repository;
|
||||
private final SeqRepository seqenceSupplier;
|
||||
|
||||
public RestSite createSite(RestSite siteRequest) {
|
||||
Site site = SiteRestConverter.convert(siteRequest);
|
||||
site.setCode(generateCustomId());
|
||||
repository.save(site);
|
||||
return SiteRestConverter.convert(site);
|
||||
}
|
||||
|
||||
public Optional<RestSite> findByCode(String code) {
|
||||
List<Site> sites = repository.findByCode(code);
|
||||
if(sites.size() == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
if (sites.size() > 1) {
|
||||
// throw new SiteDuplicateException(code);
|
||||
// dunno what todo...
|
||||
|
||||
}
|
||||
return Optional.of(SiteRestConverter.convert(sites.get(0)));
|
||||
}
|
||||
|
||||
public Site findSiteObjectById(String site_id) {
|
||||
return repository.findById(site_id).orElseThrow(() -> new SiteNotFoundException("boid", site_id));
|
||||
}
|
||||
|
||||
public Optional<RestSite> findByCode(@Valid RestSite siteRequest) {
|
||||
return findByCode(siteRequest.getCode());
|
||||
}
|
||||
|
||||
private String generateCustomId() {
|
||||
return String.format("O-%06d", seqenceSupplier.getNextSequence());
|
||||
}
|
||||
|
||||
public RestSite findById(String site_id) {
|
||||
return SiteRestConverter.convert( findSiteObjectById(site_id));
|
||||
}
|
||||
|
||||
public RestAddress getAddressbySiteId(String site_id) {
|
||||
return SiteRestConverter.convert(findSiteObjectById(site_id).getAddress());
|
||||
}
|
||||
|
||||
public RestSite updateById(String site_id, @Valid RestSite updateData) {
|
||||
Site site = findSiteObjectById(site_id);
|
||||
if ( !site.getCode().equals(updateData.getCode())) {
|
||||
throw new SiteCodeIdConflictException(site_id, updateData.getCode(), site.getCode());
|
||||
}
|
||||
Site updatedSite = SiteRestConverter.convert(updateData);
|
||||
updatedSite.setId(site.getId());
|
||||
repository.save(updatedSite);
|
||||
return SiteRestConverter.convert(updatedSite);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.indu.siteservice.utils;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.ReadingConverter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@ReadingConverter
|
||||
//@Converter(autoApply = true)
|
||||
public class ReadingStateConverter implements Converter<String, SiteState> {
|
||||
@Override
|
||||
public SiteState convert(String source) {
|
||||
// TODO Auto-generated method stub
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
for (SiteState state : SiteState.values()) {
|
||||
if (state.getValue().equals(source)) {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.indu.siteservice.utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.indu.siteservice.dto.RestAddress;
|
||||
import com.indu.siteservice.dto.RestSite;
|
||||
import com.indu.siteservice.model.Address;
|
||||
import com.indu.siteservice.model.Site;
|
||||
|
||||
public class SiteRestConverter {
|
||||
|
||||
public static RestSite convert(Site source) {
|
||||
return RestSite.builder()
|
||||
.siteAddress(source.getAddress().getAddress())
|
||||
.siteZip(source.getAddress().getZip())
|
||||
.siteCity(source.getAddress().getCity())
|
||||
.code(source.getCode())
|
||||
.state(source.getState())
|
||||
.description(source.getDescription())
|
||||
.applianceIds(source.getAppliances())
|
||||
.id(source.getId())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Site convert(RestSite source) {
|
||||
Address siteAddress = Address.builder()
|
||||
.zip(source.getSiteZip())
|
||||
.address(source.getSiteAddress())
|
||||
.city(source.getSiteCity())
|
||||
.build();
|
||||
|
||||
|
||||
return Site.builder()
|
||||
.address(siteAddress)
|
||||
.code(source.getCode())
|
||||
.appliances(source.getApplianceIds() == null ? new ArrayList<Long>() : source.getApplianceIds())
|
||||
.state(source.getState())
|
||||
.id(source.getId())
|
||||
.description(source.getDescription())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static RestAddress convert(Address address) {
|
||||
return RestAddress.builder()
|
||||
.address(address.getAddress())
|
||||
.city(address.getCity())
|
||||
.zip(address.getZip())
|
||||
.build();
|
||||
}
|
||||
|
||||
public static Address convert(RestAddress address) {
|
||||
return Address.builder()
|
||||
.address(address.getAddress())
|
||||
.city(address.getCity())
|
||||
.zip(address.getZip())
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.indu.siteservice.utils;
|
||||
|
||||
public enum SiteState {
|
||||
AKTIVE("active"),
|
||||
INACTIVE("inactive"),
|
||||
DELETED("deleted");
|
||||
|
||||
private final String state;
|
||||
private SiteState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return state;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.indu.siteservice.utils;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.convert.WritingConverter;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@WritingConverter
|
||||
//@Converter(autoApply = true)
|
||||
public class WritingStateConverter implements Converter<SiteState, String> {
|
||||
@Override
|
||||
public String convert(SiteState source) {
|
||||
// TODO Auto-generated method stub
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return source.getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* @Override public String convertToDatabaseColumn(SiteState attribute) { if
|
||||
* (attribute== null) { return null; } log.info(attribute.getValue()); return
|
||||
* attribute.getValue(); }
|
||||
*
|
||||
* @Override public SiteState convertToEntityAttribute(String dbData) {
|
||||
* if(dbData == null) { return null; } for (SiteState state :
|
||||
* SiteState.values()) { if (state.getValue().equals(dbData)) { return state; }
|
||||
* } return null; }
|
||||
*/
|
||||
73
task-service/pom.xml
Normal file
73
task-service/pom.xml
Normal file
@ -0,0 +1,73 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.indu</groupId>
|
||||
<artifactId>indu-flow-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
<artifactId>task-service</artifactId>
|
||||
<name>task-service</name>
|
||||
<description>Task Service</description>
|
||||
<properties>
|
||||
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<annotationProcessorPaths>
|
||||
<path>
|
||||
<groupId>org.mapstruct</groupId>
|
||||
<artifactId>mapstruct-processor</artifactId>
|
||||
<version>${org.mapstruct.version}</version>
|
||||
</path>
|
||||
</annotationProcessorPaths>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@ -0,0 +1,12 @@
|
||||
package com.indu.taskservice;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class TaskApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TaskApplication.class, args);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
package com.indu.taskservice.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.indu.taskservice.dto.TaskRequest;
|
||||
import com.indu.taskservice.dto.TaskResponse;
|
||||
import com.indu.taskservice.dto.TaskStateRequest;
|
||||
import com.indu.taskservice.service.TaskService;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping("/api/tasks")
|
||||
public class TaskController {
|
||||
private final TaskService service;
|
||||
|
||||
@GetMapping
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public List<TaskResponse> getAllTasks() {
|
||||
return service.getAllTasks();
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public TaskResponse createTask(@RequestBody TaskRequest request) {
|
||||
return service.createTask(request);
|
||||
}
|
||||
|
||||
@GetMapping(path="/{id}")
|
||||
public TaskResponse getTaskById(@RequestParam String id) {
|
||||
return service.getById(id);
|
||||
}
|
||||
|
||||
@PatchMapping(path="{id}/state")
|
||||
public TaskResponse setState(@RequestParam String id, @Valid @RequestBody TaskStateRequest taskRequest) {
|
||||
return service.updateState(id, taskRequest);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
package com.indu.taskservice.dto;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import com.indu.taskservice.model.Task;
|
||||
|
||||
@Mapper
|
||||
public interface TaskMapper {
|
||||
TaskMapper instance = Mappers.getMapper(TaskMapper.class);
|
||||
|
||||
TaskResponse taskToResponse(Task task);
|
||||
Task requestToTask(TaskRequest task);
|
||||
|
||||
@Mapping(target = "id", ignore = true)
|
||||
void updateTaskFromRequest(TaskRequest request, @MappingTarget Task task);
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.indu.taskservice.dto;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import com.indu.taskservice.model.TaskState;
|
||||
import com.indu.taskservice.model.User;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class TaskRequest {
|
||||
private String id;
|
||||
@NotNull
|
||||
private TaskState state;
|
||||
|
||||
private Map<String, String> data;
|
||||
private User editor;
|
||||
|
||||
@NotNull
|
||||
private Date lastEdited;
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.indu.taskservice.dto;
|
||||
|
||||
import com.indu.taskservice.model.TaskState;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class TaskResponse {
|
||||
private String id;
|
||||
private TaskState state;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
package com.indu.taskservice.dto;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.indu.taskservice.model.TaskState;
|
||||
import com.indu.taskservice.model.User;
|
||||
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Builder
|
||||
public class TaskStateRequest {
|
||||
@NotNull
|
||||
private TaskState state;
|
||||
@NotNull
|
||||
private User editor;
|
||||
@NotNull
|
||||
private Date lastEdited;
|
||||
}
|
||||
@ -0,0 +1,15 @@
|
||||
package com.indu.taskservice.exception;
|
||||
|
||||
import com.indu.taskservice.model.TaskState;
|
||||
|
||||
public class StateTransitionNotAllowedException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 4066544793849348805L;
|
||||
|
||||
public StateTransitionNotAllowedException(TaskState from, TaskState to) {
|
||||
super("State transition from " + from.name() +" to " + to.name() +" is not allowed");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.indu.taskservice.exception;
|
||||
|
||||
public class TaskChangedException extends RuntimeException {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 4066544793849348805L;
|
||||
|
||||
public TaskChangedException() {
|
||||
super("This task changed since last call. Retry");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,27 @@
|
||||
package com.indu.taskservice.exception;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
|
||||
|
||||
import com.indu.taskservice.model.ErrorMessage;
|
||||
|
||||
@ControllerAdvice
|
||||
public class TaskExceptionHandler extends ResponseEntityExceptionHandler {
|
||||
|
||||
@ExceptionHandler( value= {TaskChangedException.class, StateTransitionNotAllowedException.class})
|
||||
public ResponseEntity<Object> handleTaskAlreadyChangedException(Exception e, WebRequest request) {
|
||||
String errorMessage = e.getLocalizedMessage();
|
||||
if ( errorMessage == null) {
|
||||
errorMessage = e.toString();
|
||||
}
|
||||
return new ResponseEntity<>(new ErrorMessage(new Date(), errorMessage), new HttpHeaders(), HttpStatus.CONFLICT);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,5 @@
|
||||
package com.indu.taskservice.model;
|
||||
|
||||
public class Action {
|
||||
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
package com.indu.taskservice.model;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
@Setter
|
||||
public class ErrorMessage {
|
||||
private Date timestamp;
|
||||
private String message;
|
||||
}
|
||||
@ -0,0 +1,28 @@
|
||||
package com.indu.taskservice.model;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.data.mongodb.core.mapping.Document;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Document(value="task")
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Task {
|
||||
private String id;
|
||||
@Builder.Default
|
||||
private TaskState state = TaskState.WAITING;
|
||||
@Builder.Default
|
||||
private Map<String, String> data = new HashMap();
|
||||
private User editor;
|
||||
@Builder.Default
|
||||
private Date lastEdited = new Date();
|
||||
}
|
||||
@ -0,0 +1,16 @@
|
||||
package com.indu.taskservice.model;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TaskState {
|
||||
|
||||
WAITING(3),
|
||||
READY(5),
|
||||
IN_PROGRESS(8),
|
||||
DONE(10),
|
||||
ABORT(-10);
|
||||
|
||||
private final int state;
|
||||
}
|
||||
@ -0,0 +1,14 @@
|
||||
package com.indu.taskservice.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class User {
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String id;
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.indu.taskservice.repository;
|
||||
|
||||
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||
|
||||
import com.indu.taskservice.model.Task;
|
||||
|
||||
public interface TaskRepository extends MongoRepository<Task, String>{
|
||||
|
||||
|
||||
@Override
|
||||
Task save(Task entity);
|
||||
|
||||
}
|
||||
@ -0,0 +1,61 @@
|
||||
package com.indu.taskservice.service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.indu.taskservice.dto.TaskMapper;
|
||||
import com.indu.taskservice.dto.TaskRequest;
|
||||
import com.indu.taskservice.dto.TaskResponse;
|
||||
import com.indu.taskservice.dto.TaskStateRequest;
|
||||
import com.indu.taskservice.exception.StateTransitionNotAllowedException;
|
||||
import com.indu.taskservice.exception.TaskChangedException;
|
||||
import com.indu.taskservice.model.Task;
|
||||
import com.indu.taskservice.repository.TaskRepository;
|
||||
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.NotFoundException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
@Service
|
||||
public class TaskService {
|
||||
|
||||
private final TaskRepository repository;
|
||||
|
||||
public List<TaskResponse> getAllTasks() {
|
||||
return repository.findAll().stream().map(task -> TaskMapper.instance.taskToResponse(task)).toList();
|
||||
}
|
||||
|
||||
public TaskResponse createTask(TaskRequest request) {
|
||||
Task task = TaskMapper.instance.requestToTask(request);
|
||||
repository.save(task);
|
||||
return TaskMapper.instance.taskToResponse(task);
|
||||
}
|
||||
|
||||
public Task getTaskById(String id) {
|
||||
return repository.findById(id).orElseThrow(() -> new NotFoundException("did not find required task"));
|
||||
}
|
||||
|
||||
public TaskResponse getById(String id) {
|
||||
return TaskMapper.instance.taskToResponse(getTaskById(id));
|
||||
}
|
||||
|
||||
//TODO workflow
|
||||
public TaskResponse updateState(String id, @Valid TaskStateRequest taskRequest) {
|
||||
Task task = getTaskById(id);
|
||||
if(!task.getLastEdited().equals(taskRequest.getLastEdited())) {
|
||||
throw new TaskChangedException();
|
||||
}
|
||||
if(!TaskStateTransitionValidator.isTransitionAllowed(task.getState(), taskRequest.getState())) {
|
||||
throw new StateTransitionNotAllowedException(task.getState(), taskRequest.getState());
|
||||
}
|
||||
task.setEditor(taskRequest.getEditor());
|
||||
task.setLastEdited(new Date());
|
||||
task.setState(taskRequest.getState());
|
||||
repository.save(task);
|
||||
return TaskMapper.instance.taskToResponse(task);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
package com.indu.taskservice.service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.indu.taskservice.model.TaskState;
|
||||
|
||||
public class TaskStateTransitionValidator {
|
||||
|
||||
private final static Map<TaskState, List<TaskState>> allowedTransitions = new HashMap<TaskState, List<TaskState>>();
|
||||
|
||||
static {
|
||||
allowedTransitions.put(TaskState.WAITING, Arrays.asList(TaskState.READY, TaskState.DONE, TaskState.ABORT));
|
||||
allowedTransitions.put(TaskState.READY, Arrays.asList(TaskState.IN_PROGRESS, TaskState.ABORT));
|
||||
allowedTransitions.put(TaskState.IN_PROGRESS, Arrays.asList(TaskState.READY, TaskState.DONE, TaskState.ABORT));
|
||||
allowedTransitions.put(TaskState.DONE, Arrays.asList(TaskState.ABORT));
|
||||
allowedTransitions.put(TaskState.ABORT, Arrays.asList());
|
||||
}
|
||||
|
||||
public static boolean isTransitionAllowed(TaskState fromState, TaskState toState) {
|
||||
// for now throw nullpointerexception if allowedTransion if state gets add to enum, that is missing here
|
||||
return allowedTransitions.get(toState).contains(toState);
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user