Start workflow be project 95/54795/1
authortalig <talig@amdocs.com>
Thu, 14 Jun 2018 08:33:52 +0000 (11:33 +0300)
committertalig <talig@amdocs.com>
Thu, 14 Jun 2018 08:33:52 +0000 (11:33 +0300)
Change-Id: Iac9fdaf21ba43113233f62a03b54bb4b756a461d
Issue-ID: SDC-1396
Signed-off-by: talig <talig@amdocs.com>
25 files changed:
.gitignore
workflow-designer-be/pom.xml
workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java
workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestConstants.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowsController.java [deleted file]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/impl/WorkflowControllerImpl.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionWrapper.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/Workflow.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/WorkflowProperty.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java [moved from workflow-designer-be/src/main/java/org/onap/sdc/workflow/config/SwaggerConfig.java with 53% similarity]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ZusammenConfig.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/UniqueValueViolationException.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/errors/WorkflowNotFoundException.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/CollaborationConfiguration.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ItemToWorkflowMapper.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/Mapper.java [new file with mode: 0644]
workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowToItemMapper.java [new file with mode: 0644]
workflow-designer-be/src/main/resources/application.properties

index 26a6c96..7cf8940 100644 (file)
@@ -14,3 +14,5 @@ test1.json
 bpmnworkflow.bpmn20.xml
 dist
 *.log
+.idea/
+*.iml
index ddcb9c6..5804147 100644 (file)
@@ -16,6 +16,7 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
         <java.version>1.8</java.version>
+        <onap.version>1.3.0-SNAPSHOT</onap.version>
     </properties>
 
     <dependencies>
             <artifactId>spring-boot-starter-jetty</artifactId>
         </dependency>
 
-        <!--
-                <dependency>
-                    <groupId>org.springframework.boot</groupId>
-                    <artifactId>spring-boot-starter-data-cassandra</artifactId>
-                </dependency>
-        -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-cassandra</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <optional>true</optional>
+        </dependency>
 
         <dependency>
             <groupId>org.springframework.boot</groupId>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-test</artifactId>
-            <scope>test</scope>
+            <artifactId>spring-boot-devtools</artifactId>
         </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-devtools</artifactId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
         </dependency>
+
+
         <dependency>
             <groupId>io.springfox</groupId>
             <artifactId>springfox-swagger-ui</artifactId>
             <version>2.8.0</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-sdc-versioning-api</artifactId>
+            <version>${onap.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc</groupId>
+            <artifactId>openecomp-sdc-versioning-core</artifactId>
+            <version>${onap.version}</version>
+            <scope>runtime</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-zusammen-api</artifactId>
+            <version>${onap.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.openecomp.sdc.core</groupId>
+            <artifactId>openecomp-zusammen-core</artifactId>
+            <version>${onap.version}</version>
+            <scope>runtime</scope>
+            <exclusions>
+                <exclusion>
+                    <groupId>javax.servlet</groupId>
+                    <artifactId>javax.servlet-api</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
 
     </dependencies>
 
index e1bd8ea..b7e3b34 100644 (file)
@@ -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 (file)
index 0000000..8f02be0
--- /dev/null
@@ -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 (file)
index 0000000..9065770
--- /dev/null
@@ -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<Workflow> 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 (file)
index 229bc8c..0000000
+++ /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<String> 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 (file)
index 0000000..b7a122b
--- /dev/null
@@ -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<Workflow> 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 (file)
index 0000000..653b0dc
--- /dev/null
@@ -0,0 +1,18 @@
+package org.onap.sdc.workflow.api.types;
+
+import java.util.Collection;
+import lombok.Data;
+
+@Data
+public class CollectionWrapper<T> {
+
+    private int total;
+    private int limit;
+    private int offset;
+    private Collection<T> results;
+
+    public CollectionWrapper(Collection<T> results) {
+        this.results = results;
+        this.total = results.size();
+    }
+}
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 (file)
index 0000000..d374a40
--- /dev/null
@@ -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<UniqueValueEntity, UniqueValueEntity> {
+
+}
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 (file)
index 0000000..925ec5c
--- /dev/null
@@ -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 (file)
index 0000000..76a6591
--- /dev/null
@@ -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 (file)
index 0000000..6c2d804
--- /dev/null
@@ -0,0 +1,9 @@
+package org.onap.sdc.workflow.persistence.types;
+
+public final class WorkflowProperty {
+
+    private WorkflowProperty() {
+    }
+
+    public static final String CATEGORY = "category";
+}
@@ -1,32 +1,18 @@
-package org.onap.sdc.workflow.config;
+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 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)
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 (file)
index 0000000..092c346
--- /dev/null
@@ -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 (file)
index 0000000..d4dc8a8
--- /dev/null
@@ -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 (file)
index 0000000..e6e88ed
--- /dev/null
@@ -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<String> 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 (file)
index 0000000..565c4f5
--- /dev/null
@@ -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<Workflow> 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 (file)
index 0000000..358863e
--- /dev/null
@@ -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 (file)
index 0000000..46a6d5e
--- /dev/null
@@ -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 (file)
index 0000000..2a4cd5a
--- /dev/null
@@ -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 (file)
index 0000000..40750f1
--- /dev/null
@@ -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<Workflow> 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 (file)
index 0000000..09e3cbd
--- /dev/null
@@ -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<Item, Workflow> {
+
+    @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 (file)
index 0000000..a66f860
--- /dev/null
@@ -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<br>  <ol>  <li>provides life cycle of
+ * mapping class , first mapSimpleProperties is called and then  mapComplexProperties is
+ * called.</li>  <li>methods mapSimpleProperties and mapComplexProperties with default
+ * implementation, these should  be overridden by concrete mapping classes for writing mapping
+ * logic.</li>  </ol>
+ */
+
+public abstract class Mapper<S, T> {
+
+    /**
+     * 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 <code>Class</code> for mapping
+     * @return <code>T</code> - instance of type <code>T</code>
+     */
+
+    public final T applyMapping(final S source, Class<T> 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 <code>map</code> method.
+     */
+    protected void preMapping(final S source, T target) {
+        // extension point
+    }
+
+    /**
+     * The actual method that does the mapping between the <code>source</code> to <code>target</code>
+     * 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 <code>map</code> method.
+     */
+    protected void postMapping(final S source, T target) {
+        // extension point
+    }
+
+    /**
+     * Creates the instance of the input class.
+     *
+     * @return <code>Object</code>
+     */
+
+    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 (file)
index 0000000..0b569f0
--- /dev/null
@@ -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<Workflow, Item> {
+
+    @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());
+    }
+}
index 5df521b..b7cfc5a 100644 (file)
@@ -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