From 16c48c29687bef763299321057767ff1fdcb0d4d Mon Sep 17 00:00:00 2001 From: talig Date: Thu, 14 Jun 2018 11:33:52 +0300 Subject: Start workflow be project Change-Id: Iac9fdaf21ba43113233f62a03b54bb4b756a461d Issue-ID: SDC-1396 Signed-off-by: talig --- .gitignore | 2 + workflow-designer-be/pom.xml | 53 ++++++++-- .../sdc/workflow/SpringBootWebApplication.java | 17 ++-- .../org/onap/sdc/workflow/api/RestConstants.java | 9 ++ .../onap/sdc/workflow/api/WorkflowController.java | 37 +++++++ .../onap/sdc/workflow/api/WorkflowsController.java | 23 ----- .../workflow/api/impl/WorkflowControllerImpl.java | 51 ++++++++++ .../sdc/workflow/api/types/CollectionWrapper.java | 18 ++++ .../onap/sdc/workflow/config/SwaggerConfig.java | 38 -------- .../persistence/UniqueValueRepository.java | 10 ++ .../persistence/types/UniqueValueEntity.java | 23 +++++ .../sdc/workflow/persistence/types/Workflow.java | 13 +++ .../persistence/types/WorkflowProperty.java | 9 ++ .../sdc/workflow/server/config/SwaggerConfig.java | 24 +++++ .../sdc/workflow/server/config/ZusammenConfig.java | 32 ++++++ .../server/filters/SessionContextFilter.java | 63 ++++++++++++ .../sdc/workflow/services/UniqueValueService.java | 107 +++++++++++++++++++++ .../sdc/workflow/services/WorkflowManager.java | 15 +++ .../errors/UniqueValueViolationException.java | 16 +++ .../services/errors/WorkflowNotFoundException.java | 13 +++ .../services/impl/CollaborationConfiguration.java | 22 +++++ .../services/impl/WorkflowManagerImpl.java | 76 +++++++++++++++ .../impl/mappers/ItemToWorkflowMapper.java | 16 +++ .../sdc/workflow/services/impl/mappers/Mapper.java | 80 +++++++++++++++ .../impl/mappers/WorkflowToItemMapper.java | 18 ++++ .../src/main/resources/application.properties | 7 +- 26 files changed, 712 insertions(+), 80 deletions(-) create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java delete mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowsController.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/impl/WorkflowControllerImpl.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java delete mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/config/SwaggerConfig.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowProperty.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/UniqueValueViolationException.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/WorkflowNotFoundException.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/CollaborationConfiguration.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ItemToWorkflowMapper.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/Mapper.java create mode 100644 workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowToItemMapper.java diff --git a/.gitignore b/.gitignore index 26a6c96e..7cf89408 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,5 @@ test1.json bpmnworkflow.bpmn20.xml dist *.log +.idea/ +*.iml diff --git a/workflow-designer-be/pom.xml b/workflow-designer-be/pom.xml index ddcb9c63..58041472 100644 --- a/workflow-designer-be/pom.xml +++ b/workflow-designer-be/pom.xml @@ -16,6 +16,7 @@ UTF-8 UTF-8 1.8 + 1.3.0-SNAPSHOT @@ -34,12 +35,15 @@ spring-boot-starter-jetty - + + org.springframework.boot + spring-boot-starter-data-cassandra + + + org.projectlombok + lombok + true + org.springframework.boot @@ -47,13 +51,16 @@ org.springframework.boot - spring-boot-starter-test - test + spring-boot-devtools + org.springframework.boot - spring-boot-devtools + spring-boot-starter-test + test + + io.springfox springfox-swagger-ui @@ -66,6 +73,34 @@ 2.8.0 compile + + org.openecomp.sdc + openecomp-sdc-versioning-api + ${onap.version} + + + org.openecomp.sdc + openecomp-sdc-versioning-core + ${onap.version} + runtime + + + org.openecomp.sdc.core + openecomp-zusammen-api + ${onap.version} + + + org.openecomp.sdc.core + openecomp-zusammen-core + ${onap.version} + runtime + + + javax.servlet + javax.servlet-api + + + diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java index e1bd8eac..b7e3b345 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java @@ -6,16 +6,15 @@ import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; import org.springframework.context.annotation.Bean; - @SpringBootApplication public class SpringBootWebApplication { - public static void main(String[] args) { - SpringApplication.run(SpringBootWebApplication.class, args); - } - @Bean - public ConfigurableServletWebServerFactory webServerFactory() { - JettyServletWebServerFactory factory = new JettyServletWebServerFactory(); - return factory; - } + public static void main(String[] args) { + SpringApplication.run(SpringBootWebApplication.class, args); + } + + @Bean + public ConfigurableServletWebServerFactory webServerFactory() { + return new JettyServletWebServerFactory(); + } } diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java new file mode 100644 index 00000000..8f02be0f --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java @@ -0,0 +1,9 @@ +package org.onap.sdc.workflow.api; + +public class RestConstants { + + private RestConstants() { + } + + public static final String USER_ID_HEADER_PARAM = "USER_ID"; +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java new file mode 100644 index 00000000..90657709 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java @@ -0,0 +1,37 @@ +package org.onap.sdc.workflow.api; + +import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.onap.sdc.workflow.api.types.CollectionWrapper; +import org.onap.sdc.workflow.persistence.types.Workflow; +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.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; + +@RequestMapping("/workflows") +@Api("Workflows") +public interface WorkflowController { + + @GetMapping + @ApiOperation("List workflows") + CollectionWrapper list(@RequestHeader(USER_ID_HEADER_PARAM) String user); + + @PostMapping + @ApiOperation("Create workflow") + Workflow create(@RequestBody Workflow workflow, @RequestHeader(USER_ID_HEADER_PARAM) String user); + + @GetMapping("/{id}") + @ApiOperation("Get workflow") + Workflow get(@PathVariable("id") String id, @RequestHeader(USER_ID_HEADER_PARAM) String user); + + @PutMapping("/{id}") + @ApiOperation("Update workflow") + Workflow update(@RequestBody Workflow workflow, @PathVariable("id") String id, + @RequestHeader(USER_ID_HEADER_PARAM) String user); +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowsController.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowsController.java deleted file mode 100644 index 229bc8c1..00000000 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowsController.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.onap.sdc.workflow.api; - -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Arrays; -import java.util.Collection; - -@RestController -@RequestMapping("/workflows") -@Api(value = "Workflows kalsjkaj") -public class WorkflowsController { - - @GetMapping - @ApiOperation(value = "List workflows", response = Collection.class) - public Collection list() { - return Arrays.asList("a", "c"); - } - -} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/impl/WorkflowControllerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/impl/WorkflowControllerImpl.java new file mode 100644 index 00000000..b7a122b8 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/impl/WorkflowControllerImpl.java @@ -0,0 +1,51 @@ +package org.onap.sdc.workflow.api.impl; + +import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; + +import org.onap.sdc.workflow.api.WorkflowController; +import org.onap.sdc.workflow.api.types.CollectionWrapper; +import org.onap.sdc.workflow.persistence.types.Workflow; +import org.onap.sdc.workflow.services.WorkflowManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; + +@RestController("workflowController") +public class WorkflowControllerImpl implements WorkflowController { + + private final WorkflowManager workflowManager; + + @Autowired + public WorkflowControllerImpl(@Qualifier("workflowManager") WorkflowManager workflowManager) { + this.workflowManager = workflowManager; + } + + @Override + public CollectionWrapper list(@RequestHeader(USER_ID_HEADER_PARAM) String user) { + return new CollectionWrapper<>(workflowManager.list()); + } + + @Override + public Workflow create(@RequestBody Workflow workflow, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + workflowManager.create(workflow); + return workflow; + } + + @Override + public Workflow get(@PathVariable("id") String id, @RequestHeader(USER_ID_HEADER_PARAM) String user) { + Workflow workflow = new Workflow(); + workflow.setId(id); + return workflowManager.get(workflow); + } + + @Override + public Workflow update(@RequestBody Workflow workflow, @PathVariable("id") String id, + @RequestHeader(USER_ID_HEADER_PARAM) String user) { + workflow.setId(id); + workflowManager.update(workflow); + return workflow; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java new file mode 100644 index 00000000..653b0dcf --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java @@ -0,0 +1,18 @@ +package org.onap.sdc.workflow.api.types; + +import java.util.Collection; +import lombok.Data; + +@Data +public class CollectionWrapper { + + private int total; + private int limit; + private int offset; + private Collection results; + + public CollectionWrapper(Collection results) { + this.results = results; + this.total = results.size(); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/config/SwaggerConfig.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/config/SwaggerConfig.java deleted file mode 100644 index ed317f4b..00000000 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/config/SwaggerConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -package org.onap.sdc.workflow.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.builders.RequestHandlerSelectors; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Contact; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; -import static springfox.documentation.builders.PathSelectors.regex; - -@Configuration -@EnableSwagger2 -public class SwaggerConfig { - - /*@Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.any()) - .paths(PathSelectors.any()) - .build(); - }*/ - - @Bean - public Docket api() { - return new Docket(DocumentationType.SWAGGER_2) - .select() - .apis(RequestHandlerSelectors.basePackage("org.onap.sdc.workflow.api")) - .paths(regex("/workflows.*")) - .build(); - } -} \ No newline at end of file diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java new file mode 100644 index 00000000..d374a404 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java @@ -0,0 +1,10 @@ +package org.onap.sdc.workflow.persistence; + +import org.onap.sdc.workflow.persistence.types.UniqueValueEntity; +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UniqueValueRepository extends CassandraRepository { + +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java new file mode 100644 index 00000000..925ec5cb --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java @@ -0,0 +1,23 @@ +package org.onap.sdc.workflow.persistence.types; + +import static org.springframework.data.cassandra.core.cql.PrimaryKeyType.PARTITIONED; + +import lombok.Data; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; +import org.springframework.data.cassandra.core.mapping.Table; + +@Table("unique_value") +@Data +public class UniqueValueEntity { + + @PrimaryKeyColumn(ordinal = 0, type = PARTITIONED) + private String type; + + @PrimaryKeyColumn(ordinal = 1, type = PARTITIONED) + private String value; + + public UniqueValueEntity(String type, String value) { + this.type = type; + this.value = value; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java new file mode 100644 index 00000000..76a6591c --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java @@ -0,0 +1,13 @@ +package org.onap.sdc.workflow.persistence.types; + + +import lombok.Data; + +@Data +public class Workflow { + + private String id; + private String name; + private String description; + private String category; +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowProperty.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowProperty.java new file mode 100644 index 00000000..6c2d804d --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowProperty.java @@ -0,0 +1,9 @@ +package org.onap.sdc.workflow.persistence.types; + +public final class WorkflowProperty { + + private WorkflowProperty() { + } + + public static final String CATEGORY = "category"; +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java new file mode 100644 index 00000000..5105114f --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java @@ -0,0 +1,24 @@ +package org.onap.sdc.workflow.server.config; + +import static springfox.documentation.builders.PathSelectors.regex; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + @Bean + public Docket api() { + return new Docket(DocumentationType.SWAGGER_2) + .select() + .apis(RequestHandlerSelectors.basePackage("org.onap.sdc.workflow.api")) + .paths(regex("/workflows.*")) + .build(); + } +} \ No newline at end of file diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java new file mode 100644 index 00000000..092c3464 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java @@ -0,0 +1,32 @@ +package org.onap.sdc.workflow.server.config; + +import javax.annotation.PostConstruct; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ZusammenConfig { + + @Value("${zusammen-tenant:workflow}") + private String tenant; + @Value("${spring.data.cassandra.contact-points:localhost}") + private String cassandraAddress; + @Value("${spring.data.cassandra.username:}") + private String cassandraUser; + @Value("${spring.data.cassandra.password:}") + private String cassandraPassword; + @Value("${zusammen.cassandra.isAuthenticate:false}") + private String cassandraAuth; + + @PostConstruct + public void init(){ + System.setProperty("cassandra.nodes", cassandraAddress); + System.setProperty("cassandra.user", cassandraUser); + System.setProperty("cassandra.password", cassandraPassword); + System.setProperty("cassandra.authenticate", Boolean.toString(Boolean.valueOf(cassandraAuth))); + } + + public String getTenant() { + return tenant; + } +} \ No newline at end of file diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java new file mode 100644 index 00000000..d4dc8a80 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java @@ -0,0 +1,63 @@ +package org.onap.sdc.workflow.server.filters; + +import static org.onap.sdc.workflow.api.RestConstants.USER_ID_HEADER_PARAM; + +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import org.onap.sdc.workflow.server.config.ZusammenConfig; +import org.openecomp.sdc.common.session.SessionContextProvider; +import org.openecomp.sdc.common.session.SessionContextProviderFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class SessionContextFilter implements Filter { + + private ZusammenConfig zusammenConfig; + + @Autowired + public SessionContextFilter(ZusammenConfig zusammenConfig) { + this.zusammenConfig = zusammenConfig; + } + + @Override + public void init(FilterConfig filterConfig) { + // not implemented + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + SessionContextProvider contextProvider = SessionContextProviderFactory.getInstance().createInterface(); + + try { + if (servletRequest instanceof HttpServletRequest) { + + contextProvider.create(getUser(servletRequest), getTenant()); + } + + filterChain.doFilter(servletRequest, servletResponse); + } finally { + contextProvider.close(); + } + } + + @Override + public void destroy() { + // not implemented + } + + private String getUser(ServletRequest servletRequest) { + return ((HttpServletRequest) servletRequest).getHeader(USER_ID_HEADER_PARAM); + } + + private String getTenant() { + return zusammenConfig.getTenant(); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java new file mode 100644 index 00000000..e6e88ed9 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java @@ -0,0 +1,107 @@ +package org.onap.sdc.workflow.services; + +import java.util.Optional; +import org.onap.sdc.workflow.persistence.UniqueValueRepository; +import org.onap.sdc.workflow.persistence.types.UniqueValueEntity; +import org.onap.sdc.workflow.services.errors.UniqueValueViolationException; +import org.openecomp.core.utilities.CommonMethods; // todo get rid of +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service("uniqueValueService") +public class UniqueValueService { + + private static final char FORMATTED_UNIQUE_VALUE_SEPARATOR = '_'; + + private final UniqueValueRepository uniqueValueRepository; + + @Autowired + public UniqueValueService(UniqueValueRepository uniqueValueRepository) { + this.uniqueValueRepository = uniqueValueRepository; + } + + /** + * Create unique value. + * + * @param type the type + * @param uniqueCombination the unique combination + */ + public void createUniqueValue(String type, String... uniqueCombination) { + formatValue(uniqueCombination).ifPresent(formattedValue -> { + validateUniqueValue(type, formattedValue, uniqueCombination); + uniqueValueRepository.insert(new UniqueValueEntity(type, formattedValue)); + }); + } + + /** + * Delete unique value. + * + * @param type the type + * @param uniqueCombination the unique combination + */ + public void deleteUniqueValue(String type, String... uniqueCombination) { + formatValue(uniqueCombination) + .ifPresent(formattedValue -> uniqueValueRepository.delete(new UniqueValueEntity(type, formattedValue))); + + } + + /** + * Update unique value. + * + * @param type the type + * @param oldValue the old value + * @param newValue the new value + * @param uniqueContext the unique context + */ + public void updateUniqueValue(String type, String oldValue, String newValue, String... uniqueContext) { + if (newValue == null || !newValue.equalsIgnoreCase(oldValue)) { + createUniqueValue(type, CommonMethods.concat(uniqueContext, new String[] {newValue})); + deleteUniqueValue(type, CommonMethods.concat(uniqueContext, new String[] {oldValue})); + } + } + + /** + * Validate unique value. + * + * @param type the type + * @param uniqueCombination the unique combination + */ + public void validateUniqueValue(String type, String... uniqueCombination) { + formatValue(uniqueCombination) + .ifPresent(formattedValue -> validateUniqueValue(type, formattedValue, uniqueCombination)); + } + + /** + * Checks if a unique value is taken. + * + * @return true if the unique value is occupied, false otherwise + */ + public boolean isUniqueValueOccupied(String type, String... uniqueCombination) { + return formatValue(uniqueCombination).map(formattedValue -> isUniqueValueOccupied(type, formattedValue)) + .orElse(false); + } + + private void validateUniqueValue(String type, String formattedValue, String... uniqueCombination) { + if (isUniqueValueOccupied(type, formattedValue)) { + throw new UniqueValueViolationException(type, getValueWithoutContext(uniqueCombination)); + } + } + + private boolean isUniqueValueOccupied(String type, String formattedValue) { + return uniqueValueRepository.findById(new UniqueValueEntity(type, formattedValue)).isPresent(); + } + + private static Optional formatValue(String[] uniqueCombination) { + if (uniqueCombination == null || uniqueCombination.length == 0 + || getValueWithoutContext(uniqueCombination) == null) { + return Optional.empty(); + } + + uniqueCombination[uniqueCombination.length - 1] = getValueWithoutContext(uniqueCombination).toLowerCase(); + return Optional.of(CommonMethods.arrayToSeparatedString(uniqueCombination, FORMATTED_UNIQUE_VALUE_SEPARATOR)); + } + + private static String getValueWithoutContext(String... uniqueCombination) { + return uniqueCombination[uniqueCombination.length - 1]; + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java new file mode 100644 index 00000000..565c4f5a --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java @@ -0,0 +1,15 @@ +package org.onap.sdc.workflow.services; + +import java.util.Collection; +import org.onap.sdc.workflow.persistence.types.Workflow; + +public interface WorkflowManager { + + Collection list(); + + Workflow get(Workflow workflow); + + void create(Workflow workflow); + + void update(Workflow workflow); +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/UniqueValueViolationException.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/UniqueValueViolationException.java new file mode 100644 index 00000000..358863e9 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/UniqueValueViolationException.java @@ -0,0 +1,16 @@ +package org.onap.sdc.workflow.services.errors; + + +import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; + +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(UNPROCESSABLE_ENTITY) +public class UniqueValueViolationException extends RuntimeException { + + private static final String UNIQUE_VALUE_VIOLATION_MSG = "%s with the value '%s' already exists."; + + public UniqueValueViolationException(String uniqueType, String value) { + super(String.format(UNIQUE_VALUE_VIOLATION_MSG, uniqueType, value)); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/WorkflowNotFoundException.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/WorkflowNotFoundException.java new file mode 100644 index 00000000..46a6d5ef --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/WorkflowNotFoundException.java @@ -0,0 +1,13 @@ +package org.onap.sdc.workflow.services.errors; + +import static org.springframework.http.HttpStatus.NOT_FOUND; + +import org.springframework.web.bind.annotation.ResponseStatus; + +@ResponseStatus(NOT_FOUND) +public class WorkflowNotFoundException extends RuntimeException { + + public WorkflowNotFoundException(String workflowId) { + super(String.format("Workflow with id %s does not exist", workflowId)); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/CollaborationConfiguration.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/CollaborationConfiguration.java new file mode 100644 index 00000000..2a4cd5aa --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/CollaborationConfiguration.java @@ -0,0 +1,22 @@ +package org.onap.sdc.workflow.services.impl; + +import org.openecomp.sdc.versioning.ItemManager; +import org.openecomp.sdc.versioning.ItemManagerFactory; +import org.openecomp.sdc.versioning.VersioningManager; +import org.openecomp.sdc.versioning.VersioningManagerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CollaborationConfiguration { + + @Bean + public ItemManager itemManager() { + return ItemManagerFactory.getInstance().createInterface(); + } + + @Bean + public VersioningManager versioningManager() { + return VersioningManagerFactory.getInstance().createInterface(); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java new file mode 100644 index 00000000..40750f10 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java @@ -0,0 +1,76 @@ +package org.onap.sdc.workflow.services.impl; + +import java.util.Collection; +import java.util.stream.Collectors; +import org.onap.sdc.workflow.persistence.types.Workflow; +import org.onap.sdc.workflow.services.UniqueValueService; +import org.onap.sdc.workflow.services.WorkflowManager; +import org.onap.sdc.workflow.services.errors.WorkflowNotFoundException; +import org.onap.sdc.workflow.services.impl.mappers.ItemToWorkflowMapper; +import org.onap.sdc.workflow.services.impl.mappers.WorkflowToItemMapper; +import org.openecomp.sdc.versioning.ItemManager; +import org.openecomp.sdc.versioning.types.Item; +import org.openecomp.sdc.versioning.types.ItemStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service("workflowManager") +public class WorkflowManagerImpl implements WorkflowManager { + + public static final String WORKFLOW_TYPE = "WORKFLOW"; + private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME"; + private final ItemManager itemManager; + private final UniqueValueService uniqueValueService; + + @Autowired + public WorkflowManagerImpl(ItemManager itemManager, + @Qualifier("uniqueValueService") UniqueValueService uniqueValueService) { + this.itemManager = itemManager; + this.uniqueValueService = uniqueValueService; + } + + @Override + public Collection list() { + ItemToWorkflowMapper mapper = new ItemToWorkflowMapper(); + return itemManager.list(item -> WORKFLOW_TYPE.equals(item.getType())).stream() + .map(item -> mapper.applyMapping(item, Workflow.class)).collect(Collectors.toList()); + } + + @Override + public Workflow get(Workflow workflow) { + ItemToWorkflowMapper mapper = new ItemToWorkflowMapper(); + Item retrievedItem = itemManager.get(workflow.getId()); + if (retrievedItem == null) { + throw new WorkflowNotFoundException(workflow.getId()); + } + return mapper.applyMapping(retrievedItem, Workflow.class); + } + + @Override + public void create(Workflow workflow) { + Item item = new WorkflowToItemMapper().applyMapping(workflow, Item.class); + item.setStatus(ItemStatus.ACTIVE); + + uniqueValueService.validateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflow.getName()); + workflow.setId(itemManager.create(item).getId()); + uniqueValueService.createUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflow.getName()); + } + + @Override + public void update(Workflow workflow) { + Item retrievedItem = itemManager.get(workflow.getId()); + if (retrievedItem == null) { + throw new WorkflowNotFoundException(workflow.getId()); + } + + uniqueValueService.updateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, retrievedItem.getName(), workflow.getName()); + + Item item = new WorkflowToItemMapper().applyMapping(workflow, Item.class); + item.setId(workflow.getId()); + item.setStatus(retrievedItem.getStatus()); + item.setVersionStatusCounters(retrievedItem.getVersionStatusCounters()); + + itemManager.update(item); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ItemToWorkflowMapper.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ItemToWorkflowMapper.java new file mode 100644 index 00000000..09e3cbd6 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ItemToWorkflowMapper.java @@ -0,0 +1,16 @@ +package org.onap.sdc.workflow.services.impl.mappers; + +import org.onap.sdc.workflow.persistence.types.Workflow; +import org.onap.sdc.workflow.persistence.types.WorkflowProperty; +import org.openecomp.sdc.versioning.types.Item; + +public class ItemToWorkflowMapper extends Mapper { + + @Override + public void map(Item source, Workflow target) { + target.setId(source.getId()); + target.setName(source.getName()); + target.setDescription(source.getDescription()); + target.setCategory((String) source.getProperties().get(WorkflowProperty.CATEGORY)); + } +} diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/Mapper.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/Mapper.java new file mode 100644 index 00000000..a66f8608 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/Mapper.java @@ -0,0 +1,80 @@ +package org.onap.sdc.workflow.services.impl.mappers; + +import org.openecomp.sdc.common.errors.CoreException; +import org.openecomp.sdc.common.errors.ErrorCode; + +/** + * Base class for all mapping classes. Mapping classes will perform data mapping from source object + * to target object Base class provides following
  1. provides life cycle of + * mapping class , first mapSimpleProperties is called and then mapComplexProperties is + * called.
  2. methods mapSimpleProperties and mapComplexProperties with default + * implementation, these should be overridden by concrete mapping classes for writing mapping + * logic.
+ */ + +public abstract class Mapper { + + /** + * Method is called for starting mapping from source object to target object method sets context + * in the thread locale and than calls mapSimpleProperties and mapComplexProperties + * respectively. + * + * @param source : source object for mapping + * @param clazz : target Class for mapping + * @return T - instance of type T + */ + + public final T applyMapping(final S source, Class clazz) { + T target = (T) instantiateTarget(clazz); + if (source != null && target != null) { + preMapping(source, target); + map(source, target); + postMapping(source, target); + + } + return target; + + } + + /** + * This method is called before the map method. + */ + protected void preMapping(final S source, T target) { + // extension point + } + + /** + * The actual method that does the mapping between the source to target + * objects. This method is being called automatically as part of the mapper class. This + * method must be override (it is abstract) by the mapper class. + * + * @param source - the source object. + * @param target - the target object. + */ + + public abstract void map(final S source, T target); + + /** + * This method is called after the map method. + */ + protected void postMapping(final S source, T target) { + // extension point + } + + /** + * Creates the instance of the input class. + * + * @return Object + */ + + private Object instantiateTarget(final Class clazz) { + + try { + return clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException exception) { + throw new CoreException((new ErrorCode.ErrorCodeBuilder()).withMessage(exception.getMessage()).build(), + exception); + } + } +} + diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowToItemMapper.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowToItemMapper.java new file mode 100644 index 00000000..0b569f09 --- /dev/null +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowToItemMapper.java @@ -0,0 +1,18 @@ +package org.onap.sdc.workflow.services.impl.mappers; + +import static org.onap.sdc.workflow.services.impl.WorkflowManagerImpl.WORKFLOW_TYPE; + +import org.onap.sdc.workflow.persistence.types.Workflow; +import org.onap.sdc.workflow.persistence.types.WorkflowProperty; +import org.openecomp.sdc.versioning.types.Item; + +public class WorkflowToItemMapper extends Mapper { + + @Override + public void map(Workflow source, Item target) { + target.setType(WORKFLOW_TYPE); + target.setName(source.getName()); + target.setDescription(source.getDescription()); + target.addProperty(WorkflowProperty.CATEGORY, source.getCategory()); + } +} diff --git a/workflow-designer-be/src/main/resources/application.properties b/workflow-designer-be/src/main/resources/application.properties index 5df521b5..b7cfc5aa 100644 --- a/workflow-designer-be/src/main/resources/application.properties +++ b/workflow-designer-be/src/main/resources/application.properties @@ -1,2 +1,7 @@ server.servlet.context-path=/wf -server.port=8080 \ No newline at end of file +server.port=8080 + +#CASSANDRA +spring.data.cassandra.contact-points=localhost +spring.data.cassandra.keyspace-name=workflow +spring.data.cassandra.port=9042 \ No newline at end of file -- cgit 1.2.3-korg