diff options
Diffstat (limited to 'sdc-workflow-designer-be')
133 files changed, 9373 insertions, 0 deletions
diff --git a/sdc-workflow-designer-be/docker/Dockerfile b/sdc-workflow-designer-be/docker/Dockerfile new file mode 100644 index 00000000..ea20fa5c --- /dev/null +++ b/sdc-workflow-designer-be/docker/Dockerfile @@ -0,0 +1,17 @@ +FROM openjdk:8-jdk-alpine + +EXPOSE 8080 + +USER root + +ARG ARTIFACT + +ADD ${ARTIFACT} /app.jar + +COPY org.onap.sdc.p12 /keystore +COPY org.onap.sdc.trust.jks /truststore + +COPY startup.sh . +RUN chmod 744 startup.sh + +ENTRYPOINT [ "./startup.sh" ]
\ No newline at end of file diff --git a/sdc-workflow-designer-be/docker/org.onap.sdc.p12 b/sdc-workflow-designer-be/docker/org.onap.sdc.p12 Binary files differnew file mode 100644 index 00000000..d03ca1c9 --- /dev/null +++ b/sdc-workflow-designer-be/docker/org.onap.sdc.p12 diff --git a/sdc-workflow-designer-be/docker/org.onap.sdc.trust.jks b/sdc-workflow-designer-be/docker/org.onap.sdc.trust.jks Binary files differnew file mode 100644 index 00000000..d07ce1a6 --- /dev/null +++ b/sdc-workflow-designer-be/docker/org.onap.sdc.trust.jks diff --git a/sdc-workflow-designer-be/docker/startup.sh b/sdc-workflow-designer-be/docker/startup.sh new file mode 100644 index 00000000..bc1d6463 --- /dev/null +++ b/sdc-workflow-designer-be/docker/startup.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +HTTPS_ENABLED=${SERVER_SSL_ENABLED:-"false"} +if [ "$HTTPS_ENABLED" = "true" ] +then + KEYSTORE=${SERVER_SSL_KEYSTORE_PATH} + if [ -f "$KEYSTORE" ]; then + echo "$KEYSTORE exist" + else + echo "Copying default keystore" + KEYSTORE_DIR=${KEYSTORE%/*} + mkdir -p $KEYSTORE_DIR + cp /keystore $KEYSTORE_DIR + chmod 755 $KEYSTORE + fi + + TRUSTSTORE=${SERVER_SSL_TRUSTSTORE_PATH} + if [ -f "$TRUSTSTORE" ]; then + echo "$TRUSTSTORE exist" + else + echo "Copying default truststore" + TRUSTSTORE_DIR=${TRUSTSTORE%/*} + mkdir -p $TRUSTSTORE_DIR + cp /truststore $TRUSTSTORE_DIR + chmod 755 $TRUSTSTORE + fi +fi +java ${JAVA_OPTIONS} -jar /app.jar ${SPRING_BOOT_OPTIONS}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/pom.xml b/sdc-workflow-designer-be/pom.xml new file mode 100644 index 00000000..aedc9ef0 --- /dev/null +++ b/sdc-workflow-designer-be/pom.xml @@ -0,0 +1,243 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <artifactId>sdc-workflow-designer-be</artifactId> + + <parent> + <groupId>org.onap.sdc.sdc-workflow-designer</groupId> + <artifactId>sdc-workflow-designer-parent</artifactId> + <version>1.7.0-SNAPSHOT</version> + </parent> + + <properties> + <spring.boot.version>2.1.0.RELEASE</spring.boot.version> + <mapstruct.version>1.3.1.Final</mapstruct.version> + <lombok.version>1.18.0</lombok.version> + <springfox.version>2.8.0</springfox.version> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-dependencies</artifactId> + <version>${spring.boot.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-web</artifactId> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-tomcat</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <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-devtools</artifactId> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-test</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger-ui</artifactId> + <version>${springfox.version}</version> + </dependency> + <dependency> + <groupId>io.springfox</groupId> + <artifactId>springfox-swagger2</artifactId> + <version>${springfox.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>openecomp-sdc-logging-api</artifactId> + <version>${onap.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>openecomp-sdc-logging-spring</artifactId> + <version>${onap.version}</version> + </dependency> + <dependency> + <groupId>org.openecomp.sdc</groupId> + <artifactId>openecomp-sdc-logging-core</artifactId> + <version>${onap.version}</version> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct</artifactId> + <version>${mapstruct.version}</version> + </dependency> + <dependency> + <groupId>org.mapstruct</groupId> + <artifactId>mapstruct-processor</artifactId> + <version>${mapstruct.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.projectlombok</groupId> + <artifactId>lombok</artifactId> + <version>${lombok.version}</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-actuator</artifactId> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-text</artifactId> + <version>1.3</version> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.6</version> + </dependency> + <dependency> + <groupId>commons-codec</groupId> + <artifactId>commons-codec</artifactId> + <version>1.9</version> + </dependency> + <dependency> + <groupId>org.onap.sdc.sdc-be-common</groupId> + <artifactId>session-lib</artifactId> + <version>1.6.0</version> + </dependency> + <dependency> + <groupId>org.onap.sdc.sdc-be-common</groupId> + <artifactId>versioning-lib</artifactId> + <version>1.6.0</version> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-cassandra</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.onap.sdc.sdc-be-common</groupId> + <artifactId>zusammen-lib</artifactId> + <version>1.6.0</version> + <exclusions> + <exclusion> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-cassandra</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.5.1</version> + </plugin> + <plugin> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-maven-plugin</artifactId> + <version>${spring.boot.version}</version> + <executions> + <execution> + <goals> + <goal>repackage</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <profiles> + <profile> + <id>docker</id> + <activation> + <activeByDefault>false</activeByDefault> + </activation> + <build> + <plugins> + <plugin> + <artifactId>maven-resources-plugin</artifactId> + <version>2.6</version> + <executions> + <execution> + <id>copy-resources-docker</id> + <phase>install</phase> + <goals> + <goal>copy-resources</goal> + </goals> + <configuration> + <outputDirectory>${basedir}/docker</outputDirectory> + <resources> + <resource> + <directory>${project.build.directory}</directory> + <include>${project.build.finalName}.jar</include> + </resource> + </resources> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>io.fabric8</groupId> + <artifactId>docker-maven-plugin</artifactId> + <configuration> + <images> + <image> + <name>onap/sdc-workflow-backend</name> + <build> + <tags> + <tag>${project.version}</tag> + </tags> + <dockerFileDir>${project.basedir}/docker</dockerFileDir> + <args> + <ARTIFACT>${project.build.finalName}.jar</ARTIFACT> + </args> + </build> + </image> + </images> + </configuration> + </plugin> + </plugins> + </build> + </profile> + </profiles> + +</project> + diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java new file mode 100644 index 00000000..87de212e --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/SpringBootWebApplication.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; + +@SpringBootApplication +@ComponentScan( {"org.onap.sdc.common", "org.onap.sdc.workflow"}) +public class SpringBootWebApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootWebApplication.class, args); + } + + @Bean + public ConfigurableServletWebServerFactory webServerFactory() { + return new JettyServletWebServerFactory(); + } + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ActivitySpecController.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ActivitySpecController.java new file mode 100644 index 00000000..ac72d46e --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ActivitySpecController.java @@ -0,0 +1,124 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; +import static org.onap.sdc.workflow.services.ActivitySpecConstant.VERSION_ID_DEFAULT_VALUE; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import java.util.stream.Collectors; +import javax.validation.Valid; +import org.onap.sdc.workflow.api.mappers.ActivitySpecDtoMapper; +import org.onap.sdc.workflow.api.types.CollectionResponse; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecActionRequest; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecCreateResponse; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecDataResponse; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecRequest; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecResponse; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; +import org.onap.sdc.workflow.services.ActivitySpecManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +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.RestController; + +@RequestMapping(value = "/v1.0/activity-spec") +@Api("Activity Specs") +@RestController("activitySpecController") +@Validated +public class ActivitySpecController { + + private final ActivitySpecManager activitySpecManager; + private final ActivitySpecDtoMapper activitySpecDtoMapper; + + @Autowired + public ActivitySpecController(@Qualifier("activitySpecManager") ActivitySpecManager activitySpecManager, + ActivitySpecDtoMapper activitySpecDtoMapper) { + this.activitySpecManager = activitySpecManager; + this.activitySpecDtoMapper = activitySpecDtoMapper; + } + + @GetMapping + @ApiOperation(value = "List activity specs", responseContainer = "List") + @ApiImplicitParam(name = USER_ID_HEADER, required = true, dataType = "string", paramType = "header") + public CollectionResponse<ActivitySpecResponse> list(@ApiParam(value = "List activity specs based on status filter", + allowableValues = "Draft,Certified,Deprecated,Deleted") @RequestParam(name = "status", required = false) + String versionStatus) { + return new CollectionResponse<>( + activitySpecManager.list(versionStatus).stream().map(activitySpecDtoMapper::toActivitySpecResponse) + .collect(Collectors.toList())); + } + + @PostMapping + @ApiOperation(value = "Create Activity Spec") + @ApiImplicitParam(name = USER_ID_HEADER, required = true, dataType = "string", paramType = "header") + public ResponseEntity<ActivitySpecCreateResponse> create(@Valid @RequestBody ActivitySpecRequest request) { + ActivitySpecEntity activitySpec = + activitySpecManager.createActivitySpec(activitySpecDtoMapper.fromActivitySpecRequest(request)); + return new ResponseEntity<>(new ActivitySpecCreateResponse(activitySpec.getId(),activitySpec.getVersionId()), + HttpStatus.CREATED); + } + + @GetMapping("/{id}/versions/{versionId}") + @ApiOperation(value = "Get Activity Spec") + @ApiImplicitParam(name = USER_ID_HEADER, required = true, dataType = "string", paramType = "header") + public ActivitySpecDataResponse get(@ApiParam(value = "Activity Spec Id") @PathVariable("id") String activitySpecId, + @ApiParam(value = "Version Id", defaultValue = VERSION_ID_DEFAULT_VALUE) @PathVariable("versionId") + String versionId) { + return activitySpecDtoMapper.toActivitySpecDataResponse( + activitySpecManager.get(new ActivitySpecEntity(activitySpecId, versionId))); + } + + @PutMapping("/{id}/versions/{versionId}") + @ApiOperation(value = "Update Activity Spec") + @ApiImplicitParam(name = USER_ID_HEADER, required = true, dataType = "string", paramType = "header") + public void update(@Valid @RequestBody ActivitySpecRequest request, + @ApiParam(value = "Activity Spec Id") @PathVariable("id") String activitySpecId, + @ApiParam(value = "Version Id", defaultValue = VERSION_ID_DEFAULT_VALUE) @PathVariable("versionId") + String versionId) { + ActivitySpecEntity activitySpec = activitySpecDtoMapper.fromActivitySpecRequest(request); + activitySpec.setId(activitySpecId); + activitySpec.setVersionId(versionId); + + activitySpecManager.update(activitySpec); + } + + @PutMapping("/{id}/versions/{versionId}/actions") + @ApiOperation(value = "Actions on a activity spec", + notes = "Performs one of the following actions on a activity spec: |" + "CERTIFY: Certifies activity spec.|" + + "DEPRECATE: Deprecates activity spec.|" + "DELETE: Deletes activity spec.") + @ApiImplicitParam(name = USER_ID_HEADER, required = true, dataType = "string", paramType = "header") + public void actOn(@Valid @RequestBody ActivitySpecActionRequest request, + @ApiParam(value = "Activity Spec Id") @PathVariable("id") String activitySpecId, + @ApiParam(value = "Version Id", defaultValue = VERSION_ID_DEFAULT_VALUE) @PathVariable("versionId") + String versionId) { + activitySpecManager + .actOnAction(new ActivitySpecEntity(activitySpecId, versionId), request.getAction()); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java new file mode 100644 index 00000000..2b24577a --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java @@ -0,0 +1,235 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static org.apache.commons.codec.digest.DigestUtils.md5Hex; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +import org.apache.http.conn.ssl.TrustStrategy; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; + +import java.util.Base64; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpHost; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.ssl.SSLContexts; +import org.onap.sdc.workflow.api.types.dto.ArtifactDeliveriesRequestDto; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.*; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.client.RestTemplate; + +import javax.net.ssl.SSLContext; + + +@Component("ArtifactAssociationHandler") +public class ArtifactAssociationService { + + private static final String WORKFLOW_ARTIFACT_TYPE = "WORKFLOW"; + private static final String WORKFLOW_ARTIFACT_DESCRIPTION = "Workflow Artifact Description"; + private static final String USER_ID_HEADER = "USER_ID"; + private static final String MD5_HEADER = "Content-MD5"; + private static final String X_ECOMP_INSTANCE_ID_HEADER = "X-ECOMP-InstanceID"; + private static final String INIT_ERROR_MSG = + "Failed while attaching workflow artifact to Operation in SDC. Parameters were not initialized: %s"; + private static final String INIT_CLIENT_MSG = + "Failed while creating the HTTP client to SDC. Following exception: %s"; + private static final Logger LOGGER = LoggerFactory.getLogger(ArtifactAssociationService.class); + @Value("${sdc.be.endpoint}") + private String sdcBeEndpoint; + @Value("${sdc.be.protocol}") + private String sdcBeProtocol; + @Value("${sdc.be.external.user}") + private String sdcUser; + @Value("${sdc.be.external.password}") + private String sdcPassword; + + private RestTemplate restClient; + + private KeyStore getKeyStore(String file, String password, String keyStoreType) throws IOException, GeneralSecurityException { + KeyStore keyStore = KeyStore.getInstance(keyStoreType); + File keyFile = new File(file); + try (FileInputStream inStr = new FileInputStream(keyFile)) { + keyStore.load(inStr, password.toCharArray()); + } + return keyStore; + + } + + + @Autowired + public ArtifactAssociationService(RestTemplateBuilder builder, + @Value("${server.ssl.trust-store}") + String truststorePath, + @Value("${server.ssl.trust-store-password}") + String truststorePassword, + @Value("${server.ssl.trust-store-type}") + String truststoreType, + @Value("${server.ssl.key-store}") + String keystorePath, + @Value("${server.ssl.key-password}") + String keystorePassword, + @Value("${server.ssl.key-store-type}") + String keystoreType, + @Value("${sdc.be.protocol}") + String protocol) { + if (protocol != null && + !protocol.equalsIgnoreCase(HttpHost.DEFAULT_SCHEME_NAME)) { + try { + KeyStore trustStore = getKeyStore(truststorePath, truststorePassword, truststoreType); + KeyStore keyStore = getKeyStore(keystorePath, keystorePassword, keystoreType); + + SSLContext sslcontext = SSLContexts.custom() + .loadKeyMaterial(keyStore, keystorePassword.toCharArray()) + .loadTrustMaterial(trustStore, new TrustSelfSignedStrategy()) + .build(); + SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( + sslcontext, + new NoopHostnameVerifier() + ); + CloseableHttpClient httpClient = + HttpClients.custom() + .setSSLSocketFactory(sslsf) + .setSSLHostnameVerifier(new NoopHostnameVerifier()) + .build(); + HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); + this.restClient = new RestTemplate(factory); + } catch (Exception e) { + LOGGER.error(String.format(INIT_CLIENT_MSG, e.getMessage()), e); + } + } else { + this.restClient = builder.build(); + } + } + + void setRestClient(RestTemplate restClient) { + this.restClient = restClient; + } + + void setSdcBeEndpoint(String value) { + this.sdcBeEndpoint = value; + } + + ResponseEntity<String> execute(String userId, ArtifactDeliveriesRequestDto deliveriesRequestDto, + ArtifactEntity artifactEntity) { + + Optional<String> initializationState = parametersInitializationState(); + if (initializationState.isPresent()) { + LOGGER.error(String.format(INIT_ERROR_MSG, initializationState.get())); + return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(String.format(INIT_ERROR_MSG, initializationState.get())); + } + + String formattedArtifact; + try { + formattedArtifact = getFormattedWorkflowArtifact(artifactEntity); + } catch (IOException e) { + LOGGER.error("Failed while attaching workflow artifact to Operation in SDC", e); + return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(e.getMessage()); + } + + HttpEntity<String> request = new HttpEntity<>(formattedArtifact, createHeaders(userId, formattedArtifact)); + + return restClient.exchange(sdcBeProtocol + "://" + sdcBeEndpoint + "/" + deliveriesRequestDto.getEndpoint(), + HttpMethod.valueOf(deliveriesRequestDto.getMethod()), request, String.class); + } + + Optional<String> parametersInitializationState() { + ArrayList<String> result = new ArrayList<>(); + if (sdcBeEndpoint == null || sdcBeEndpoint.equals("")) { + result.add("SDC_ENDPOINT"); + } + if (sdcBeProtocol == null || sdcBeProtocol.equals("")) { + result.add("SDC_PROTOCOL"); + } + if (sdcUser == null || sdcUser.equals("")) { + result.add("SDC_USER"); + } + if (sdcPassword == null || sdcPassword.equals("")) { + result.add("SDC_PASSWORD"); + } + + if (result.isEmpty() || this.restClient == null) { + return Optional.empty(); + } else { + return Optional.of(result.toString()); + } + } + + + private String getFormattedWorkflowArtifact(ArtifactEntity artifactEntity) throws IOException { + + byte[] encodeBase64 = Base64.getEncoder().encode(IOUtils.toByteArray(artifactEntity.getArtifactData())); + String encodedPayloadData = new String(encodeBase64); + + Map<String, String> artifactInfo = new HashMap<>(); + artifactInfo.put("artifactName", artifactEntity.getFileName()); + artifactInfo.put("payloadData", encodedPayloadData); + artifactInfo.put("artifactType", WORKFLOW_ARTIFACT_TYPE); + artifactInfo.put("description", WORKFLOW_ARTIFACT_DESCRIPTION); + + ObjectMapper mapper = new ObjectMapper(); + return mapper.writeValueAsString(artifactInfo); + } + + private HttpHeaders createHeaders(String userId, String formattedArtifact) { + HttpHeaders headers = new HttpHeaders(); + headers.add(USER_ID_HEADER, userId); + headers.add(HttpHeaders.AUTHORIZATION, createAuthorizationsHeaderValue(sdcUser, sdcPassword)); + headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); + headers.add(MD5_HEADER, calculateMD5Base64EncodedByString(formattedArtifact)); + headers.add(X_ECOMP_INSTANCE_ID_HEADER, "InstanceId"); + return headers; + } + + private String calculateMD5Base64EncodedByString(String data) { + String calculatedMd5 = md5Hex(data); + // encode base-64 result + byte[] encodeBase64 = Base64.getEncoder().encode(calculatedMd5.getBytes()); + return new String(encodeBase64); + } + + private String createAuthorizationsHeaderValue(String username, String password) { + String auth = username + ":" + password; + byte[] encodedAuth = Base64.getEncoder().encode(auth.getBytes(Charset.forName("US-ASCII"))); + return "Basic " + new String(encodedAuth); + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/DisableSwaggerController.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/DisableSwaggerController.java new file mode 100644 index 00000000..12d4b06c --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/DisableSwaggerController.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2019 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import javax.servlet.http.HttpServletResponse; + +import org.springframework.context.annotation.Profile; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Profile("!swagger") +@RestController +public class DisableSwaggerController { + @RequestMapping("swagger-ui.html") + public void swagger(HttpServletResponse response) { + response.setStatus(HttpStatus.NOT_FOUND.value()); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java new file mode 100644 index 00000000..70633d41 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ExceptionsHandler.java @@ -0,0 +1,119 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static org.springframework.http.HttpStatus.BAD_REQUEST; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; + +import java.util.function.Function; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.apache.commons.text.RandomStringGenerator; +import org.onap.sdc.workflow.api.types.ErrorResponse; +import org.onap.sdc.workflow.api.types.UnexpectedErrorResponse; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.InvalidArtifactException; +import org.onap.sdc.workflow.services.exceptions.UniqueValueViolationException; +import org.onap.sdc.workflow.services.exceptions.VersionCreationException; +import org.onap.sdc.workflow.services.exceptions.VersionModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.exceptions.VersionStatusModificationException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.springframework.context.support.DefaultMessageSourceResolvable; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.ServletRequestBindingException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; + +@ControllerAdvice +@RestController +public class ExceptionsHandler extends ResponseEntityExceptionHandler { + + private static final Logger LOG = LoggerFactory.getLogger(ExceptionsHandler.class); + + private static final String LOG_MSG = "Exception was mapped to {} response"; + private static final String UNEXPECTED_ERROR_MSG = "Something bad happened. Please contact support with code %s"; + private static final RandomStringGenerator CODE_GENERATOR = + new RandomStringGenerator.Builder().withinRange('A', 'Z').build(); + private static final int CODE_LENGTH = 8; + + private static final Function<Exception, UnexpectedErrorResponse> UNEXPECTED_EXCEPTION_MAPPER = + isDevInfoDisabled() + ? e -> new UnexpectedErrorResponse(getUnexpectedErrorMessage()) + : e -> new UnexpectedErrorResponse(getUnexpectedErrorMessage(), ExceptionUtils.getStackTrace(e)); + + @Override + public ResponseEntity<Object> handleServletRequestBindingException(ServletRequestBindingException ex, + HttpHeaders headers, HttpStatus status, WebRequest request) { + LOG.debug(LOG_MSG, BAD_REQUEST, ex); + // Convert Spring-generated binding exceptions into the format of an application message + return new ResponseEntity<>(new ErrorResponse(ex.getMessage()), BAD_REQUEST); + } + + @Override + protected final ResponseEntity<Object> handleMethodArgumentNotValid(final MethodArgumentNotValidException exception, + final HttpHeaders headers, final HttpStatus status, final WebRequest request) { + LOG.debug(LOG_MSG, BAD_REQUEST, exception); + String errorMsg = exception.getBindingResult().getFieldErrors().stream() + .map(DefaultMessageSourceResolvable::getDefaultMessage).findFirst() + .orElse(exception.getMessage()); + return new ResponseEntity<>(new ErrorResponse(errorMsg), BAD_REQUEST); + } + + @ExceptionHandler(EntityNotFoundException.class) + public final ResponseEntity<ErrorResponse> handleNotFoundException(Exception exception) { + LOG.debug(LOG_MSG, NOT_FOUND, exception); + return new ResponseEntity<>(new ErrorResponse(exception.getMessage()), NOT_FOUND); + } + + @ExceptionHandler( + {InvalidArtifactException.class, VersionCreationException.class, VersionModificationException.class, + VersionStateModificationException.class, + VersionStateModificationMissingArtifactException.class, + VersionStatusModificationException.class, + UniqueValueViolationException.class, + WorkflowModificationException.class}) + public final ResponseEntity<ErrorResponse> handleUnprocessableEntityException(Exception exception) { + LOG.debug(LOG_MSG, UNPROCESSABLE_ENTITY, exception); + return new ResponseEntity<>(new ErrorResponse(exception.getMessage()), UNPROCESSABLE_ENTITY); + } + + @ExceptionHandler(Exception.class) + public final ResponseEntity<UnexpectedErrorResponse> handleUnexpectedException(Exception exception) { + UnexpectedErrorResponse response = UNEXPECTED_EXCEPTION_MAPPER.apply(exception); + LOG.error(response.getMessage(), exception); + return new ResponseEntity<>(response, INTERNAL_SERVER_ERROR); + } + + private static boolean isDevInfoDisabled() { + return Boolean.FALSE.toString().equalsIgnoreCase(System.getProperty("errors.includeDevInfo")); + } + + private static String getUnexpectedErrorMessage() { + return String.format(UNEXPECTED_ERROR_MSG, CODE_GENERATOR.generate(CODE_LENGTH)); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestParams.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestParams.java new file mode 100644 index 00000000..c22a0c20 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/RestParams.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +public class RestParams { + + private RestParams() { + } + + public static final String USER_ID_HEADER = "USER_ID"; + public static final String OFFSET = "offset"; + public static final String LIMIT = "limit"; + public static final String SORT = "sort"; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java new file mode 100644 index 00000000..ff06f828 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowController.java @@ -0,0 +1,138 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static org.onap.sdc.workflow.api.RestParams.LIMIT; +import static org.onap.sdc.workflow.api.RestParams.OFFSET; +import static org.onap.sdc.workflow.api.RestParams.SORT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import javax.validation.Valid; +import org.onap.sdc.workflow.api.types.Paging; +import org.onap.sdc.workflow.api.types.Sorting; +import org.onap.sdc.workflow.api.types.VersionStatesFormatter; +import org.onap.sdc.workflow.api.types.WorkflowStatusDto; +import org.onap.sdc.workflow.services.WorkflowManager; +import org.onap.sdc.workflow.services.WorkflowVersionManager; +import org.onap.sdc.workflow.services.annotations.UserId; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.PagingRequest; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.SortingRequest; +import org.onap.sdc.workflow.services.types.Workflow; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +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.RestController; +import springfox.documentation.annotations.ApiIgnore; + +@RequestMapping("/wf/workflows") +@Api("Workflows") +@RestController("workflowController") +public class WorkflowController { + + private final WorkflowManager workflowManager; + private final WorkflowVersionManager workflowVersionManager; + + @Autowired + public WorkflowController(@Qualifier("workflowManager") WorkflowManager workflowManager, + @Qualifier("workflowVersionManager") WorkflowVersionManager workflowVersionManager) { + this.workflowManager = workflowManager; + this.workflowVersionManager = workflowVersionManager; + } + + @GetMapping(produces = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("List workflows") + @ApiImplicitParams({@ApiImplicitParam(name = "versionState", dataType = "string", paramType = "query", + allowableValues = "DRAFT,CERTIFIED", value = "Filter by version state"), + @ApiImplicitParam(name = OFFSET, dataType = "string", paramType = "query", defaultValue = "0", + value = "Index of the starting item"), + @ApiImplicitParam(name = LIMIT, dataType = "string", paramType = "query", defaultValue = "200", + value = "Number of returned items"), + @ApiImplicitParam(name = SORT, dataType = "string", paramType = "query", defaultValue = "name:asc", + value = "Sorting criteria in the format: property:(asc|desc). Default sort order is ascending.", + allowableValues = "name:asc,name:desc"), + @ApiImplicitParam(name = "searchNameFilter", dataType = "string", paramType = "query", + value = "Filter by workflow name"), + @ApiImplicitParam(name = "archiving", dataType = "string", paramType = "query", + allowableValues = "ACTIVE,ARCHIVED", value = "Filter by workflow status")}) + public Page<Workflow> list(@ApiIgnore String archiving, @ApiIgnore String searchNameFilter, + @ApiIgnore VersionStatesFormatter versionStateFilter, @ApiIgnore Paging paging, + @ApiIgnore Sorting sorting, @UserId String user) { + return workflowManager.list(archiving, searchNameFilter, versionStateFilter.getVersionStates(), initRequestSpec(paging, sorting)); + } + + @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Create workflow") + public ResponseEntity<Workflow> create(@Validated @RequestBody Workflow workflow, @UserId String user) { + return new ResponseEntity<>(workflowManager.create(workflow), HttpStatus.CREATED); + } + + @GetMapping(path = "/{workflowId}") + @ApiOperation("Get workflow") + public Workflow get(@PathVariable("workflowId") String workflowId, + @ApiParam(value = "Expand workflow data", allowableValues = "versions") + @RequestParam(value = "expand", required = false) String expand, @UserId String user) { + Workflow workflow = new Workflow(); + workflow.setId(workflowId); + Workflow retrievedWorkflow = workflowManager.get(workflow); + if ("versions".equals(expand)) { + retrievedWorkflow.setVersions(workflowVersionManager.list(workflowId, null)); + } + return retrievedWorkflow; + } + + @PutMapping(path = "/{workflowId}", consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Update workflow") + public Workflow update(@RequestBody Workflow workflow, @PathVariable("workflowId") String workflowId, + @UserId String user) { + workflow.setId(workflowId); + workflowManager.update(workflow); + return workflow; + } + + @PostMapping(path = "/{workflowId}/archiving", consumes = MediaType.APPLICATION_JSON_VALUE) + @ApiOperation("Update workflow status") + public ResponseEntity updateStatus(@RequestBody @Valid WorkflowStatusDto request, @PathVariable("workflowId") String workflowId, + @UserId String user) { + workflowManager.updateStatus(workflowId, ArchivingStatus.valueOf(request.getStatus())); + return new ResponseEntity(HttpStatus.OK); + } + + private RequestSpec initRequestSpec(Paging paging, Sorting sorting) { + return new RequestSpec(new PagingRequest(paging.getOffset() == null ? DEFAULT_OFFSET : paging.getOffset(), + paging.getLimit() == null ? DEFAULT_LIMIT : paging.getLimit()), + SortingRequest.builder().sorts(sorting.getSorts()).build()); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java new file mode 100644 index 00000000..213cd713 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/WorkflowVersionController.java @@ -0,0 +1,161 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import java.util.stream.Collectors; +import javax.validation.Valid; +import org.onap.sdc.workflow.api.mappers.WorkflowVersionDtoMapper; +import org.onap.sdc.workflow.api.types.CollectionResponse; +import org.onap.sdc.workflow.api.types.VersionStateDto; +import org.onap.sdc.workflow.api.types.VersionStatesFormatter; +import org.onap.sdc.workflow.api.types.WorkflowVersionRequest; +import org.onap.sdc.workflow.api.types.WorkflowVersionResponse; +import org.onap.sdc.workflow.api.types.dto.ArtifactDeliveriesRequestDto; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; +import org.onap.sdc.workflow.services.WorkflowVersionManager; +import org.onap.sdc.workflow.services.annotations.UserId; +import org.onap.sdc.workflow.services.types.WorkflowVersion; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.core.io.InputStreamResource; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +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.RestController; +import org.springframework.web.multipart.MultipartFile; +import springfox.documentation.annotations.ApiIgnore; + +@RequestMapping("/wf/workflows/{workflowId}/versions") +@Api("Workflow versions") +@RestController("workflowsVersionController") +public class WorkflowVersionController { + + private final WorkflowVersionManager versionManager; + private final WorkflowVersionDtoMapper versionDtoMapper; + private final ArtifactAssociationService associationHandler; + + @Autowired + public WorkflowVersionController(@Qualifier("workflowVersionManager") WorkflowVersionManager versionManager, + WorkflowVersionDtoMapper versionDtoMapper, + @Qualifier("ArtifactAssociationHandler") ArtifactAssociationService artifactAssociationHandler) { + this.versionManager = versionManager; + this.versionDtoMapper = versionDtoMapper; + this.associationHandler = artifactAssociationHandler; + } + + @GetMapping + @ApiOperation("List workflow versions") + @ApiImplicitParam(name = "state", dataType = "string", paramType = "query", allowableValues = "DRAFT,CERTIFIED", + value = "Filter by state") + public CollectionResponse<WorkflowVersionResponse> list(@PathVariable("workflowId") String workflowId, + @ApiIgnore VersionStatesFormatter stateFilter, @UserId String user) { + return new CollectionResponse<>(versionManager.list(workflowId, stateFilter.getVersionStates()).stream() + .map(versionDtoMapper::workflowVersionToResponse) + .collect(Collectors.toList())); + } + + @PostMapping + @ApiOperation("Create workflow version") + public ResponseEntity<WorkflowVersionResponse> create(@RequestBody @Valid WorkflowVersionRequest request, + @PathVariable("workflowId") String workflowId, + @RequestParam(value = "baseVersionId", required = false) String baseVersionId, @UserId String user) { + WorkflowVersionResponse createdVersion = versionDtoMapper.workflowVersionToResponse( + versionManager.create(workflowId, baseVersionId, versionDtoMapper.requestToWorkflowVersion(request))); + return new ResponseEntity<>(createdVersion, HttpStatus.CREATED); + } + + @GetMapping("/{versionId}") + @ApiOperation("Get workflow version") + public WorkflowVersionResponse get(@PathVariable("workflowId") String workflowId, + @PathVariable("versionId") String versionId, @UserId String user) { + return versionDtoMapper.workflowVersionToResponse(versionManager.get(workflowId, versionId)); + } + + @PutMapping("/{versionId}") + @ApiOperation("Update workflow version") + public void update(@RequestBody @Valid WorkflowVersionRequest request, + @PathVariable("workflowId") String workflowId, @PathVariable("versionId") String versionId, + @UserId String user) { + WorkflowVersion version = versionDtoMapper.requestToWorkflowVersion(request); + version.setId(versionId); + versionManager.update(workflowId, version); + } + + @GetMapping("/{versionId}/state") + @ApiOperation("Get workflow version state") + public VersionStateDto getState(@PathVariable("workflowId") String workflowId, + @PathVariable("versionId") String versionId, @UserId String user) { + return new VersionStateDto(versionManager.getState(workflowId, versionId)); + } + + @PostMapping("/{versionId}/state") + @ApiOperation("Update workflow version state") + public VersionStateDto updateState(@RequestBody VersionStateDto state, + @PathVariable("workflowId") String workflowId, @PathVariable("versionId") String versionId, + @UserId String user) { + versionManager.updateState(workflowId, versionId, state.getName()); + return new VersionStateDto(state.getName()); + } + + @PostMapping("/{versionId}/artifact-deliveries") + @ApiOperation("upload of artifact to VF operation workflow") + public ResponseEntity<String> artifactDeliveries(@RequestBody ArtifactDeliveriesRequestDto deliveriesRequestDto, + @PathVariable("workflowId") String workflowId, @PathVariable("versionId") String versionId, + @UserId String user) { + return associationHandler + .execute(user, deliveriesRequestDto, versionManager.getArtifact(workflowId, versionId)); + } + + @PutMapping("/{versionId}/artifact") + @ApiOperation("Create/update artifact of a version") + public void uploadArtifact(@RequestBody MultipartFile fileToUpload, @PathVariable("workflowId") String workflowId, + @PathVariable("versionId") String versionId, @UserId String user) { + versionManager.uploadArtifact(workflowId, versionId, fileToUpload); + } + + @GetMapping("/{versionId}/artifact") + @ApiOperation("Download workflow version artifact") + public ResponseEntity<Resource> getArtifact(@PathVariable("workflowId") String workflowId, + @PathVariable("versionId") String versionId, @UserId String user) { + ArtifactEntity artifact = versionManager.getArtifact(workflowId, versionId); + + return ResponseEntity.ok() + .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=" + artifact.getFileName()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .body(new InputStreamResource(artifact.getArtifactData())); + } + + @DeleteMapping("/{versionId}/artifact") + @ApiOperation("Delete workflow version artifact") + public void deleteArtifact(@PathVariable("workflowId") String workflowId, + @PathVariable("versionId") String versionId, @UserId String user) { + versionManager.deleteArtifact(workflowId, versionId); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/mappers/ActivitySpecDtoMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/mappers/ActivitySpecDtoMapper.java new file mode 100644 index 00000000..cea7c878 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/mappers/ActivitySpecDtoMapper.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.mappers; + +import org.mapstruct.Mapper; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecDataResponse; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecRequest; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecResponse; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; + +@Mapper(componentModel = "spring") +public interface ActivitySpecDtoMapper { + + ActivitySpecResponse toActivitySpecResponse(ActivitySpecEntity activitySpec); + + ActivitySpecDataResponse toActivitySpecDataResponse(ActivitySpecEntity activitySpec); + + ActivitySpecEntity fromActivitySpecRequest(ActivitySpecRequest request); + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/mappers/WorkflowVersionDtoMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/mappers/WorkflowVersionDtoMapper.java new file mode 100644 index 00000000..120b0d23 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/mappers/WorkflowVersionDtoMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.mappers; + +import org.mapstruct.Mapper; +import org.onap.sdc.workflow.api.types.WorkflowVersionRequest; +import org.onap.sdc.workflow.api.types.WorkflowVersionResponse; +import org.onap.sdc.workflow.services.types.WorkflowVersion; + +@Mapper(componentModel = "spring") +public interface WorkflowVersionDtoMapper { + + WorkflowVersion requestToWorkflowVersion(WorkflowVersionRequest request); + + WorkflowVersionResponse workflowVersionToResponse(WorkflowVersion workflowVersion); + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/swagger/UserIdReader.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/swagger/UserIdReader.java new file mode 100644 index 00000000..d16c9407 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/swagger/UserIdReader.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.swagger; + +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; + +import com.fasterxml.classmate.TypeResolver; +import com.google.common.base.Optional; +import org.onap.sdc.workflow.services.annotations.UserId; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; +import springfox.documentation.service.ResolvedMethodParameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.ParameterBuilderPlugin; +import springfox.documentation.spi.service.contexts.ParameterContext; +import springfox.documentation.swagger.common.SwaggerPluginSupport; + +/** + * This component is neccesary because swagger cannot find a custom annotations in API. + * This is needed to find specifically the {@link UserId} annotation + */ +@Component +@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1000) +public class UserIdReader implements ParameterBuilderPlugin { + + private static final String HEADER = "header"; + private final TypeResolver resolver; + + public UserIdReader(TypeResolver resolver) { + this.resolver = resolver; + } + + @Override + public void apply(ParameterContext parameterContext) { + ResolvedMethodParameter methodParameter = parameterContext.resolvedMethodParameter(); + Optional<UserId> requestParam = methodParameter.findAnnotation(UserId.class); + if (requestParam.isPresent()) { + parameterContext.parameterBuilder().parameterType(HEADER).name(USER_ID_HEADER) + .type(resolver.resolve(String.class)); + } + } + + @Override + public boolean supports(DocumentationType documentationType) { + return true; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionResponse.java new file mode 100644 index 00000000..1734dd6c --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/CollectionResponse.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import java.util.Collection; +import lombok.Data; + +@Data +public class CollectionResponse<T> { + + private int total; + private Collection<T> items; + + public CollectionResponse(Collection<T> items) { + this.items = items; + this.total = items.size(); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/ErrorResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/ErrorResponse.java new file mode 100644 index 00000000..45f54341 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/ErrorResponse.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ErrorResponse { + + private String message; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Paging.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Paging.java new file mode 100644 index 00000000..7e47f6d6 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Paging.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT; + +import java.util.Optional; +import lombok.Getter; + +@Getter +public class Paging { + + private Integer offset; + private Integer limit; + + public void setOffset(String offset) { + getIntValue(offset).ifPresent(integer -> this.offset = integer); + } + + public void setLimit(String limit) { + getIntValue(limit).map(integer -> integer > MAX_LIMIT ? MAX_LIMIT : integer).ifPresent(integer -> { + if (integer != 0) { + this.limit = integer; + } + }); + } + + private static Optional<Integer> getIntValue(String value) { + try { + int intValue = Integer.parseInt(value); + return intValue < 0 ? Optional.empty() : Optional.of(intValue); + } catch (NumberFormatException e) { + return Optional.empty(); + } + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Parameter.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Parameter.java new file mode 100644 index 00000000..f5bbecec --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Parameter.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import lombok.Data; +import org.onap.sdc.workflow.persistence.types.ParameterType; + +@Data +public class Parameter { + @NotBlank(message = "Parameter Name may not be blank") + @Pattern(regexp = "[A-Za-z0-9_ ]+", message = "Parameter name must contain only letters, digits and underscores") + private String name; + @NotNull + private ParameterType type; + @NotNull + private boolean mandatory; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Sorting.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Sorting.java new file mode 100644 index 00000000..38b579b2 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/Sorting.java @@ -0,0 +1,66 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import lombok.Getter; +import org.onap.sdc.workflow.services.types.Sort; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; + +@Getter +public class Sorting { + + private static final String SORTS_DELIMITER = ","; + private static final String DIRECTION_DELIMITER = ":"; + private static final String ASC = "asc"; + private static final String DESC = "desc"; + private static final Logger LOGGER = LoggerFactory.getLogger(Sorting.class); + + private List<Sort> sorts = Collections.emptyList(); + + public void setSort(String sortString) { + this.sorts = Arrays.stream(sortString.split(SORTS_DELIMITER)) + .map(Sorting::formatSort) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + } + + private static Sort formatSort(String sort) { + String[] tokens = sort.split(DIRECTION_DELIMITER, 2); + + return tokens.length == 2 + ? formatSingleSort(tokens[0], tokens[1]) + : new Sort(tokens[0], true); + } + + private static Sort formatSingleSort(String property, String direction) { + if (ASC.equalsIgnoreCase(direction)) { + return new Sort(property, true); + } + if (DESC.equalsIgnoreCase(direction)) { + return new Sort(property, false); + } + LOGGER.warn("Sorting direction {} of property {} is invalid. Allowed direction values: asc, desc.", direction, + property); + return null; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/UnexpectedErrorResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/UnexpectedErrorResponse.java new file mode 100644 index 00000000..8cf513a2 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/UnexpectedErrorResponse.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import lombok.Getter; + +@Getter +public class UnexpectedErrorResponse extends ErrorResponse { + + private String devInfo; + + public UnexpectedErrorResponse(String message) { + super(message); + } + + public UnexpectedErrorResponse(String message, String devInfo) { + super(message); + this.devInfo = devInfo; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionStateDto.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionStateDto.java new file mode 100644 index 00000000..8e6dd09f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionStateDto.java @@ -0,0 +1,35 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import java.util.List; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +@Data +@NoArgsConstructor +public class VersionStateDto { + + private WorkflowVersionState name; + private List<WorkflowVersionState> nextStates; + + public VersionStateDto(WorkflowVersionState state) { + name = state; + nextStates = state.getNextStates(); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionStatesFormatter.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionStatesFormatter.java new file mode 100644 index 00000000..cc17f928 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/VersionStatesFormatter.java @@ -0,0 +1,53 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import java.util.Arrays; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.Getter; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; + +@Getter +public class VersionStatesFormatter { + + private static final Logger LOGGER = LoggerFactory.getLogger(VersionStatesFormatter.class); + + private Set<WorkflowVersionState> versionStates = null; + + public void setVersionState(String value) { + this.versionStates = formatString(value); + } + + public void setState(String value) { + setVersionState(value); + } + + private static Set<WorkflowVersionState> formatString(String value) { + try { + return value == null ? null : Arrays.stream(value.split(",")).map(WorkflowVersionState::valueOf) + .collect(Collectors.toSet()); + } catch (IllegalArgumentException ex) { + LOGGER.warn("value {} is invalid and cannot be formatted to a set of version states, " + + "therefore it set to empty set", value, ex); + return Collections.emptySet(); + } + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowStatusDto.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowStatusDto.java new file mode 100644 index 00000000..6e5ab1cf --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowStatusDto.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import lombok.Data; +import org.onap.sdc.workflow.api.validation.ValidStatus; + +@Data +public class WorkflowStatusDto { + @ValidStatus(message = "Invalid status. Allowable values are: ARCHIVED,ACTIVE.") + private String status; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowVersionRequest.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowVersionRequest.java new file mode 100644 index 00000000..090f129a --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowVersionRequest.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import java.util.Collection; +import java.util.Collections; +import javax.validation.Valid; +import lombok.Data; +import org.onap.sdc.workflow.api.validation.NoDuplicates; + +@Data +public class WorkflowVersionRequest { + + private String name; + private String description; + @Valid + @NoDuplicates(message = "Inputs names must be unique") + private Collection<Parameter> inputs = Collections.emptyList(); + @Valid + @NoDuplicates(message = "Outputs names must be unique") + private Collection<Parameter> outputs = Collections.emptyList(); +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowVersionResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowVersionResponse.java new file mode 100644 index 00000000..460d3d63 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/WorkflowVersionResponse.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import java.util.Date; +import lombok.Data; +import lombok.EqualsAndHashCode; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +@EqualsAndHashCode(callSuper = true) +@Data +public class WorkflowVersionResponse extends WorkflowVersionRequest { + + private String id; + private String baseId; + private WorkflowVersionState state; + private boolean hasArtifact; + private Date creationTime; + private Date modificationTime; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecAction.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecAction.java new file mode 100644 index 00000000..87a97fff --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecAction.java @@ -0,0 +1,21 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +public enum ActivitySpecAction { + CERTIFY, DEPRECATE, DELETE +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecActionRequest.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecActionRequest.java new file mode 100644 index 00000000..8b469da4 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecActionRequest.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +import javax.validation.constraints.NotNull; + +@lombok.Data +public class ActivitySpecActionRequest { + + @NotNull + private ActivitySpecAction action; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecBase.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecBase.java new file mode 100644 index 00000000..cf494c20 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecBase.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +import java.util.List; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import lombok.Data; + +@Data +abstract class ActivitySpecBase { + + @NotBlank(message = "Mandatory name field is missing") + @Pattern(regexp = "^[a-zA-Z0-9-]*$", message = "name should match with \"^[a-zA-Z0-9-]*$\" pattern") + private String name; + private List<String> categoryList; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecCreateResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecCreateResponse.java new file mode 100644 index 00000000..895c74e8 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecCreateResponse.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class ActivitySpecCreateResponse { + + private String id; + private String versionId; +} + diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecDataResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecDataResponse.java new file mode 100644 index 00000000..d4b1003f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecDataResponse.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +import lombok.EqualsAndHashCode; + +@lombok.Data +@EqualsAndHashCode(callSuper = true) +public class ActivitySpecDataResponse extends ActivitySpecRequest { + + private String id; + private String status; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecRequest.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecRequest.java new file mode 100644 index 00000000..972e99cc --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecRequest.java @@ -0,0 +1,37 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +import io.swagger.annotations.ApiModel; +import java.util.List; +import javax.validation.Valid; +import lombok.EqualsAndHashCode; +import org.onap.sdc.workflow.persistence.types.ActivitySpecParameter; + +@ApiModel(value = "ActivitySpecRequest") +@lombok.Data +@EqualsAndHashCode(callSuper = true) +public class ActivitySpecRequest extends ActivitySpecBase { + + private String description; + @Valid + private List<ActivitySpecParameter> inputs; + @Valid + private List<ActivitySpecParameter> outputs; + private String type; + private String content; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecResponse.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecResponse.java new file mode 100644 index 00000000..a061b3fd --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/activityspec/ActivitySpecResponse.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.activityspec; + +import lombok.EqualsAndHashCode; + +@lombok.Data +@EqualsAndHashCode(callSuper = true) +public class ActivitySpecResponse extends ActivitySpecBase { + + private String id; + private String status; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/dto/ArtifactDeliveriesRequestDto.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/dto/ArtifactDeliveriesRequestDto.java new file mode 100644 index 00000000..5ec54ffb --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/types/dto/ArtifactDeliveriesRequestDto.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * This class is a simple data object for the Artifact-Deliveries API. + * It will be used to build a HTTP request to be sent to SDC external API. + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ArtifactDeliveriesRequestDto { + + /** + * The HTTP method (PUT, POST etc) that will be executed. + */ + private String method; + + /** + * The server to which the request will be sent. Correct format is <IP>:<PORT>. + */ + private String endpoint; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ActivitySpecParameterNameValidator.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ActivitySpecParameterNameValidator.java new file mode 100644 index 00000000..06818c9d --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ActivitySpecParameterNameValidator.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import org.onap.sdc.workflow.persistence.types.ActivitySpecParameter; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component("ActivitySpecParameterNameValidator") +public class ActivitySpecParameterNameValidator implements ConstraintValidator<ValidName, ActivitySpecParameter> { + + private String validationRegex; + private static final String defaultValidationRegex = "^\\S*$"; + private String validationMessage; + private static final String defaultValidationMessage = "Input and Output names must not contain any spaces"; + + @Override + public boolean isValid(ActivitySpecParameter parameter, ConstraintValidatorContext context) { + Pattern pattern = Pattern.compile(validationRegex); + Matcher matcher = pattern.matcher(parameter.getName()); + boolean isValid = matcher.find(); + if (!isValid) { + context.disableDefaultConstraintViolation(); + context.buildConstraintViolationWithTemplate(validationMessage).addConstraintViolation(); + } + return isValid; + } + + @Value("${activitySpec.parameterName.validation:" + defaultValidationRegex + "}") + void setValidationRegex(String regex) { + if (Objects.isNull(regex) || regex.equals("")) { + Objects.requireNonNull(regex); + } else { + validationRegex = regex; + } + } + + @Value("${activitySpec.parameterName.validationMessage:" + defaultValidationMessage + "}") + void setValidationMessage(String message) { + if (Objects.isNull(message) || message.equals("")) { + Objects.requireNonNull(message); + } else { + validationMessage = message; + } + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ArchivingStatusValidator.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ArchivingStatusValidator.java new file mode 100644 index 00000000..bfbf7580 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ArchivingStatusValidator.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import org.onap.sdc.workflow.services.types.ArchivingStatus; + +public class ArchivingStatusValidator implements ConstraintValidator<ValidStatus, String> { + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (value == null) { + return false; + } else { + try { + Enum.valueOf(ArchivingStatus.class, value); + return true; + } catch (IllegalArgumentException var3) { + return false; + } + } + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/NoDuplicates.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/NoDuplicates.java new file mode 100644 index 00000000..296e4387 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/NoDuplicates.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.validation.Constraint; +import javax.validation.Payload; + +@Target({ElementType.TYPE, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = {NoDuplicatesValidator.class}) +public @interface NoDuplicates { + + String message(); + + Class<?>[] groups() default {}; + + Class<? extends Payload>[] payload() default {}; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/NoDuplicatesValidator.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/NoDuplicatesValidator.java new file mode 100644 index 00000000..7ade1ab0 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/NoDuplicatesValidator.java @@ -0,0 +1,37 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; +import javax.validation.ConstraintValidator; +import javax.validation.ConstraintValidatorContext; +import org.onap.sdc.workflow.api.types.Parameter; + +public class NoDuplicatesValidator implements ConstraintValidator<NoDuplicates, Collection<Parameter>> { + + @Override + public boolean isValid(Collection<Parameter> parameters, ConstraintValidatorContext context) { + if (Objects.isNull(parameters) || parameters.size() < 2) { + return true; + } + Set<String> testSet = new HashSet<>(); + return parameters.stream().allMatch(parameter -> testSet.add(parameter.getName())); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidName.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidName.java new file mode 100644 index 00000000..2d90aeba --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidName.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.validation.Constraint; +import javax.validation.Payload; + +@Target({ElementType.TYPE, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = {ActivitySpecParameterNameValidator.class}) +public @interface ValidName { + + String message() default ""; + + Class<?>[] groups() default {}; + + Class<? extends Payload>[] payload() default {}; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidStatus.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidStatus.java new file mode 100644 index 00000000..15778b1d --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/validation/ValidStatus.java @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import javax.validation.Constraint; +import javax.validation.Payload; + +@Target({ElementType.TYPE, ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Constraint(validatedBy = {ArchivingStatusValidator.class}) +public @interface ValidStatus { + + String message(); + + Class<?>[] groups() default {}; + + Class<? extends Payload>[] payload() default {}; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ActivitySpecRepository.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ActivitySpecRepository.java new file mode 100644 index 00000000..f8f1d9a9 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ActivitySpecRepository.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence; + +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; + +public interface ActivitySpecRepository { + + void create(ActivitySpecEntity activitySpec); + + ActivitySpecEntity get(ActivitySpecEntity activitySpec); + + void update(ActivitySpecEntity activitySpec); +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ArtifactRepository.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ArtifactRepository.java new file mode 100644 index 00000000..e10279fe --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ArtifactRepository.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence; + + +import java.util.Optional; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; + + +public interface ArtifactRepository { + + void update(String workflowId, String versionId,ArtifactEntity artifactEntity); + + Optional<ArtifactEntity> get(String workflowId, String versionId); + + boolean isExist(String workflowId, String versionId); + + void createStructure(String workflowId, String versionId); + + void delete(String workflowId, String versionId); + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ParameterRepository.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ParameterRepository.java new file mode 100644 index 00000000..9f7fb1ad --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/ParameterRepository.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence; + +import java.util.Collection; +import org.onap.sdc.workflow.persistence.types.ParameterEntity; +import org.onap.sdc.workflow.persistence.types.ParameterRole; + + +public interface ParameterRepository { + + void createStructure(String id, String versionId); + + Collection<ParameterEntity> list(String id, String versionId, ParameterRole role); + + void deleteAll(String id, String versionId, ParameterRole role); + + ParameterEntity get(String id, String versionId, String parameterId); + + void delete(String id, String versionId, String parameterId); + + ParameterEntity create(String id, String versionId , ParameterRole role, ParameterEntity parameter); + + void update(String id, String versionId, ParameterRole role, ParameterEntity parameter); +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java new file mode 100644 index 00000000..cf7b0633 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/UniqueValueRepository.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ActivitySpecRepositoryImpl.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ActivitySpecRepositoryImpl.java new file mode 100644 index 00000000..b304f900 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ActivitySpecRepositoryImpl.java @@ -0,0 +1,141 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl; + +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.buildStructuralElement; + +import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement; +import com.amdocs.zusammen.datatypes.item.Action; +import com.amdocs.zusammen.datatypes.item.ElementContext; +import com.amdocs.zusammen.datatypes.item.Info; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Objects; +import java.util.Optional; +import org.onap.sdc.common.versioning.persistence.zusammen.ZusammenSessionContextCreator; +import org.onap.sdc.common.zusammen.services.ZusammenAdaptor; +import org.onap.sdc.workflow.persistence.ActivitySpecRepository; +import org.onap.sdc.workflow.persistence.impl.types.ActivitySpecData; +import org.onap.sdc.workflow.persistence.impl.types.ActivitySpecElementType; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; +import org.onap.sdc.workflow.services.ActivitySpecConstant; +import org.onap.sdc.workflow.services.utilities.JsonUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class ActivitySpecRepositoryImpl implements ActivitySpecRepository { + + private final ZusammenAdaptor zusammenAdaptor; + private final ZusammenSessionContextCreator contextCreator; + + @Autowired + public ActivitySpecRepositoryImpl(ZusammenAdaptor zusammenAdaptor, ZusammenSessionContextCreator contextCreator) { + this.zusammenAdaptor = zusammenAdaptor; + this.contextCreator = contextCreator; + } + + @Override + public void create(ActivitySpecEntity activitySpec) { + ZusammenElement generalElement = mapActivityDetailsToZusammenElement(activitySpec, Action.CREATE); + + ElementContext elementContext = new ElementContext(activitySpec.getId(), activitySpec.getVersionId()); + zusammenAdaptor + .saveElement(contextCreator.create(), elementContext, generalElement, "Create Activity Spec General Info Element"); + } + + @Override + public ActivitySpecEntity get(ActivitySpecEntity entity) { + ElementContext elementContext = new ElementContext(entity.getId(), entity.getVersionId()); + Optional<Element> element = + zusammenAdaptor.getElementByName(contextCreator.create(), elementContext, null, ActivitySpecElementType.ACTIVITYSPEC.name()); + return element.map(this::mapZusammenElementToActivityDetails).orElse(null); + } + + @Override + public void update(ActivitySpecEntity entity) { + + ZusammenElement generalElement = mapActivityDetailsToZusammenElement(entity, Action.UPDATE); + + ElementContext elementContext = new ElementContext(entity.getId(), entity.getVersionId()); + zusammenAdaptor + .saveElement(contextCreator.create(), elementContext, generalElement, "Update Activity Spec General Info Element"); + } + + private ZusammenElement mapActivityDetailsToZusammenElement(ActivitySpecEntity entity, Action action) { + ZusammenElement generalElement = buildStructuralElement(ActivitySpecElementType.ACTIVITYSPEC.name(), action); + + enrichElementInfoFromEntity(generalElement, entity); + enrichElementDataFromEntity(generalElement, entity); + return generalElement; + } + + private void enrichElementInfoFromEntity(ZusammenElement element, ActivitySpecEntity entity) { + element.getInfo().addProperty(InfoPropertyName.DESCRIPTION.getValue(), entity.getDescription()); + element.getInfo().addProperty(InfoPropertyName.NAME.getValue(), entity.getName()); + element.getInfo().addProperty(InfoPropertyName.CATEGORY.getValue(), entity.getCategoryList()); + } + + private void enrichElementDataFromEntity(ZusammenElement element, ActivitySpecEntity entity) { + ActivitySpecData activitySpecData = new ActivitySpecData(); + activitySpecData.setInputs(entity.getInputs()); + activitySpecData.setOutputs(entity.getOutputs()); + activitySpecData.setType(entity.getType()); + activitySpecData.setContent(entity.getContent()); + element.setData(new ByteArrayInputStream(JsonUtil.object2Json(activitySpecData).getBytes())); + } + + private ActivitySpecEntity mapZusammenElementToActivityDetails(Element element) { + ActivitySpecEntity entity = new ActivitySpecEntity(); + entity.setId(element.getElementId().getValue()); + enrichEntityFromElementData(entity, element.getData()); + enrichEntityFromElementInfo(entity, element.getInfo()); + return entity; + } + + private void enrichEntityFromElementData(ActivitySpecEntity entity, InputStream data) { + ActivitySpecData activitySpecData = JsonUtil.json2Object(data, ActivitySpecData.class); + if (Objects.nonNull(activitySpecData)) { + entity.setInputs(activitySpecData.getInputs()); + entity.setOutputs(activitySpecData.getOutputs()); + entity.setType(activitySpecData.getType()); + entity.setContent(activitySpecData.getContent()); + } + } + + private void enrichEntityFromElementInfo(ActivitySpecEntity entity, Info info) { + entity.setName(info.getProperty(InfoPropertyName.NAME.getValue())); + entity.setDescription(info.getProperty(InfoPropertyName.DESCRIPTION.getValue())); + entity.setCategoryList(info.getProperty(InfoPropertyName.CATEGORY.getValue())); + } + + public enum InfoPropertyName { + DESCRIPTION("description"), NAME("name"), CATEGORY(ActivitySpecConstant.CATEGORY_ATTRIBUTE_NAME); + + private final String value; + + InfoPropertyName(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ArtifactRepositoryImpl.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ArtifactRepositoryImpl.java new file mode 100644 index 00000000..4ad54614 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ArtifactRepositoryImpl.java @@ -0,0 +1,136 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl; + +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.buildStructuralElement; + +import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement; +import com.amdocs.zusammen.datatypes.item.Action; +import com.amdocs.zusammen.datatypes.item.ElementContext; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Optional; +import org.apache.commons.io.IOUtils; +import org.onap.sdc.common.versioning.persistence.zusammen.ZusammenSessionContextCreator; +import org.onap.sdc.common.zusammen.services.ZusammenAdaptor; +import org.onap.sdc.workflow.persistence.ArtifactRepository; +import org.onap.sdc.workflow.persistence.impl.types.WorkflowElementType; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class ArtifactRepositoryImpl implements ArtifactRepository { + + private static final String FILE_NAME_PROPERTY = "fileName"; + private static final String EMPTY_DATA = "{}"; + + private final ZusammenAdaptor zusammenAdaptor; + private final ZusammenSessionContextCreator contextCreator; + + @Autowired + public ArtifactRepositoryImpl(ZusammenAdaptor zusammenAdaptor, ZusammenSessionContextCreator contextCreator) { + this.zusammenAdaptor = zusammenAdaptor; + this.contextCreator = contextCreator; + } + + @Override + public void update(String workflowId, String versionId, ArtifactEntity artifactEntity) { + + ZusammenElement artifactElement = buildStructuralElement(WorkflowElementType.ARTIFACT.name(), Action.UPDATE); + artifactElement.setData(artifactEntity.getArtifactData()); + artifactElement.getInfo().addProperty(FILE_NAME_PROPERTY, artifactEntity.getFileName()); + + + ElementContext elementContext = new ElementContext(workflowId, versionId); + + zusammenAdaptor + .saveElement(contextCreator.create(), elementContext, artifactElement, "Update WorkflowVersion Artifact Element"); + } + + @Override + public Optional<ArtifactEntity> get(String workflowId, String versionId) { + + ElementContext elementContext = new ElementContext(workflowId, versionId); + + Optional<Element> elementOptional = + zusammenAdaptor.getElementByName(contextCreator.create(), elementContext, null, WorkflowElementType.ARTIFACT.name()); + + if (!elementOptional.isPresent() || hasEmptyData(elementOptional.get().getData())) { + return Optional.empty(); + } + + Element artifactElement = elementOptional.get(); + + ArtifactEntity artifact = new ArtifactEntity(artifactElement.getInfo().getProperty(FILE_NAME_PROPERTY), + artifactElement.getData()); + + return Optional.of(artifact); + } + + @Override + public boolean isExist(String workflowId, String versionId) { + + ElementContext elementContext = new ElementContext(workflowId, versionId); + + Optional<ElementInfo> optionalElementInfo = zusammenAdaptor.getElementInfoByName(contextCreator.create(), elementContext, null, + WorkflowElementType.ARTIFACT.name()); + return optionalElementInfo.isPresent() && optionalElementInfo.get().getInfo().getProperties() + .containsKey(FILE_NAME_PROPERTY); + } + + @Override + public void createStructure(String workflowId, String versionId) { + + ElementContext elementContext = new ElementContext(workflowId, versionId); + + ZusammenElement artifactElement = buildStructuralElement(WorkflowElementType.ARTIFACT.name(), Action.CREATE); + artifactElement.setData(new ByteArrayInputStream(EMPTY_DATA.getBytes())); + + zusammenAdaptor + .saveElement(contextCreator.create(), elementContext, artifactElement, "Create WorkflowVersion Artifact Element"); + + } + + @Override + public void delete(String workflowId, String versionId) { + + ElementContext elementContext = new ElementContext(workflowId, versionId); + + ZusammenElement artifactElement = buildStructuralElement(WorkflowElementType.ARTIFACT.name(), Action.UPDATE); + artifactElement.setData(new ByteArrayInputStream(EMPTY_DATA.getBytes())); + artifactElement.getInfo().getProperties().remove(FILE_NAME_PROPERTY); + + zusammenAdaptor.saveElement(contextCreator.create(), elementContext, artifactElement, "Delete WorkflowVersion Artifact Data"); + + } + + private boolean hasEmptyData(InputStream elementData) { + + byte[] byteElementData; + try { + byteElementData = IOUtils.toByteArray(elementData); + } catch (IOException ex) { + return false; + } + return Arrays.equals(EMPTY_DATA.getBytes(), byteElementData); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java new file mode 100644 index 00000000..eeef2477 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryImpl.java @@ -0,0 +1,171 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl; + +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.ELEMENT_TYPE_PROPERTY; +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.buildElement; +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.buildStructuralElement; + +import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement; +import com.amdocs.zusammen.datatypes.Id; +import com.amdocs.zusammen.datatypes.item.Action; +import com.amdocs.zusammen.datatypes.item.ElementContext; +import com.amdocs.zusammen.datatypes.item.Info; +import java.util.Collection; +import java.util.Optional; +import java.util.stream.Collectors; +import org.onap.sdc.common.versioning.persistence.zusammen.ZusammenSessionContextCreator; +import org.onap.sdc.common.zusammen.services.ZusammenAdaptor; +import org.onap.sdc.workflow.persistence.ParameterRepository; +import org.onap.sdc.workflow.persistence.impl.types.ParameterPropertyName; +import org.onap.sdc.workflow.persistence.impl.types.WorkflowElementType; +import org.onap.sdc.workflow.persistence.types.ParameterEntity; +import org.onap.sdc.workflow.persistence.types.ParameterRole; +import org.onap.sdc.workflow.persistence.types.ParameterType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Repository; + +@Repository +public class ParameterRepositoryImpl implements ParameterRepository { + + private final ZusammenAdaptor zusammenAdaptor; + private final ZusammenSessionContextCreator contextCreator; + + @Autowired + public ParameterRepositoryImpl(ZusammenAdaptor zusammenAdaptor, ZusammenSessionContextCreator contextCreator) { + this.zusammenAdaptor = zusammenAdaptor; + this.contextCreator = contextCreator; + } + + @Override + public void createStructure(String id, String versionId) { + ElementContext elementContext = new ElementContext(id, versionId); + + ZusammenElement inputsElement = buildStructuralElement(WorkflowElementType.INPUTS.name(), Action.CREATE); + ZusammenElement outputsElement = buildStructuralElement(WorkflowElementType.OUTPUTS.name(), Action.CREATE); + + zusammenAdaptor.saveElement(contextCreator.create(), elementContext, inputsElement, "Create WorkflowVersion INPUTS Element"); + zusammenAdaptor.saveElement(contextCreator.create(), elementContext, outputsElement, "Create WorkflowVersion OUTPUTS Element"); + } + + @Override + public Collection<ParameterEntity> list(String id, String versionId, ParameterRole role) { + ElementContext elementContext = new ElementContext(id, versionId); + + return zusammenAdaptor.listElementsByName(contextCreator.create(), elementContext, null, getParentElementType(role)).stream() + .map(this::mapElementInfoToParameter).collect(Collectors.toList()); + } + + @Override + public void deleteAll(String id, String versionId, ParameterRole role) { + ElementContext elementContext = new ElementContext(id, versionId); + + Optional<ElementInfo> optionalParentElement = + zusammenAdaptor.getElementInfoByName(contextCreator.create(), elementContext, null, getParentElementType(role)); + + if (!optionalParentElement.isPresent()) { + throw new IllegalStateException( + String.format("Missing data for workflow id %s version id %s", id, versionId)); + } + ZusammenElement parentElement = buildElement(optionalParentElement.get().getId(), Action.IGNORE); + parentElement.setSubElements(optionalParentElement.get().getSubElements().stream() + .map(parameter -> buildElement(parameter.getId(), Action.DELETE)) + .collect(Collectors.toList())); + + zusammenAdaptor.saveElement(contextCreator.create(), elementContext, parentElement, "Delete all " + role); + } + + @Override + public ParameterEntity get(String id, String versionId, String parameterId) { + ElementContext elementContext = new ElementContext(id, versionId); + + Optional<ElementInfo> element = zusammenAdaptor.getElementInfo(contextCreator.create(), elementContext, new Id(parameterId)); + + return element.map(this::mapElementInfoToParameter).orElse(null); + } + + @Override + public void delete(String id, String versionId, String parameterId) { + ElementContext elementContext = new ElementContext(id, versionId); + + ZusammenElement parameterElement = buildElement(new Id(parameterId), Action.DELETE); + + zusammenAdaptor.saveElement(contextCreator.create(), elementContext, parameterElement, + String.format("Delete Parameter with id %s", parameterId)); + } + + @Override + public ParameterEntity create(String id, String versionId, ParameterRole role, ParameterEntity parameter) { + ZusammenElement parameterElement = parameterToZusammenElement(parameter, role, Action.CREATE); + ZusammenElement parentElement = buildStructuralElement(getParentElementType(role), Action.IGNORE); + parentElement.addSubElement(parameterElement); + + ElementContext elementContext = new ElementContext(id, versionId); + + Element savedElement = zusammenAdaptor.saveElement(contextCreator.create(), elementContext, parentElement, + "Create WorkflowVersion Parameter Element"); + + parameter.setId(savedElement.getSubElements().iterator().next().getElementId().getValue()); + return parameter; + } + + @Override + public void update(String id, String versionId, ParameterRole role, ParameterEntity parameter) { + ElementContext elementContext = new ElementContext(id, versionId); + + ZusammenElement parameterElement = parameterToZusammenElement(parameter, role, Action.UPDATE); + + zusammenAdaptor.saveElement(contextCreator.create(), elementContext, parameterElement, "Update WorkflowVersion Parameter"); + } + + private ZusammenElement parameterToZusammenElement(ParameterEntity parameter, ParameterRole role, Action action) { + ZusammenElement parameterElement = + buildElement(parameter.getId() == null ? null : new Id(parameter.getId()), action); + Info info = new Info(); + info.setName(parameter.getName()); + info.addProperty(ELEMENT_TYPE_PROPERTY, WorkflowElementType.valueOf(role.name())); + info.addProperty(ParameterPropertyName.TYPE.name(), parameter.getType()); + info.addProperty(ParameterPropertyName.MANDATORY.name(), parameter.isMandatory()); + parameterElement.setInfo(info); + + return parameterElement; + } + + private ParameterEntity mapElementInfoToParameter(ElementInfo elementInfo) { + ParameterEntity parameterEntity = new ParameterEntity(); + parameterEntity.setId(elementInfo.getId().getValue()); + parameterEntity.setName(elementInfo.getInfo().getName()); + parameterEntity + .setType(ParameterType.valueOf(elementInfo.getInfo().getProperty(ParameterPropertyName.TYPE.name()))); + parameterEntity.setMandatory(elementInfo.getInfo().getProperty(ParameterPropertyName.MANDATORY.name())); + return parameterEntity; + } + + private static String getParentElementType(ParameterRole role) { + switch (role) { + case INPUT: + return WorkflowElementType.INPUTS.name(); + case OUTPUT: + return WorkflowElementType.OUTPUTS.name(); + default: + throw new IllegalArgumentException("Wrong Element Type"); + } + } + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ActivitySpecData.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ActivitySpecData.java new file mode 100644 index 00000000..5daba8d6 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ActivitySpecData.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl.types; + +import java.util.Collections; +import java.util.List; +import org.onap.sdc.workflow.persistence.types.ActivitySpecParameter; + +@lombok.Data +public class ActivitySpecData { + + private List<ActivitySpecParameter> inputs = Collections.emptyList(); + private List<ActivitySpecParameter> outputs = Collections.emptyList(); + private String type; + private String content; +} + diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ActivitySpecElementType.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ActivitySpecElementType.java new file mode 100644 index 00000000..e26b8088 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ActivitySpecElementType.java @@ -0,0 +1,21 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl.types; + +public enum ActivitySpecElementType { + ACTIVITYSPEC +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ParameterPropertyName.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ParameterPropertyName.java new file mode 100644 index 00000000..300ddc49 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/ParameterPropertyName.java @@ -0,0 +1,21 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl.types; + +public enum ParameterPropertyName { + TYPE, MANDATORY +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/WorkflowElementType.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/WorkflowElementType.java new file mode 100644 index 00000000..109ce97c --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/impl/types/WorkflowElementType.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl.types; + +public enum WorkflowElementType { + + ARTIFACT, + INPUTS, + OUTPUTS, + INPUT, + OUTPUT +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ActivitySpecEntity.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ActivitySpecEntity.java new file mode 100644 index 00000000..cf3be394 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ActivitySpecEntity.java @@ -0,0 +1,44 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +import java.util.List; +import lombok.NoArgsConstructor; + +@lombok.Data +@NoArgsConstructor +public class ActivitySpecEntity { + + private String id; + private String versionId; + private String name; + private String description; + + private List<String> categoryList; + private List<ActivitySpecParameter> inputs; + private List<ActivitySpecParameter> outputs; + private String type; + private String content; + + //Not to be maintained in activityspec element + private String status; + + public ActivitySpecEntity(String id, String versionId) { + this.id = id; + this.versionId = versionId; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ActivitySpecParameter.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ActivitySpecParameter.java new file mode 100644 index 00000000..ec1c2681 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ActivitySpecParameter.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.sdc.workflow.api.validation.ValidName; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@ValidName +public class ActivitySpecParameter { + + private String name; + private String type; + private String value; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ArtifactEntity.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ArtifactEntity.java new file mode 100644 index 00000000..62819754 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ArtifactEntity.java @@ -0,0 +1,29 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +import java.io.InputStream; +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class ArtifactEntity { + + private String fileName; + private InputStream artifactData; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterEntity.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterEntity.java new file mode 100644 index 00000000..4dfd1e4f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterEntity.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class ParameterEntity { + + private String id; + private String name; + private ParameterType type; + private boolean mandatory; + + public ParameterEntity(String name) { + this.name = name; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterRole.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterRole.java new file mode 100644 index 00000000..9f5aacfe --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterRole.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +public enum ParameterRole { + + INPUT, + OUTPUT + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterType.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterType.java new file mode 100644 index 00000000..04d09c01 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/ParameterType.java @@ -0,0 +1,25 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +public enum ParameterType { + STRING, + INTEGER, + FLOAT, + BOOLEAN, + TIMESTAMP +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java new file mode 100644 index 00000000..faf515b7 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/persistence/types/UniqueValueEntity.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.types; + +import static org.springframework.data.cassandra.core.cql.PrimaryKeyType.PARTITIONED; + +import lombok.AllArgsConstructor; +import lombok.Data; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; +import org.springframework.data.cassandra.core.mapping.Table; + +@Table("unique_value") +@Data +@AllArgsConstructor +public class UniqueValueEntity { + + @PrimaryKeyColumn(ordinal = 0, type = PARTITIONED) + private String type; + + @PrimaryKeyColumn(ordinal = 1, type = PARTITIONED) + private String value; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ApplicationConfigurer.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ApplicationConfigurer.java new file mode 100644 index 00000000..a5cce460 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/ApplicationConfigurer.java @@ -0,0 +1,50 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + * Modifications copyright (c) 2019 Nokia + * ================================================================================ + */ + +package org.onap.sdc.workflow.server.config; + +import java.util.List; +import org.onap.sdc.workflow.server.resolvers.UserIdResolver; +import org.openecomp.sdc.logging.servlet.spring.LoggingInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class ApplicationConfigurer implements WebMvcConfigurer { + + private final LoggingInterceptor loggingInterceptor; + + @Autowired + public ApplicationConfigurer(LoggingInterceptor loggingInterceptor) { + this.loggingInterceptor = loggingInterceptor; + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(loggingInterceptor); + } + + @Override + public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { + argumentResolvers.add(new UserIdResolver()); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/LoggingInterceptorConfig.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/LoggingInterceptorConfig.java new file mode 100644 index 00000000..53dbda59 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/LoggingInterceptorConfig.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.server.config; + +import org.openecomp.sdc.logging.servlet.HttpHeader; +import org.openecomp.sdc.logging.servlet.spring.LoggingInterceptor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class LoggingInterceptorConfig { + + @Value("${onap.logging.requestIdHeader}") + private String[] loggingRequestIdHeaders; + + @Value("${onap.logging.partnerNameHeader}") + private String[] loggingPartnerNameHeader; + + @Bean + public LoggingInterceptor createLoggingInterceptor() { + return new LoggingInterceptor(new HttpHeader(loggingRequestIdHeaders), + new HttpHeader(loggingPartnerNameHeader)); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java new file mode 100644 index 00000000..a2eca63a --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/SwaggerConfig.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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("/(wf/workflows|v1.0/activity-spec).*")) + .build(); + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/WebServerConfig.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/WebServerConfig.java new file mode 100644 index 00000000..e760ecd1 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/WebServerConfig.java @@ -0,0 +1,44 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.server.config; + +import org.eclipse.jetty.server.ServerConnector; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.embedded.jetty.JettyServerCustomizer; +import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class WebServerConfig implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> { + + @Value("${http.port}") + private int httpPort; + + @Override + public void customize(ConfigurableServletWebServerFactory container) { + if (container instanceof JettyServletWebServerFactory) { + JettyServletWebServerFactory containerFactory = (JettyServletWebServerFactory) container; + containerFactory.addServerCustomizers((JettyServerCustomizer) server -> { + ServerConnector connector = new ServerConnector(server); + connector.setPort(httpPort); + server.addConnector(connector); + }); + } + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/WorkflowZusammenConfigProvider.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/WorkflowZusammenConfigProvider.java new file mode 100644 index 00000000..dbd2d6de --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/config/WorkflowZusammenConfigProvider.java @@ -0,0 +1,48 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.server.config; + +import lombok.Getter; +import org.onap.sdc.common.zusammen.config.ZusammenConfigProvider; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Getter +public class WorkflowZusammenConfigProvider implements ZusammenConfigProvider { + + @Value("${spring.data.cassandra.keyspace-name}") + private String tenant; + @Value("${spring.data.cassandra.contact-points}") + private String cassandraAddresses; + @Value("${spring.data.cassandra.port}") + private String cassandraPort; + + @Value("${spring.data.cassandra.username}") + private String cassandraUser; + @Value("${spring.data.cassandra.password}") + private String cassandraPassword; + @Value("${zusammen.cassandra.isAuthenticate}") + private String cassandraAuth; + @Value("${spring.data.cassandra.ssl}") + + private String cassandraSSL; + @Value("${zusammen.cassandra.trustStorePath}") + private String cassandraTrustStorePath; + @Value("${zusammen.cassandra.trustStorePassword}") + private String cassandraTrustStorePassword; +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java new file mode 100644 index 00000000..57cda856 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/filters/SessionContextFilter.java @@ -0,0 +1,73 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.server.filters; + +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.common.session.SessionContextProvider; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +public class SessionContextFilter implements Filter { + + private final SessionContextProvider sessionContextProvider; + @Value("${spring.data.cassandra.keyspace-name}") + private String tenant; + + @Autowired + public SessionContextFilter(SessionContextProvider sessionContextProvider) { + this.sessionContextProvider = sessionContextProvider; + } + + @Override + public void init(FilterConfig filterConfig) { + // not implemented + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + try { + if (servletRequest instanceof HttpServletRequest) { + sessionContextProvider.create(getUser(servletRequest), tenant); + } + + filterChain.doFilter(servletRequest, servletResponse); + } finally { + sessionContextProvider.close(); + } + } + + @Override + public void destroy() { + // not implemented + } + + private String getUser(ServletRequest servletRequest) { + return "GLOBAL_USER"; + // TODO: 7/11/2018 get user from header when collaboration will be supported + //((HttpServletRequest) servletRequest).getHeader(USER_ID_HEADER_PARAM); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/resolvers/UserIdResolver.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/resolvers/UserIdResolver.java new file mode 100644 index 00000000..80cb07a8 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/server/resolvers/UserIdResolver.java @@ -0,0 +1,71 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.server.resolvers; + +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; + +import java.util.Objects; +import javax.servlet.http.HttpServletRequest; +import org.onap.sdc.workflow.services.annotations.UserId; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.ServletRequestBindingException; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +/** + * Resolves a user ID from an HTTP header and injects it into a parameter of type {@link String} annotated with {@link + * UserId}. The header is considered mandatory, therefore an error is returned to the client if no user ID was sent. + * + * @author evitaliy + * @since 21 Aug 2018 + */ +public class UserIdResolver implements HandlerMethodArgumentResolver { + + private static final String ERROR_MESSAGE = "Missing mandatory request header '" + USER_ID_HEADER + "'"; + + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + + if (!methodParameter.hasParameterAnnotation(UserId.class)) { + return false; + } + + Class<?> parameterType = methodParameter.getParameterType(); + if (!parameterType.equals(String.class)) { + throw new IllegalStateException("Cannot inject user ID into a parameter of type " + + parameterType.getTypeName()); + } + + return true; + } + + @Override + public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, + NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) + throws ServletRequestBindingException { + + HttpServletRequest httpServletRequest = nativeWebRequest.getNativeRequest(HttpServletRequest.class); + String userHeader = Objects.requireNonNull(httpServletRequest).getHeader(USER_ID_HEADER); + if (userHeader == null) { + throw new ServletRequestBindingException(ERROR_MESSAGE); + } + + return userHeader; + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/ActivitySpecConstant.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/ActivitySpecConstant.java new file mode 100644 index 00000000..bee916aa --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/ActivitySpecConstant.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services; + +public class ActivitySpecConstant { + + public static final String CATEGORY_ATTRIBUTE_NAME = "category"; + public static final String VERSION_ID_DEFAULT_VALUE = "latest"; + public static final String ACTIVITY_SPEC_NOT_FOUND = "No Activity Spec found for the given identifiers"; + + private ActivitySpecConstant() { + //Utility Class declaring constants does not require instantiation. + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/ActivitySpecManager.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/ActivitySpecManager.java new file mode 100644 index 00000000..b93a8dc8 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/ActivitySpecManager.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services; + +import java.util.Collection; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecAction; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; + +public interface ActivitySpecManager { + + ActivitySpecEntity createActivitySpec(ActivitySpecEntity activitySpec); + + ActivitySpecEntity get(ActivitySpecEntity activitySpec); + + void update(ActivitySpecEntity activitySpec); + + void actOnAction(ActivitySpecEntity activitySpec, ActivitySpecAction action); + + Collection<ActivitySpecEntity> list(String versionStatus); +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java new file mode 100644 index 00000000..0a789829 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/UniqueValueService.java @@ -0,0 +1,122 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services; + +import java.util.Optional; +import org.apache.commons.lang3.ArrayUtils; +import org.onap.sdc.workflow.persistence.UniqueValueRepository; +import org.onap.sdc.workflow.persistence.types.UniqueValueEntity; +import org.onap.sdc.workflow.services.exceptions.UniqueValueViolationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service("uniqueValueService") +public class UniqueValueService { + + private static final String 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, ArrayUtils.addAll(uniqueContext, newValue)); + deleteUniqueValue(type, ArrayUtils.addAll(uniqueContext, 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)); + } + + private Optional<String> formatValue(String[] uniqueCombination) { + if (ArrayUtils.isEmpty(uniqueCombination) || getValueWithoutContext(uniqueCombination) == null) { + return Optional.empty(); + } + + uniqueCombination[uniqueCombination.length - 1] = getValueWithoutContext(uniqueCombination).toLowerCase(); + return Optional.of(String.join(FORMATTED_UNIQUE_VALUE_SEPARATOR, uniqueCombination)); + } + + 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(); + } + + /** + * 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 String getValueWithoutContext(String[] uniqueCombination) { + return uniqueCombination[uniqueCombination.length - 1]; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java new file mode 100644 index 00000000..2c7a7c24 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowManager.java @@ -0,0 +1,37 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services; + +import java.util.Set; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +public interface WorkflowManager { + + Page<Workflow> list(String statusFilter, String searchNameFilter, Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec); + + Workflow get(Workflow workflow); + + Workflow create(Workflow workflow); + + void update(Workflow workflow); + + void updateStatus(String workflowId, ArchivingStatus status); +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java new file mode 100644 index 00000000..a7f5c421 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/WorkflowVersionManager.java @@ -0,0 +1,46 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services; + +import java.util.Collection; +import java.util.Set; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; +import org.onap.sdc.workflow.services.types.WorkflowVersion; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.springframework.web.multipart.MultipartFile; + + +public interface WorkflowVersionManager { + + Collection<WorkflowVersion> list(String workflowId, Set<WorkflowVersionState> stateFilter); + + WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion version); + + void update(String workflowId, WorkflowVersion version); + + WorkflowVersion get(String workflowId, String versionId); + + WorkflowVersionState getState(String workflowId, String versionId); + + void updateState(String workflowId, String versionId, WorkflowVersionState state); + + ArtifactEntity getArtifact(String workflowId, String versionId); + + void deleteArtifact(String workflowId, String versionId); + + void uploadArtifact(String workflowId, String versionId, MultipartFile artifact); +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/annotations/UserId.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/annotations/UserId.java new file mode 100644 index 00000000..90a1a763 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/annotations/UserId.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.annotations; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface UserId { } diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/EntityNotFoundException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/EntityNotFoundException.java new file mode 100644 index 00000000..7fc3e81c --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/EntityNotFoundException.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class EntityNotFoundException extends RuntimeException { + + public EntityNotFoundException(String message) { + super(message); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/InvalidArtifactException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/InvalidArtifactException.java new file mode 100644 index 00000000..c4584179 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/InvalidArtifactException.java @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class InvalidArtifactException extends RuntimeException { + + public InvalidArtifactException(String message) { + super("Invalid artifact file can not be processed. Error: " + message); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/UniqueValueViolationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/UniqueValueViolationException.java new file mode 100644 index 00000000..a3046a77 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/UniqueValueViolationException.java @@ -0,0 +1,27 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + + +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/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java new file mode 100644 index 00000000..31c88923 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionCreationException.java @@ -0,0 +1,31 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class VersionCreationException extends RuntimeException { + + private static final String MSG = "Error creating a new version for workflow with id %s"; + private static final String MSG_WITH_BASE_ID = MSG + " based on version %s: %s"; + + public VersionCreationException(String workflowId, String baseVersionId, String detailedMessage) { + super(String.format(MSG_WITH_BASE_ID, workflowId, baseVersionId, detailedMessage)); + } + + public VersionCreationException(String workflowId) { + super(String.format(MSG, workflowId)); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionModificationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionModificationException.java new file mode 100644 index 00000000..752d6bce --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionModificationException.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class VersionModificationException extends RuntimeException { + + public VersionModificationException(String workflowId, String versionId) { + super(String.format( + "Error while trying to modify version %s of workflow %s: Version is CERTIFIED and can not be edited", + versionId, workflowId)); + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java new file mode 100644 index 00000000..43360bd6 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationException.java @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +public class VersionStateModificationException extends RuntimeException { + + public VersionStateModificationException(String workflowId, String versionId, WorkflowVersionState sourceState, + WorkflowVersionState targetState) { + this(workflowId, versionId, sourceState, targetState, null); + } + + public VersionStateModificationException(String workflowId, String versionId, WorkflowVersionState sourceState, + WorkflowVersionState targetState, Exception submitException) { + super(String.format("Workflow %s, version %s: state can not be changed from %s to %s", workflowId, versionId, + sourceState.name(), targetState.name()), submitException); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationMissingArtifactException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationMissingArtifactException.java new file mode 100644 index 00000000..abda1caf --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStateModificationMissingArtifactException.java @@ -0,0 +1,32 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +public class VersionStateModificationMissingArtifactException extends RuntimeException { + + public static final String WORKFLOW_MODIFICATION_STATE_MISSING_ARTIFACT_TEMPLATE = + "Workflow %s, version %s: state can not be changed from %s to %s. Missing artifact"; + + public VersionStateModificationMissingArtifactException(String workflowId, String versionId, + WorkflowVersionState sourceState, + WorkflowVersionState targetState) { + super(String.format(WORKFLOW_MODIFICATION_STATE_MISSING_ARTIFACT_TEMPLATE, workflowId, versionId, + sourceState.name(), targetState.name())); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStatusModificationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStatusModificationException.java new file mode 100644 index 00000000..917a8384 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionStatusModificationException.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +import org.onap.sdc.common.versioning.services.types.VersionStatus; + +public class VersionStatusModificationException extends RuntimeException { + + public VersionStatusModificationException(String activitySpecId, String versionId, VersionStatus sourceState, + VersionStatus targetState) { + super(String.format("Activity spec %s, version %s: status can not be changed from %s to %s", activitySpecId, + versionId, sourceState.name(), targetState.name())); + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionValidationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionValidationException.java new file mode 100644 index 00000000..815bc0b2 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/VersionValidationException.java @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class VersionValidationException extends RuntimeException { + + private static final String MSG = "Error creating or modifying version for workflow with id %s: %s"; + + public VersionValidationException(String workflowId, String detailedMessage) { + super(String.format(MSG, workflowId, detailedMessage)); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowModificationException.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowModificationException.java new file mode 100644 index 00000000..7aa5ac0b --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/exceptions/WorkflowModificationException.java @@ -0,0 +1,25 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.exceptions; + +public class WorkflowModificationException extends RuntimeException { + + public WorkflowModificationException(String workflowId) { + super(String.format( + "Error while trying to modify workflow %s: Workflow is ARCHIVED and can not be edited", workflowId)); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/ActivitySpecManagerImpl.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/ActivitySpecManagerImpl.java new file mode 100644 index 00000000..e1849b9f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/ActivitySpecManagerImpl.java @@ -0,0 +1,231 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +import static org.onap.sdc.common.versioning.services.types.VersionStatus.Certified; +import static org.onap.sdc.common.versioning.services.types.VersionStatus.Deleted; +import static org.onap.sdc.common.versioning.services.types.VersionStatus.Deprecated; +import static org.onap.sdc.common.versioning.services.types.VersionStatus.Draft; +import static org.onap.sdc.workflow.services.ActivitySpecConstant.ACTIVITY_SPEC_NOT_FOUND; +import static org.onap.sdc.workflow.services.ActivitySpecConstant.VERSION_ID_DEFAULT_VALUE; + +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.onap.sdc.common.versioning.services.ItemManager; +import org.onap.sdc.common.versioning.services.VersioningManager; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.Version; +import org.onap.sdc.common.versioning.services.types.VersionCreationMethod; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecAction; +import org.onap.sdc.workflow.persistence.ActivitySpecRepository; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; +import org.onap.sdc.workflow.services.ActivitySpecManager; +import org.onap.sdc.workflow.services.UniqueValueService; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.VersionStatusModificationException; +import org.onap.sdc.workflow.services.impl.mappers.ActivitySpecMapper; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; + +@Service("activitySpecManager") +public class ActivitySpecManagerImpl implements ActivitySpecManager { + + private static final String ACTIVITY_SPEC_NAME = "ActivitySpec.Name"; + private static final Logger LOGGER = LoggerFactory.getLogger(ActivitySpecManagerImpl.class); + private static final Map<VersionStatus, VersionStatus> EXPECTED_PREV_STATUS; + + static { + EXPECTED_PREV_STATUS = new EnumMap<>(VersionStatus.class); + EXPECTED_PREV_STATUS.put(Certified, Draft); + EXPECTED_PREV_STATUS.put(Deprecated, Certified); + EXPECTED_PREV_STATUS.put(Deleted, Deprecated); + } + + private final ItemManager itemManager; + private final VersioningManager versioningManager; + private final ActivitySpecRepository activitySpecDao; + private final UniqueValueService uniqueValueService; + private final ActivitySpecMapper activitySpecMapper; + + + @Autowired + public ActivitySpecManagerImpl(ItemManager itemManager, VersioningManager versioningManager, + ActivitySpecRepository activitySpecDao, + @Qualifier("uniqueValueService") UniqueValueService uniqueValueService, + ActivitySpecMapper activitySpecMapper) { + this.itemManager = itemManager; + this.versioningManager = versioningManager; + this.activitySpecDao = activitySpecDao; + this.uniqueValueService = uniqueValueService; + this.activitySpecMapper = activitySpecMapper; + } + + @Override + public ActivitySpecEntity createActivitySpec(ActivitySpecEntity activitySpec) { + + uniqueValueService.validateUniqueValue(ACTIVITY_SPEC_NAME, activitySpec.getName()); + + Item item = new Item(); + activitySpecMapper.toItem(activitySpec, item); + Item createdItem = itemManager.create(item); + + Version createdVersion = + versioningManager.create(createdItem.getId(), null, new Version(), VersionCreationMethod.major); + + activitySpec.setId(createdItem.getId()); + activitySpec.setVersionId(createdVersion.getId()); + activitySpecDao.create(activitySpec); + + uniqueValueService.createUniqueValue(ACTIVITY_SPEC_NAME, activitySpec.getName()); + return activitySpec; + } + + @Override + public ActivitySpecEntity get(ActivitySpecEntity activitySpec) { + activitySpec.setVersionId(calculateLatestVersion(activitySpec)); + ActivitySpecEntity retrieved; + try { + + retrieved = activitySpecDao.get(activitySpec); + } catch (RuntimeException e) { + LOGGER.error("Failed to retrieve activity spec for activitySpecId: {} and version: {}", + activitySpec.getId(), activitySpec.getVersionId(), e); + throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND); + } + if (retrieved != null) { + final Version retrievedVersion = versioningManager.get(activitySpec.getId(), activitySpec.getVersionId()); + retrieved.setStatus(Objects.nonNull(retrievedVersion) ? retrievedVersion.getStatus().name() : null); + } + return retrieved; + } + + @Override + public void update(ActivitySpecEntity activitySpec) { + Item item = itemManager.get(activitySpec.getId()); + if (item == null) { + LOGGER.error("Activity Spec with id {} was not found", activitySpec.getId()); + throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND); + } + uniqueValueService.updateUniqueValue(ACTIVITY_SPEC_NAME, item.getName(), activitySpec.getName()); + + activitySpecMapper.toItem(activitySpec, item); + itemManager.update(activitySpec.getId(), item); + + activitySpec.setVersionId(calculateLatestVersion(activitySpec)); + activitySpecDao.update(activitySpec); + } + + @Override + public void actOnAction(ActivitySpecEntity activitySpec, ActivitySpecAction action) { + VersionStatus newStatus = getVersionStatusByAction(action); + + String versionId = calculateLatestVersion(activitySpec); + Version retrievedVersion; + try { + retrievedVersion = versioningManager.get(activitySpec.getId(), versionId); + } catch (RuntimeException e) { + LOGGER.error("failed to get activity {}, version {}", activitySpec.getId(), versionId, e); + throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND); + } + if (retrievedVersion == null) { + throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND); + } + + VersionStatus retrievedStatus = retrievedVersion.getStatus(); + VersionStatus expectedPrevStatus = EXPECTED_PREV_STATUS.get(newStatus); + if (expectedPrevStatus != null && retrievedStatus != expectedPrevStatus) { + LOGGER.debug("Failed to {} since activity spec is in status {}", action.name(), retrievedStatus); + throw new VersionStatusModificationException(activitySpec.getId(), versionId, retrievedStatus, + newStatus); + } + + versioningManager.updateStatus(activitySpec.getId(), retrievedVersion.getId(), newStatus, + "actionOnActivitySpec :" + action.name()); + + if (action == ActivitySpecAction.DELETE) { + final String activitySpecName = get(new ActivitySpecEntity(activitySpec.getId(), versionId)).getName(); + uniqueValueService.deleteUniqueValue(ACTIVITY_SPEC_NAME, activitySpecName); + } + } + + private VersionStatus getVersionStatusByAction(ActivitySpecAction action) { + switch (action) { + case DELETE: + return Deleted; + case DEPRECATE: + return Deprecated; + case CERTIFY: + return Certified; + default: + throw new UnsupportedOperationException( + String.format("Activity Spec action %s is not supported", action.name())); + } + + } + + @Override + public Collection<ActivitySpecEntity> list(String versionStatus) { + Predicate<Item> itemPredicate; + if (Objects.nonNull(versionStatus)) { + VersionStatus statusEnumValue; + + try { + statusEnumValue = VersionStatus.valueOf(versionStatus); + } catch (IllegalArgumentException e) { + LOGGER.debug("Unexpected value of VersionStatus {}", versionStatus); + return Collections.emptyList(); + } + itemPredicate = + item -> ItemType.ACTIVITYSPEC.name().equals(item.getType()) && item.getVersionStatusCounters() + .containsKey( + statusEnumValue); + } else { + itemPredicate = item -> ItemType.ACTIVITYSPEC.name().equals(item.getType()); + } + + return itemManager.list(itemPredicate).stream() + .sorted(Comparator.comparing(Item::getModificationTime).reversed()) + .map(activitySpecMapper::itemToActivitySpec).collect(Collectors.toList()); + } + + private String calculateLatestVersion(ActivitySpecEntity activitySpec) { + if (VERSION_ID_DEFAULT_VALUE.equalsIgnoreCase(activitySpec.getVersionId())) { + List<Version> versions; + try { + versions = versioningManager.list(activitySpec.getId()); + } catch (RuntimeException e) { + LOGGER.error("Failed to list versions for activitySpecId {}", activitySpec.getId(), e); + throw new EntityNotFoundException(ACTIVITY_SPEC_NOT_FOUND); + } + if (Objects.nonNull(versions) && !versions.isEmpty()) { + return versions.get(0).getId(); + } + } + return activitySpec.getVersionId(); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/ItemType.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/ItemType.java new file mode 100644 index 00000000..8a05d88d --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/ItemType.java @@ -0,0 +1,21 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +public enum ItemType { + WORKFLOW, ACTIVITYSPEC +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java new file mode 100644 index 00000000..fc135621 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImpl.java @@ -0,0 +1,217 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +import static org.onap.sdc.workflow.services.impl.ItemType.WORKFLOW; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET; +import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT; + +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import org.onap.sdc.common.versioning.services.ItemManager; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.ItemStatus; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.services.UniqueValueService; +import org.onap.sdc.workflow.services.WorkflowManager; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; +import org.onap.sdc.workflow.services.impl.mappers.ArchivingStatusMapper; +import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; +import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.PagingRequest; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.Sort; +import org.onap.sdc.workflow.services.types.SortingRequest; +import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +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 { + + private static final String WORKFLOW_NOT_FOUND_ERROR_MSG = "Workflow with id '%s' does not exist"; + private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME"; + private static final Predicate<Item> WORKFLOW_ITEM_TYPE_FILTER = item -> WORKFLOW.name().equals(item.getType()); + private static final String WORKSPACES_SORT_PROPERTY = "name"; + private static final RequestSpec WORKSPACES_DEFAULT_REQUEST_SPEC = + new RequestSpec(new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), + SortingRequest.builder().sort(new Sort(WORKSPACES_SORT_PROPERTY, true)).build()); + + private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowManagerImpl.class); + + private final ItemManager itemManager; + private final UniqueValueService uniqueValueService; + private final WorkflowMapper workflowMapper; + private final ArchivingStatusMapper archivingStatusMapper; + private final VersionStateMapper versionStateMapper; + + @Autowired + public WorkflowManagerImpl(ItemManager itemManager, + @Qualifier("uniqueValueService") UniqueValueService uniqueValueService, WorkflowMapper workflowMapper, + ArchivingStatusMapper archivingStatusMapper, VersionStateMapper versionStateMapper) { + this.itemManager = itemManager; + this.uniqueValueService = uniqueValueService; + this.workflowMapper = workflowMapper; + this.archivingStatusMapper = archivingStatusMapper; + this.versionStateMapper = versionStateMapper; + } + + @Override + public Page<Workflow> list(String statusFilter, String searchNameFilter, + Set<WorkflowVersionState> versionStatesFilter, RequestSpec requestSpec) { + requestSpec = getRequestSpec(requestSpec); + + Collection<Item> workflowItems = + itemManager.list(createFilter(statusFilter, searchNameFilter, versionStatesFilter)); + + List<Workflow> workflowsSlice = workflowItems.stream().map(workflowMapper::fromItem) + .sorted(getWorkflowComparator(requestSpec.getSorting())) + .skip(requestSpec.getPaging().getOffset()) + .limit(requestSpec.getPaging().getLimit()).collect(Collectors.toList()); + + return new Page<>(workflowsSlice, requestSpec.getPaging(), workflowItems.size()); + } + + @Override + public Workflow get(Workflow workflow) { + Item retrievedItem = itemManager.get(workflow.getId()); + if (retrievedItem == null) { + throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId())); + } + return this.workflowMapper.fromItem(retrievedItem); + } + + @Override + public Workflow create(Workflow workflow) { + Item item = new Item(); + workflowMapper.toItem(workflow, item); + + uniqueValueService.validateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflow.getName()); + Item createdItem = itemManager.create(item); + uniqueValueService.createUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflow.getName()); + + return workflowMapper.fromItem(createdItem); + } + + @Override + public void update(Workflow workflow) { + Item item = itemManager.get(workflow.getId()); + if (item == null) { + throw new EntityNotFoundException(String.format(WORKFLOW_NOT_FOUND_ERROR_MSG, workflow.getId())); + } + + if (ItemStatus.ARCHIVED.equals(item.getStatus())) { + throw new WorkflowModificationException(workflow.getId()); + } + + uniqueValueService.updateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, item.getName(), workflow.getName()); + + workflowMapper.toItem(workflow, item); + itemManager.update(workflow.getId(), item); + } + + @Override + public void updateStatus(String workflowId, ArchivingStatus status) { + itemManager.updateStatus(workflowId, archivingStatusMapper.toItemStatus(status)); + } + + private static RequestSpec getRequestSpec(RequestSpec requestSpec) { + if (requestSpec == null) { + return WORKSPACES_DEFAULT_REQUEST_SPEC; + } + if (requestSpec.getPaging() == null) { + requestSpec.setPaging(WORKSPACES_DEFAULT_REQUEST_SPEC.getPaging()); + } else { + handlePagingRequestValues(requestSpec.getPaging()); + } + if (requestSpec.getSorting() == null) { + requestSpec.setSorting(WORKSPACES_DEFAULT_REQUEST_SPEC.getSorting()); + } + return requestSpec; + } + + private static void handlePagingRequestValues(PagingRequest paging) { + if (paging.getOffset() == null) { + paging.setOffset(DEFAULT_OFFSET); + } + if (paging.getLimit() == null) { + paging.setLimit(DEFAULT_LIMIT); + } else if (paging.getLimit() > MAX_LIMIT) { + paging.setLimit(MAX_LIMIT); + } + } + + private static Comparator<Workflow> getWorkflowComparator(SortingRequest sorting) { + Boolean byNameAscending = sorting.getSorts().stream() + .filter(sort -> WORKSPACES_SORT_PROPERTY.equalsIgnoreCase(sort.getProperty())) + .findFirst().map(Sort::isAscendingOrder).orElse(true); + Comparator<Workflow> byName = Comparator.comparing(Workflow::getName); + + return byNameAscending ? byName : byName.reversed(); + } + + private Predicate<Item> createFilter(String itemStatusFilter, String searchNameFilter, + Set<WorkflowVersionState> versionStatesFilter) { + + Set<VersionStatus> versionStatusesFilter = versionStatesFilter == null ? null : + versionStatesFilter.stream() + .map(versionStateMapper::workflowVersionStateToVersionStatus) + .collect(Collectors.toSet()); + + Predicate<Item> filter = addSearchNameFilter(WORKFLOW_ITEM_TYPE_FILTER, searchNameFilter); + + filter = addVersionStatusFilter(filter, versionStatusesFilter); + + return addItemStatusFilter(filter, itemStatusFilter); + + } + + private static Predicate<Item> addSearchNameFilter(Predicate<Item> filter, String searchNameFilter) { + return filter.and(item -> searchNameFilter == null || item.getName().toLowerCase() + .contains(searchNameFilter.toLowerCase())); + } + + private static Predicate<Item> addVersionStatusFilter(Predicate<Item> filter, Set<VersionStatus> versionStatuses) { + return filter.and(item -> versionStatuses == null || item.getVersionStatusCounters().keySet().stream() + .anyMatch(versionStatuses::contains)); + } + + private static Predicate<Item> addItemStatusFilter(Predicate<Item> filter, String itemStatusFilter) { + if (itemStatusFilter != null) { + try { + ItemStatus.valueOf(itemStatusFilter.toUpperCase()); + } catch (IllegalArgumentException e) { + LOGGER.debug("Illegal Workflow status filter: {}. Ignoring filter", itemStatusFilter, e); + return filter; + } + return filter.and(item -> item.getStatus().equals(ItemStatus.valueOf(itemStatusFilter.toUpperCase()))); + } + return filter; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java new file mode 100644 index 00000000..f95e6a1f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImpl.java @@ -0,0 +1,308 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +import static org.onap.sdc.workflow.services.types.WorkflowVersionState.CERTIFIED; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Collection; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.onap.sdc.common.versioning.services.ItemManager; +import org.onap.sdc.common.versioning.services.VersioningManager; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.ItemStatus; +import org.onap.sdc.common.versioning.services.types.Version; +import org.onap.sdc.common.versioning.services.types.VersionCreationMethod; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.persistence.ArtifactRepository; +import org.onap.sdc.workflow.persistence.ParameterRepository; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; +import org.onap.sdc.workflow.persistence.types.ParameterEntity; +import org.onap.sdc.workflow.persistence.types.ParameterRole; +import org.onap.sdc.workflow.services.WorkflowVersionManager; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.InvalidArtifactException; +import org.onap.sdc.workflow.services.exceptions.VersionCreationException; +import org.onap.sdc.workflow.services.exceptions.VersionModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; +import org.onap.sdc.workflow.services.impl.mappers.VersionMapper; +import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; +import org.onap.sdc.workflow.services.types.WorkflowVersion; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +@Service("workflowVersionManager") +public class WorkflowVersionManagerImpl implements WorkflowVersionManager { + + private static final String VERSION_NOT_EXIST_MSG = "version with id '%s' does not exist for workflow with id '%s'"; + private final VersioningManager versioningManager; + private final ItemManager itemManager; + private final ArtifactRepository artifactRepository; + private final ParameterRepository parameterRepository; + private final VersionMapper versionMapper; + private final VersionStateMapper versionStateMapper; + private static final Logger LOGGER = LoggerFactory.getLogger(WorkflowVersionManagerImpl.class); + + @Autowired + public WorkflowVersionManagerImpl(VersioningManager versioningManager, ArtifactRepository artifactRepository, + VersionMapper versionMapper, VersionStateMapper versionStateMapper, ItemManager itemManager, + ParameterRepository parameterRepository) { + this.itemManager = itemManager; + this.versioningManager = versioningManager; + this.artifactRepository = artifactRepository; + this.parameterRepository = parameterRepository; + this.versionMapper = versionMapper; + this.versionStateMapper = versionStateMapper; + } + + @Override + public Collection<WorkflowVersion> list(String workflowId, Set<WorkflowVersionState> stateFilter) { + Set<VersionStatus> versionStatusFilter = + stateFilter == null ? null : + stateFilter.stream().map(versionStateMapper::workflowVersionStateToVersionStatus) + .collect(Collectors.toSet()); + + return versioningManager.list(workflowId).stream() + .filter(version -> versionStatusFilter == null || versionStatusFilter.contains( + version.getStatus())) + .map(versionMapper::fromVersion) + .sorted(Comparator.comparing(WorkflowVersion::getName).reversed()) + .peek(workflowVersion -> loadAndAddParameters(workflowId, workflowVersion)) + .collect(Collectors.toList()); + } + + @Override + public WorkflowVersion get(String workflowId, String versionId) { + WorkflowVersion workflowVersion = versionMapper.fromVersion(getVersion(workflowId, versionId)); + loadAndAddParameters(workflowId, workflowVersion); + workflowVersion.setHasArtifact(artifactRepository.isExist(workflowId,versionId)); + return workflowVersion; + } + + @Override + public WorkflowVersion create(String workflowId, String baseVersionId, WorkflowVersion workflowVersion) { + validateWorkflowStatus(workflowId); + List<Version> versions = versioningManager.list(workflowId); + + if (baseVersionId != null) { + if (!workflowVersion.getInputs().isEmpty() || !workflowVersion.getOutputs().isEmpty()) { + throw new VersionCreationException(workflowId, baseVersionId, "Inputs/Outputs should not be supplied"); + } + validateVersionExistAndCertified(workflowId, versions, baseVersionId); + } else if (!versions.isEmpty()) { + throw new VersionCreationException(workflowId); + } + + Version version = new Version(); + version.setDescription(workflowVersion.getDescription()); + Version createdVersion = versioningManager.create(workflowId, baseVersionId, version, VersionCreationMethod.major); + + if (versions.isEmpty()) { // only for first versionId + artifactRepository.createStructure(workflowId, createdVersion.getId()); + parameterRepository.createStructure(workflowId, createdVersion.getId()); + updateParameters(workflowId, createdVersion.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs()); + versioningManager.publish(workflowId, createdVersion.getId(), "Add initial data"); + } + + return get(workflowId, createdVersion.getId()); + } + + @Override + public void update(String workflowId, WorkflowVersion workflowVersion) { + validateWorkflowStatus(workflowId); + Version version = getVersion(workflowId, workflowVersion.getId()); + if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(version.getStatus()))) { + throw new VersionModificationException(workflowId, workflowVersion.getId()); + } + + versionMapper.toVersion(workflowVersion, version); + + updateParameters(workflowId, version.getId(), workflowVersion.getInputs(), workflowVersion.getOutputs()); + + versioningManager.update(workflowId, version.getId(), version); + + Version updatedVersion = versioningManager.get(workflowId, version.getId()); + if (updatedVersion.getState().isDirty()) { + versioningManager.publish(workflowId, version.getId(), "Update version"); + } + } + + + @Override + public WorkflowVersionState getState(String workflowId, String versionId) { + return versionStateMapper.versionStatusToWorkflowVersionState(getVersion(workflowId, versionId).getStatus()); + } + + @Override + public void updateState(String workflowId, String versionId, WorkflowVersionState newState) { + WorkflowVersionState currentState = getState(workflowId, versionId); + if (newState == CERTIFIED) { + if(!artifactRepository.isExist(workflowId,versionId)){ + throw new VersionStateModificationMissingArtifactException(workflowId, versionId, currentState, + newState); + } + try { + versioningManager.updateStatus(workflowId, versionId, VersionStatus.Certified, + String.format("Update version state to %s", newState.name())); + } catch (Exception submitException) { + throw new VersionStateModificationException(workflowId, versionId, currentState, newState, + submitException); + } + } else { + throw new VersionStateModificationException(workflowId, versionId, currentState, newState); + } + } + + @Override + public void uploadArtifact(String workflowId, String versionId, MultipartFile artifact) { + validateWorkflowStatus(workflowId); + Version retrievedVersion = getVersion(workflowId, versionId); + if (CERTIFIED.equals(versionStateMapper.versionStatusToWorkflowVersionState(retrievedVersion.getStatus()))) { + throw new VersionModificationException(workflowId, versionId); + } + + try (InputStream artifactData = artifact.getInputStream()) { + ArtifactEntity artifactEntity = + new ArtifactEntity(StringUtils.cleanPath(artifact.getOriginalFilename()), artifactData); + artifactRepository.update(workflowId, versionId, artifactEntity); + Version updatedVersion = versioningManager.get(workflowId, versionId); + if(updatedVersion.getState().isDirty()) { + versioningManager.publish(workflowId, updatedVersion.getId(), "Update artifact"); + } + + } catch (IOException e) { + LOGGER.error(String.format("Upload Artifact failed for workflow id %s and version id %s", + workflowId, versionId),e); + throw new InvalidArtifactException(e.getMessage()); + } + } + + @Override + public ArtifactEntity getArtifact(String workflowId, String versionId) { + getVersion(workflowId, versionId); + Optional<ArtifactEntity> artifactOptional = artifactRepository.get(workflowId, versionId); + if (!artifactOptional.isPresent()) { + LOGGER.error("Workflow Version Artifact was not found for workflow id {} and version id {}", + workflowId, versionId); + throw new EntityNotFoundException( + String.format("Artifact for workflow id %s version id %s was not found", workflowId, versionId)); + } + return artifactOptional.get(); + } + + @Override + public void deleteArtifact(String workflowId, String versionId) { + validateWorkflowStatus(workflowId); + WorkflowVersion retrievedVersion = get(workflowId, versionId); + if (CERTIFIED.equals(retrievedVersion.getState())) { + LOGGER.error("Workflow Version is certified and can not be edited.Workflow id {} and version id {}", + workflowId, versionId); + throw new VersionModificationException(workflowId, versionId); + } + if(retrievedVersion.isHasArtifact()) { + artifactRepository.delete(workflowId, versionId); + versioningManager.publish(workflowId, versionId, "Delete Artifact"); + } + } + + private void validateVersionExistAndCertified(String workflowId, List<Version> versions, String versionId) { + Version baseVersion = findVersion(versions, versionId).orElseThrow( + () -> new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId))); + + if (CERTIFIED != versionStateMapper.versionStatusToWorkflowVersionState(baseVersion.getStatus())) { + throw new VersionCreationException(workflowId, versionId, "base version must be CERTIFIED"); + } + } + + private Version getVersion(String workflowId, String versionId) { + try { + Version version = versioningManager.get(workflowId, versionId); + if (version == null) { + throw new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId)); + } + return version; + } catch (Exception e) { + LOGGER.error(String.format( + "Workflow Version was not found.Workflow id %s and version id %s", workflowId, + versionId),e); + throw new EntityNotFoundException(String.format(VERSION_NOT_EXIST_MSG, versionId, workflowId)); + } + } + + private void updateParameters(String workflowId, String versionId, Collection<ParameterEntity> inputs, + Collection<ParameterEntity> outputs) { + updateVersionParameters(workflowId, versionId, ParameterRole.INPUT, inputs); + updateVersionParameters(workflowId, versionId, ParameterRole.OUTPUT, outputs); + } + + private void updateVersionParameters(String workflowId, String versionId, ParameterRole role, + Collection<ParameterEntity> parameters) { + + Collection<ParameterEntity> retrievedParams = parameterRepository.list(workflowId, versionId, role); + Map<String, ParameterEntity> retrievedParamsByName = + retrievedParams.stream().collect(Collectors.toMap(ParameterEntity::getName, Function.identity())); + + Set<String> namesOfParamsToKeep = new HashSet<>(); + for (ParameterEntity parameter : parameters) { + + ParameterEntity retrievedParam = retrievedParamsByName.get(parameter.getName()); + if (retrievedParam == null) { + parameterRepository.create(workflowId, versionId, role, parameter); + } else { + parameter.setId(retrievedParam.getId()); + parameterRepository.update(workflowId, versionId, role, parameter); + namesOfParamsToKeep.add(parameter.getName()); + } + } + + retrievedParams.stream().filter(retrievedParam -> !namesOfParamsToKeep.contains(retrievedParam.getName())) + .forEach(retrievedParam -> parameterRepository + .delete(workflowId, versionId, retrievedParam.getId())); + } + + private void loadAndAddParameters(String workflowId, WorkflowVersion workflowVersion) { + workflowVersion.setInputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.INPUT)); + workflowVersion.setOutputs(parameterRepository.list(workflowId, workflowVersion.getId(), ParameterRole.OUTPUT)); + } + + private static Optional<Version> findVersion(List<Version> versions, String versionId) { + return versions.stream().filter(version -> versionId.equals(version.getId())).findFirst(); + } + + void validateWorkflowStatus(String workflowId) { + Item workflowItem = itemManager.get(workflowId); + if (ItemStatus.ARCHIVED.equals(workflowItem.getStatus())) { + throw new WorkflowModificationException(workflowId); + } + } + +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ActivitySpecMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ActivitySpecMapper.java new file mode 100644 index 00000000..09e96c3e --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ActivitySpecMapper.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import static org.onap.sdc.workflow.services.ActivitySpecConstant.CATEGORY_ATTRIBUTE_NAME; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; +import org.onap.sdc.workflow.services.ActivitySpecConstant; +import org.onap.sdc.workflow.services.impl.ItemType; + +@Mapper(componentModel = "spring", imports = {ItemType.class, ActivitySpecConstant.class}) +public interface ActivitySpecMapper { + + @Mapping(source = "versionStatusCounters", target = "status") + @Mapping(source = "properties", target = "categoryList") + ActivitySpecEntity itemToActivitySpec(Item item); + + @InheritInverseConfiguration + @Mapping(expression = "java(ItemType.ACTIVITYSPEC.name())", target = "type") + @Mapping(target = "versionStatusCounters", ignore = true) + @Mapping(target = "status", ignore = true) + @Mapping(source = "categoryList", target = "properties") + void toItem(ActivitySpecEntity activitySpec, @MappingTarget Item retrievedItem); + + default String versionStatusCountersToStatus(Map<VersionStatus, Integer> versionStatusCounters) { + return versionStatusCounters.keySet().stream().findFirst().map(Enum::name).orElse(null); + } + + default Map<String, Object> categoriesToProperties(List<String> categories) { + Map<String, Object> properties = new HashMap<>(); + properties.put(CATEGORY_ATTRIBUTE_NAME, categories); + return properties; + } + + default List<String> propertiesToCategories(Map<String, Object> properties) { + return (List<String>) properties.get(CATEGORY_ATTRIBUTE_NAME); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ArchivingStatusMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ArchivingStatusMapper.java new file mode 100644 index 00000000..702815f6 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/ArchivingStatusMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.onap.sdc.common.versioning.services.types.ItemStatus; +import org.onap.sdc.workflow.services.types.ArchivingStatus; + +@Mapper(componentModel = "spring") +public interface ArchivingStatusMapper { + + @ValueMapping(source = "ACTIVE", target = "ACTIVE") + @ValueMapping(source = "ARCHIVED", target = "ARCHIVED") + @ValueMapping(source = "<ANY_REMAINING>", target = "ACTIVE") + ArchivingStatus fromItemStatus(ItemStatus status); + + @InheritInverseConfiguration + ItemStatus toItemStatus(ArchivingStatus status); + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionMapper.java new file mode 100644 index 00000000..145c79fe --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionMapper.java @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.onap.sdc.common.versioning.services.convertors.VersionConvertor; +import org.onap.sdc.common.versioning.services.types.Version; +import org.onap.sdc.workflow.services.impl.ItemType; +import org.onap.sdc.workflow.services.types.WorkflowVersion; + +@Mapper(componentModel = "spring", uses = VersionStateMapper.class) +public interface VersionMapper extends VersionConvertor<WorkflowVersion> { + + @Override + default String getItemType(){ + return ItemType.WORKFLOW.name(); + } + + @Override + @Mapping(source = "status", target = "state") + WorkflowVersion fromVersion(Version version); + + @Override + @InheritInverseConfiguration + @Mapping(target = "status", ignore = true) + void toVersion(WorkflowVersion workflowVersion, @MappingTarget Version retrievedVersion); + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java new file mode 100644 index 00000000..05772f4f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; + +@Mapper(componentModel = "spring") +public interface VersionStateMapper { + + @ValueMapping(source = "Certified", target = "CERTIFIED") + @ValueMapping(source = "Draft", target = "DRAFT") + @ValueMapping(source = "<ANY_REMAINING>", target = "DRAFT") + WorkflowVersionState versionStatusToWorkflowVersionState(VersionStatus status); + + @InheritInverseConfiguration + VersionStatus workflowVersionStateToVersionStatus(WorkflowVersionState status); + + default Set<WorkflowVersionState> versionStatusCountersToWorkflowVersionStates( + Map<VersionStatus, Integer> versionStatusCounters) { + return versionStatusCounters.keySet().stream().map(this::versionStatusToWorkflowVersionState) + .collect(Collectors.toSet()); + } + + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java new file mode 100644 index 00000000..214d2ac6 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapper.java @@ -0,0 +1,49 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.onap.sdc.common.versioning.services.convertors.ItemConvertor; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.workflow.services.impl.ItemType; +import org.onap.sdc.workflow.services.types.Workflow; + +@Mapper(componentModel = "spring", imports = ItemType.class, + uses = {VersionStateMapper.class, ArchivingStatusMapper.class}) +public interface WorkflowMapper extends ItemConvertor<Workflow> { + + @Override + default String getItemType() { + return ItemType.WORKFLOW.name(); + } + + @Override + @Mapping(source = "versionStatusCounters", target = "versionStates") + @Mapping(source = "status", target = "archiving") + Workflow fromItem(Item item); + + @Override + @InheritInverseConfiguration + @Mapping(target = "status", ignore = true) + @Mapping(target = "versionStatusCounters", ignore = true) + @Mapping(expression = "java(ItemType.WORKFLOW.name())", target = "type") + void toItem(Workflow workflow, @MappingTarget Item item); + +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/ArchivingStatus.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/ArchivingStatus.java new file mode 100644 index 00000000..2e7eb22b --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/ArchivingStatus.java @@ -0,0 +1,22 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +public enum ArchivingStatus { + ARCHIVED, + ACTIVE +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Page.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Page.java new file mode 100644 index 00000000..3fc9d0ba --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Page.java @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import java.util.List; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +public class Page<T> { + + private Paging paging; + private List<T> items; + + public Page(List<T> items, PagingRequest pagingRequest, int total) { + this.items = items; + this.paging = new Paging(pagingRequest, items.size(), total); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Paging.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Paging.java new file mode 100644 index 00000000..2c4124fa --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Paging.java @@ -0,0 +1,41 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import lombok.Getter; + +@Getter +public class Paging { + + private int offset; + private int limit; + private int count; + private boolean hasMore; + private int total; + + public Paging(PagingRequest pagingRequest, int count, int total) { + this.offset = pagingRequest.getOffset(); + this.limit = pagingRequest.getLimit(); + this.count = count; + setTotal(total); + } + + private void setTotal(int total) { + this.total = total; + this.hasMore = total > offset + limit; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingConstants.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingConstants.java new file mode 100644 index 00000000..214e7ea2 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingConstants.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +public class PagingConstants { + + public static final int DEFAULT_OFFSET = 0; + public static final int DEFAULT_LIMIT = 200; + public static final int MAX_LIMIT = 2000; + + private PagingConstants() { + throw new IllegalStateException("Constants class"); + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingRequest.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingRequest.java new file mode 100644 index 00000000..6408ee69 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/PagingRequest.java @@ -0,0 +1,39 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import lombok.Getter; + +@Getter +public class PagingRequest { + + private Integer offset; + private Integer limit; + + public PagingRequest(int offset, int limit) { + setOffset(offset); + setLimit(limit); + } + + public void setOffset(int offset) { + this.offset = offset < 0 ? null : offset; + } + + public void setLimit(int limit) { + this.limit = limit <= 0 ? null : limit; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/RequestSpec.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/RequestSpec.java new file mode 100644 index 00000000..06ebdf1c --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/RequestSpec.java @@ -0,0 +1,28 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class RequestSpec { + + private PagingRequest paging; + private SortingRequest sorting; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Sort.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Sort.java new file mode 100644 index 00000000..b26ef1cb --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Sort.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import lombok.AllArgsConstructor; +import lombok.EqualsAndHashCode; +import lombok.Getter; + +@Getter +@EqualsAndHashCode +@AllArgsConstructor +public class Sort { + + private String property; + private boolean ascendingOrder; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/SortingRequest.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/SortingRequest.java new file mode 100644 index 00000000..cd8b2c27 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/SortingRequest.java @@ -0,0 +1,30 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import java.util.List; +import lombok.Builder; +import lombok.Getter; +import lombok.Singular; + +@Builder +@Getter +public class SortingRequest { + + @Singular + private List<Sort> sorts; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java new file mode 100644 index 00000000..fcac779f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/Workflow.java @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + + +import static org.onap.sdc.workflow.services.types.WorkflowValidationConstants.MAX_LENGTH; +import static org.onap.sdc.workflow.services.types.WorkflowValidationConstants.MIN_LENGTH; + +import java.util.Collection; +import java.util.Set; +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; +import lombok.Data; + + +@Data +public class Workflow { + + private String id; + @NotBlank(message = "Workflow name may not be blank.") + @Size(min = MIN_LENGTH, max = MAX_LENGTH, + message = "Workflow name must be at least " + MIN_LENGTH + " characters, and no more than " + MAX_LENGTH + + " characters.") + @Pattern(regexp = "[A-Za-z0-9_. -]+", message = "Workflow name must contain only letters, digits and underscores.") + private String name; + private String description; + private Set<WorkflowVersionState> versionStates; + private Collection<WorkflowVersion> versions; + private ArchivingStatus archiving; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowValidationConstants.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowValidationConstants.java new file mode 100644 index 00000000..2d54c7b8 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowValidationConstants.java @@ -0,0 +1,23 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +public class WorkflowValidationConstants { + + public static final int MAX_LENGTH = 80; + public static final int MIN_LENGTH = 6; +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowVersion.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowVersion.java new file mode 100644 index 00000000..0699157f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowVersion.java @@ -0,0 +1,46 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.onap.sdc.workflow.persistence.types.ParameterEntity; + + +@Data +@NoArgsConstructor +public class WorkflowVersion { + + private String id; + private String name; + private String description; + private String baseId; + private WorkflowVersionState state; + private Collection<ParameterEntity> inputs = Collections.emptyList(); + private Collection<ParameterEntity> outputs = Collections.emptyList(); + private boolean hasArtifact; + private Date creationTime; + private Date modificationTime; + + public WorkflowVersion(String id) { + this.id = id; + this.state = WorkflowVersionState.DRAFT; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowVersionState.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowVersionState.java new file mode 100644 index 00000000..cccdd5c7 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/types/WorkflowVersionState.java @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.types; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public enum WorkflowVersionState { + + CERTIFIED, DRAFT(CERTIFIED); + + private final List<WorkflowVersionState> nextStates; + + WorkflowVersionState(WorkflowVersionState... nextStates) { + this.nextStates = Collections.unmodifiableList(Arrays.asList(nextStates)); + } + + public List<WorkflowVersionState> getNextStates() { + return nextStates; + } +} diff --git a/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/utilities/JsonUtil.java b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/utilities/JsonUtil.java new file mode 100644 index 00000000..3e197a9f --- /dev/null +++ b/sdc-workflow-designer-be/src/main/java/org/onap/sdc/workflow/services/utilities/JsonUtil.java @@ -0,0 +1,96 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.utilities; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonIOException; +import com.google.gson.JsonSyntaxException; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; + +public class JsonUtil { + + private static final Gson gson = new Gson(); + + private JsonUtil() { + } + + /** + * Object 2 json string. + * + * @param obj the obj + * @return the string + */ + public static String object2Json(Object obj) { + return sbObject2Json(obj).toString(); + + } + + /** + * Sb object 2 json string builder. + * + * @param obj the obj + * @return the string builder + */ + public static StringBuilder sbObject2Json(Object obj) { + return new StringBuilder(new GsonBuilder().setPrettyPrinting().create().toJson(obj)); + } + + /** + * Json 2 object t. + * + * @param <T> the type parameter + * @param json the json + * @param classOfT the class of t + * @return the t + */ + public static <T> T json2Object(String json, Class<T> classOfT) { + T typ; + try { + try (Reader br = new StringReader(json)) { + typ = gson.fromJson(br, classOfT); + } + } catch (JsonIOException | JsonSyntaxException | IOException exception) { + throw new RuntimeException(exception); + } + return typ; + } + + /** + * Json 2 object t. + * + * @param <T> the type parameter + * @param is the is + * @param classOfT the class of t + * @return the t + */ + public static <T> T json2Object(InputStream is, Class<T> classOfT) { + T type; + try (Reader br = new BufferedReader(new InputStreamReader(is))) { + type = new Gson().fromJson(br, classOfT); + } catch (JsonIOException | JsonSyntaxException | IOException exception) { + throw new RuntimeException(exception); + } + return type; + } + +} diff --git a/sdc-workflow-designer-be/src/main/resources/application-dev.properties b/sdc-workflow-designer-be/src/main/resources/application-dev.properties new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/sdc-workflow-designer-be/src/main/resources/application-dev.properties diff --git a/sdc-workflow-designer-be/src/main/resources/application.properties b/sdc-workflow-designer-be/src/main/resources/application.properties new file mode 100644 index 00000000..7dcc2c4b --- /dev/null +++ b/sdc-workflow-designer-be/src/main/resources/application.properties @@ -0,0 +1,66 @@ +#/ +# Copyright � 2016-2018 European Support Limited +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#/ +server.servlet.context-path=/ +http.port=${HTTP_PORT:8080} + +server.port=${SERVER_PORT:8443} +server.ssl.enabled=${SERVER_SSL_ENABLED:true} +server.ssl.key-password=${SERVER_SSL_KEY_PASSWORD:} +server.ssl.key-store-password=${SERVER_SSL_KEY_PASSWORD:} +server.ssl.key-store=${SERVER_SSL_KEYSTORE_PATH:} +server.ssl.key-store-type=${SERVER_SSL_KEYSTORE_TYPE:} +server.ssl.trust-store-password=${SERVER_SSL_TRUST_PASSWORD:} +server.ssl.trust-store=${SERVER_SSL_TRUSTSTORE_PATH:} +server.ssl.trust-store-type=${SERVER_SSL_TRUSTSTORE_TYPE:} +#server.ssl.protocol=${SERVER_SSL_PROTOCOL:TLS} +#server.ssl.enabled-protocols=${SERVER_SSL_ENABLED_PROTOCOL:TLSv1.2} + + +sdc.be.protocol=${SDC_PROTOCOL:} +sdc.be.endpoint=${SDC_ENDPOINT:} +sdc.be.external.user=${SDC_USER:} +sdc.be.external.password=${SDC_PASSWORD:} + +#CASSANDRA +spring.data.cassandra.contact-points=${CS_HOSTS} +spring.data.cassandra.keyspace-name=workflow +spring.data.cassandra.port=${CS_PORT:9042} +spring.data.cassandra.username=${CS_USER:} +spring.data.cassandra.password=${CS_PASSWORD:} +zusammen.cassandra.isAuthenticate=${CS_AUTHENTICATE:false} +spring.data.cassandra.ssl=${CS_SSL_ENABLED:false} +zusammen.cassandra.trustStorePath=${CS_TRUST_STORE_PATH:} +zusammen.cassandra.trustStorePassword=${CS_TRUST_STORE_PASSWORD:} +spring.data.cassandra.jmx-enabled=false + +#Actuators +management.endpoint.health.show-details=always + +#Headers are comma separated list +onap.logging.requestIdHeader=X-ECOMP-RequestID,X-ONAP-RequestID +onap.logging.partnerNameHeader=USER_ID + +logging.level.org.springframework=INFO +logging.level.org.onap.sdc.workflow=INFO + +#output to a temp_folder/file +logging.file=${java.io.tmpdir}/application.log + +# Logging pattern for the console +logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss} - %msg%n + +# Logging pattern for file +logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg% diff --git a/sdc-workflow-designer-be/src/main/resources/logback.xml b/sdc-workflow-designer-be/src/main/resources/logback.xml new file mode 100644 index 00000000..f0a4bcb2 --- /dev/null +++ b/sdc-workflow-designer-be/src/main/resources/logback.xml @@ -0,0 +1,194 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + ~ Copyright © 2016-2018 European Support Limited + ~ + ~ Licensed under the Apache License, Version 2.0 (the "License"); + ~ you may not use this file except in compliance with the License. + ~ You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, software + ~ distributed under the License is distributed on an "AS IS" BASIS, + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ~ See the License for the specific language governing permissions and + ~ limitations under the License. + --> + +<configuration> + + <property scope="system" name="ONAP-component-name" value="workflow-designer"/> + <property scope="system" name="ONAP-subcomponent-name" value="backend"/> + <property name="log.home" value="/var/log/ONAP"/> + <property name="log.location" value="${log.home}/${ONAP-component-name}/${ONAP-subcomponent-name}"/> + + <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <file>${log.location}/error.log</file> + + <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> + <level>INFO</level> + </filter> + + <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> + <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"> + <marker>AUDIT</marker> + </evaluator> + <onMismatch>NEUTRAL</onMismatch> + <onMatch>DENY</onMatch> + </filter> + + <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> + <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"> + <marker>METRICS</marker> + </evaluator> + <onMismatch>NEUTRAL</onMismatch> + <onMatch>DENY</onMatch> + </filter> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.location}/error.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern> + %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%thread||%X{ServiceName}|%X{PartnerName}|%X{TargetEntity}|%X{TargetServiceName}|%level||%X{ErrorCode}|%X{ErrorDescription}|%msg%n + </pattern> + </encoder> + </appender> + + <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <file>${log.location}/debug.log</file> + + <filter class="ch.qos.logback.classic.filter.LevelFilter"> + <level>DEBUG</level> + <onMatch>ACCEPT</onMatch> + <onMismatch>DENY</onMismatch> + </filter> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.location}/debug.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern> + %d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}|%X{RequestId}|%msg%n + </pattern> + </encoder> + </appender> + + <appender name="ASYNC_DEBUG" class="ch.qos.logback.classic.AsyncAppender"> + <appender-ref ref="DEBUG"/> + </appender> + + <appender name="AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <file>${log.location}/audit.log</file> + + <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> + <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"> + <marker>AUDIT</marker> + </evaluator> + <onMismatch>DENY</onMismatch> + <onMatch>ACCEPT</onMatch> + </filter> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.location}/audit.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern> + %X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{PartnerName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceId}|%level||%X{ServerIpAddress}|%X{ElapsedTime}|%X{Server}|%X{ClientIpAddress}||||||||%msg%n + </pattern> + </encoder> + </appender> + + <appender name="METRICS" class="ch.qos.logback.core.rolling.RollingFileAppender"> + + <file>${log.location}/metrics.log</file> + + <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> + <evaluator class="ch.qos.logback.classic.boolex.OnMarkerEvaluator"> + <marker>METRICS</marker> + </evaluator> + <onMismatch>DENY</onMismatch> + <onMatch>ACCEPT</onMatch> + </filter> + + <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> + <fileNamePattern>${log.location}/metrics.log.%i + </fileNamePattern> + <minIndex>1</minIndex> + <maxIndex>10</maxIndex> + </rollingPolicy> + + <triggeringPolicy + class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> + <maxFileSize>20MB</maxFileSize> + </triggeringPolicy> + + <encoder> + <pattern> + %X{BeginTimestamp}|%X{EndTimestamp}|%X{RequestId}|%X{ServiceInstanceId}|%thread||%X{ServiceName}|%X{TargetEntity}|%X{TargetServiceName}|%X{StatusCode}|%X{ResponseCode}|%X{ResponseDescription}|%X{InstanceId}|%level||%X{ServerIpAddress}|%X{ElapsedTime}|%X{Server}|%X{ClientIpAddress}||||||||||%msg%n + </pattern> + </encoder> + </appender> + + <logger name="org.openecomp" level="info" additivity="false"> + <appender-ref ref="ERROR"/> + <appender-ref ref="ASYNC_DEBUG"/> + <appender-ref ref="AUDIT"/> + <appender-ref ref="METRICS"/> + </logger> + + <logger name="org.onap" level="info" additivity="false"> + <appender-ref ref="ERROR"/> + <appender-ref ref="ASYNC_DEBUG"/> + <appender-ref ref="AUDIT"/> + <appender-ref ref="METRICS"/> + </logger> + + <!-- See https://docs.spring.io/spring-boot/docs/current/reference/html/howto-logging.html --> + <include resource="org/springframework/boot/logging/logback/defaults.xml" /> + <include resource="org/springframework/boot/logging/logback/console-appender.xml" /> + + <root level="error"> + <appender-ref ref="CONSOLE"/> + </root> + + <logger name="org.springframework.web" level="error"> + <appender-ref ref="CONSOLE"/> + </logger> + + <logger name="logging.level.org.hibernate" level="error"> + <appender-ref ref="CONSOLE"/> + </logger> + +</configuration>
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java new file mode 100644 index 00000000..d73d5d6f --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/RestPath.java @@ -0,0 +1,76 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow; + +import static org.onap.sdc.workflow.api.RestParams.LIMIT; +import static org.onap.sdc.workflow.api.RestParams.OFFSET; +import static org.onap.sdc.workflow.api.RestParams.SORT; + +public class RestPath { + + private RestPath() { + //Hiding implicit constructor + } + + private static final String WORKFLOWS_URL = "/wf/workflows"; + private static final String WORKFLOW_URL_FORMATTER = WORKFLOWS_URL + "/%s"; + private static final String ARCHIVE_URL_FORMATTER = WORKFLOWS_URL + "/%s/archiving"; + private static final String VERSIONS_URL_FORMATTER = WORKFLOWS_URL + "/%s/versions"; + private static final String VERSION_URL_FORMATTER = WORKFLOWS_URL + "/%s/versions/%s"; + private static final String SORT_QUERY_STRING_FORMATTER = SORT + "=%s"; + private static final String LIMIT_QUERY_STRING_FORMATTER = LIMIT + "=%s"; + private static final String OFFSET_QUERY_STRING_FORMATTER = OFFSET + "=%s"; + private static final String WORKFLOW_URL_FORMATTER_QUERY_PARAMS_ALL = + WORKFLOWS_URL + "?" + SORT_QUERY_STRING_FORMATTER+ "&" + LIMIT_QUERY_STRING_FORMATTER + "&" + + OFFSET_QUERY_STRING_FORMATTER; + private static final String WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_LIMIT = + WORKFLOWS_URL + "?" + OFFSET_QUERY_STRING_FORMATTER; + private static final String WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_OFFSET = + WORKFLOWS_URL + "?" + LIMIT_QUERY_STRING_FORMATTER; + + public static String getWorkflowsPathAllQueryParams(String sort, String limit, String offset) { + return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_ALL, sort, limit, offset); + } + + public static String getWorkflowsPathNoSortAndLimit(String offset) { + return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_LIMIT, offset); + } + + public static String getWorkflowsPathNoSortAndOffset(String limit) { + return String.format(WORKFLOW_URL_FORMATTER_QUERY_PARAMS_NO_SORT_AND_OFFSET, limit); + } + + public static String getWorkflowsPath() { + return WORKFLOWS_URL; + } + + public static String getWorkflowPath(String workflowId) { + return String.format(WORKFLOW_URL_FORMATTER, workflowId); + } + + public static String getArchiveWorkflowPath(String workflowId) { + return String.format(ARCHIVE_URL_FORMATTER, workflowId); + } + + public static String getWorkflowVersions(String workflowId) { + return String.format(VERSIONS_URL_FORMATTER, workflowId); + } + + public static String getWorkflowVersion(String workflowId, String versionId) { + return String.format(VERSION_URL_FORMATTER, workflowId, versionId); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java new file mode 100644 index 00000000..33cc0700 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/TestUtil.java @@ -0,0 +1,65 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow; + +import static org.onap.sdc.workflow.services.impl.ItemType.WORKFLOW; + +import org.onap.sdc.common.versioning.persistence.types.InternalItem; +import org.onap.sdc.common.versioning.persistence.types.InternalVersion; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.ItemStatus; + +public class TestUtil { + + public static Workflow createWorkflow(int workflowNum, boolean createId, ArchivingStatus archivingStatus) { + Workflow workflow = new Workflow(); + if (createId) { + workflow.setId(String.valueOf(workflowNum)); + } + workflow.setName("Workflow_" + workflowNum); + workflow.setDescription("Description_" + workflowNum); + workflow.setArchiving(archivingStatus); + + return workflow; + } + + public static Item createItem(int itemNum, boolean setType, boolean setId, ItemStatus archivingStatus) { + InternalItem item = new InternalItem(); + if (setId) { + item.setId(String.valueOf(itemNum)); + } + item.setName("Workflow_" + itemNum); + item.setDescription("Description_" + itemNum); + if (setType) { + item.setType(WORKFLOW.name()); + } + item.setStatus(archivingStatus); + return item; + } + + public static InternalVersion createRetrievedVersion(String id, VersionStatus status) { + InternalVersion version = new InternalVersion(); + version.setId(id); + version.setStatus(status); + return version; + } + + +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ArtifactAssociationHandlerTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ArtifactAssociationHandlerTest.java new file mode 100644 index 00000000..b4d1180b --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ArtifactAssociationHandlerTest.java @@ -0,0 +1,124 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static junit.framework.TestCase.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import java.io.IOException; +import java.io.InputStream; +import org.apache.commons.io.IOUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mockito; +import org.onap.sdc.workflow.api.types.dto.ArtifactDeliveriesRequestDto; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.web.client.RestTemplate; + + +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration( + classes = {ArtifactAssociationHandlerTest.RestBuilderMockProvider.class, ArtifactAssociationService.class}) +@TestPropertySource(locations = "classpath:application-test.properties") +@Component("ArtifactAssociationHandlerTest") +public class ArtifactAssociationHandlerTest { + + @Configuration + static class RestBuilderMockProvider { + + @Bean + public RestTemplateBuilder templateBuilder() { + return Mockito.mock(RestTemplateBuilder.class); + } + + @Bean + public RestTemplate restTemplate() { + return Mockito.mock(RestTemplate.class); + } + } + + private static final String FILE_NAME = "fileName.txt"; + private static final String USER_ID = "cs0008"; + private static final String END_POINT = + "sdc/v1/catalog/resources/46434d20-40f6-4a5f-a0c4-8c1da6791bdb/interfaces/137a0264-47a5-4dab-b79d-cfdd8cd9a9a1/artifacts/ef82dec9-cb99-48a3-aaba-5ae832417dc5"; + private final String EROR_MSG = + "Failed while attaching workflow artifact to Operation in SDC. Parameters were not initialized: [SDC_ENDPOINT]"; + private InputStream inputStreamMock; + private ArtifactEntity artifactMock; + private ArtifactDeliveriesRequestDto requestDto; + @Value("${sdc.be.endpoint}") + private String sdcBeEndpoint; + @Value("${sdc.be.protocol}") + private String sdcBeProtocol; + @Value("${sdc.be.external.user}") + private String sdcUser; + @Value("${sdc.be.external.password}") + private String sdcPassword; + + @Autowired + private RestTemplate restClientMock; + + + @Autowired + private ArtifactAssociationService associationService; + + @Before + public void setUp() throws IOException { + inputStreamMock = IOUtils.toInputStream("some test data for my input stream", "UTF-8"); + artifactMock = new ArtifactEntity(FILE_NAME, inputStreamMock); + requestDto = new ArtifactDeliveriesRequestDto("POST", END_POINT); + associationService.setRestClient(restClientMock); + } + + + @Test + public void shouldGetResponseStatusOk() { + ResponseEntity<String> responseEntity = new ResponseEntity(HttpStatus.OK); + when(restClientMock.exchange(eq(sdcBeProtocol + "://" + sdcBeEndpoint + "/" + requestDto.getEndpoint()), + eq(HttpMethod.POST), any(HttpEntity.class), eq(String.class))).thenReturn(responseEntity); + + ResponseEntity<String> response = associationService.execute(USER_ID, requestDto, artifactMock); + assertEquals(200, response.getStatusCode().value()); + + } + + + @Test + public void shouldReturnStatusFailWhenNoParametersInitialized() { + associationService.setSdcBeEndpoint(null); + ResponseEntity<String> response = associationService.execute(USER_ID, requestDto, artifactMock); + assertEquals(417, response.getStatusCode().value()); + assertEquals(EROR_MSG, response.getBody()); + } + +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java new file mode 100644 index 00000000..ee924007 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/ExceptionsHandlerTest.java @@ -0,0 +1,83 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR; +import static org.springframework.http.HttpStatus.NOT_FOUND; +import static org.springframework.http.HttpStatus.UNPROCESSABLE_ENTITY; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.onap.sdc.workflow.api.types.ErrorResponse; +import org.onap.sdc.workflow.api.types.UnexpectedErrorResponse; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.VersionModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ExceptionsHandlerTest { + + @InjectMocks + private ExceptionsHandler exceptionsHandler; + + @Test + public void handleNotFoundException() { + EntityNotFoundException exception = new EntityNotFoundException("message"); + ResponseEntity<ErrorResponse> response = exceptionsHandler.handleNotFoundException(exception); + + assertEquals(NOT_FOUND, response.getStatusCode()); + assertEquals(exception.getMessage(), response.getBody().getMessage()); + } + + @Test + public void handleUnprocessableEntityException() { + VersionModificationException exception = new VersionModificationException("1", "2"); + ResponseEntity<ErrorResponse> response = exceptionsHandler.handleUnprocessableEntityException(exception); + + assertEquals(UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals(exception.getMessage(), response.getBody().getMessage()); + } + + @Test + public void handleUnprocessableEntityVersionStateModificationMissingArtifactException() { + VersionStateModificationMissingArtifactException exception = + new VersionStateModificationMissingArtifactException("WF_ID", "Version_id", + WorkflowVersionState.DRAFT, WorkflowVersionState.CERTIFIED); + ResponseEntity<ErrorResponse> response = exceptionsHandler.handleUnprocessableEntityException(exception); + + assertEquals(UNPROCESSABLE_ENTITY, response.getStatusCode()); + assertEquals(exception.getMessage(), response.getBody().getMessage()); + } + + @Test + public void handleUnexpectedException() { + Exception exception = new Exception("message"); + ResponseEntity<UnexpectedErrorResponse> response = exceptionsHandler.handleUnexpectedException(exception); + + assertEquals(INTERNAL_SERVER_ERROR, response.getStatusCode()); + assertNotNull(response.getBody().getMessage()); + assertFalse(response.getBody().getMessage().contains(exception.getMessage())); + assertNotNull(response.getBody().getDevInfo()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java new file mode 100644 index 00000000..5e0f61d0 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowControllerTest.java @@ -0,0 +1,311 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.sdc.workflow.api; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.onap.sdc.workflow.TestUtil.createWorkflow; +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET; +import static org.onap.sdc.workflow.services.types.WorkflowValidationConstants.MAX_LENGTH; +import static org.onap.sdc.workflow.services.types.WorkflowValidationConstants.MIN_LENGTH; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import com.amdocs.zusammen.datatypes.Id; +import com.amdocs.zusammen.datatypes.item.Item; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.workflow.RestPath; +import org.onap.sdc.workflow.server.resolvers.UserIdResolver; +import org.onap.sdc.workflow.services.WorkflowManager; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.PagingRequest; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.Sort; +import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.utilities.JsonUtil; +import org.springframework.data.web.PageableHandlerMethodArgumentResolver; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +@RunWith(MockitoJUnitRunner.class) +public class WorkflowControllerTest { + + private static final String USER_ID = "userId"; + private static final String MISSING_USER_HEADER_ERROR = "Missing mandatory request header 'USER_ID'"; + private static final String DEFAULT_SORT_VALUE = "name:asc"; + + private MockMvc mockMvc; + + @Mock + private WorkflowManager workflowManagerMock; + @Captor + private ArgumentCaptor<RequestSpec> requestSpecArg; + @InjectMocks + private WorkflowController workflowController; + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.standaloneSetup(workflowController) + .setCustomArgumentResolvers(new PageableHandlerMethodArgumentResolver()) + .setCustomArgumentResolvers(new UserIdResolver()) + .setControllerAdvice(new ExceptionsHandler()).build(); + } + + @Test + public void shouldReturnErrorWhenMissingUserIdInGetReqHeader() throws Exception { + Workflow workflowMock = createWorkflow(1, true, ArchivingStatus.ACTIVE); + mockMvc.perform(get(RestPath.getWorkflowPath(workflowMock.getId())).contentType(APPLICATION_JSON)) + .andExpect(status().isBadRequest()).andExpect(jsonPath("$.message", is(MISSING_USER_HEADER_ERROR))); + } + + @Test + public void shouldReturnWorkflowDataWhenRequestPathIsOk() throws Exception { + Workflow workflowMock = createWorkflow(1, true, ArchivingStatus.ACTIVE); + doReturn(workflowMock).when(workflowManagerMock).get(any(Workflow.class)); + mockMvc.perform(get(RestPath.getWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.id", is(workflowMock.getId()))) + .andExpect(jsonPath("$.name", is(workflowMock.getName()))); + } + + @Test + public void shouldReturnErrorWhenMissingUserIdInListReqHeader() throws Exception { + mockMvc.perform(get(RestPath.getWorkflowsPath()).contentType(APPLICATION_JSON)) + .andExpect(status().isBadRequest()).andExpect(jsonPath("$.message", is(MISSING_USER_HEADER_ERROR))); + } + + @Test + public void shouldReturnOkWhenArchivingWorkflow() throws Exception { + Workflow workflowMock = createWorkflow(1, true, ArchivingStatus.ACTIVE); + mockMvc.perform(post(RestPath.getArchiveWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON) + .content( + "{\"status\": \"ARCHIVED\"}")) + .andExpect(status().isOk()); + verify(workflowManagerMock).updateStatus(workflowMock.getId(), ArchivingStatus.ARCHIVED); + } + + @Test + public void shouldReturnOkWhenRestoringWorkflow() throws Exception { + Workflow workflowMock = createWorkflow(1, true, ArchivingStatus.ACTIVE); + mockMvc.perform(post(RestPath.getArchiveWorkflowPath(workflowMock.getId())).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON) + .content("{\"status\": \"ACTIVE\"}")) + .andExpect(status().isOk()); + verify(workflowManagerMock).updateStatus(workflowMock.getId(), ArchivingStatus.ACTIVE); + } + + @Test + public void listWhenExist() throws Exception { + mockManagerList3(); + ResultActions result = mockMvc.perform( + get(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); + for (int i = 0; i < 3; i++) { + result.andExpect(jsonPath(String.format("$.items[%s].id", i), is(String.valueOf(i + 1)))); + } + + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, DEFAULT_LIMIT, Collections.emptyList()); + } + + @Test + public void listWhenPagingAndSortingAreSet() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "1")) + .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), 1, 2, + Collections.singletonList(new Sort("name", true))); + } + + @Test + public void shouldReturnResultsWithDefaultWhenLimitIsNegative() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "-2", "1")) + .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT, + Collections.singletonList(new Sort("name", true))); + } + + @Test + public void shouldFallbackOnDefaultOffsetWhenOffsetIsNegative() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "-1")) + .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2, + Collections.singletonList(new Sort("name", true))); + } + + @Test + public void shouldFallbackOnDefaultLimitWhenLimitIsNotAnInteger() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "abc", "0")) + .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), 0, DEFAULT_LIMIT, + Collections.singletonList(new Sort("name", true))); + } + + @Test + public void shouldFallbackOnDefaultOffsetWhenOffsetIsNotAnInteger() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathAllQueryParams(DEFAULT_SORT_VALUE, "2", "abc")) + .header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON)) + .andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 2, + Collections.singletonList(new Sort("name", true))); + } + + @Test + public void shouldReturnDefaultLimitOffsetAppliedWorkflowsWhenLimitIsNotSpecified() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndLimit("1")).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON)) + .andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), 1, DEFAULT_LIMIT, Collections.emptyList()); + } + + @Test + public void shouldReturnDefaultOffsetAppliedWorkflowsWhenOffsetIsNotSpecified() throws Exception { + mockManagerList3(); + mockMvc.perform(get(RestPath.getWorkflowsPathNoSortAndOffset("1")).header(USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON)) + .andExpect(status().isOk()).andExpect(jsonPath("$.items", hasSize(3))); + verify(workflowManagerMock).list(any(), any(), any(), requestSpecArg.capture()); + assertRequestSpec(requestSpecArg.getValue(), DEFAULT_OFFSET, 1, Collections.emptyList()); + } + + @Test + public void shouldCreateWorkflowWhenCallingPostRestRequest() throws Exception { + Item item = new Item(); + item.setId(new Id("abc")); + Workflow reqWorkflow = createWorkflow(1, false, any()); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isCreated()); + verify(workflowManagerMock).create(reqWorkflow); + } + + @Test + public void shouldThrowExceptionWhenWorkflowNameInvalid() throws Exception { + Workflow reqWorkflow = new Workflow(); + reqWorkflow.setName("Invalid workflow name %"); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isBadRequest()).andExpect( + jsonPath("$.message", is("Workflow name must contain only letters, digits and underscores."))); + } + + @Test + public void shouldThrowExceptionWhenWorkflowNameBlank() throws Exception { + Workflow reqWorkflow = new Workflow(); + reqWorkflow.setName(" "); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldThrowExceptionWhenWorkflowNameNull() throws Exception { + Workflow reqWorkflow = new Workflow(); + reqWorkflow.setName(null); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldThrowExceptionWhenWorkflowNameEmptyString() throws Exception { + Workflow reqWorkflow = new Workflow(); + reqWorkflow.setName(""); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldThrowExceptionWhenWorkflowNameMoreThanMax() throws Exception { + Workflow reqWorkflow = new Workflow(); + reqWorkflow.setName("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isBadRequest()).andExpect(jsonPath("$.message", + is("Workflow name must be at least " + MIN_LENGTH + " characters, and no more than " + MAX_LENGTH + + " characters."))); + } + + @Test + public void shouldThrowExceptionWhenWorkflowNameLessThanMin() throws Exception { + Workflow reqWorkflow = new Workflow(); + reqWorkflow.setName("AAA"); + mockMvc.perform(post(RestPath.getWorkflowsPath()).header(USER_ID_HEADER, USER_ID).contentType(APPLICATION_JSON) + .content(JsonUtil.object2Json(reqWorkflow))) + .andExpect(status().isBadRequest()).andExpect(jsonPath("$.message", + is("Workflow name must be at least " + MIN_LENGTH + " characters, and no more than " + MAX_LENGTH + + " characters."))); + } + + private void mockManagerList3() { + doReturn(new Page<>(Arrays.asList(createWorkflow(1, true, ArchivingStatus.ACTIVE), + createWorkflow(2, true, ArchivingStatus.ACTIVE), createWorkflow(3, true, ArchivingStatus.ACTIVE)), + new PagingRequest(DEFAULT_OFFSET, DEFAULT_LIMIT), 3)).when(workflowManagerMock) + .list(any(), any(), any(), any()); + } + + private static void assertRequestSpec(RequestSpec actual, int expectedOffset, int expectedLimit, + List<Sort> expectedSorts) { + assertEquals(Integer.valueOf(expectedOffset), actual.getPaging().getOffset()); + assertEquals(Integer.valueOf(expectedLimit), actual.getPaging().getLimit()); + if (expectedSorts.isEmpty()) { + assertEquals(expectedSorts, actual.getSorting().getSorts()); + } else { + for (int i = 0; i < expectedSorts.size(); i++) { + assertEquals(expectedSorts.get(i), actual.getSorting().getSorts().get(i)); + } + } + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java new file mode 100644 index 00000000..a8813c05 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/WorkflowVersionControllerTest.java @@ -0,0 +1,165 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api; + +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.springframework.http.MediaType.APPLICATION_JSON; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.util.Arrays; +import java.util.Collection; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.workflow.RestPath; +import org.onap.sdc.workflow.api.mappers.WorkflowVersionDtoMapper; +import org.onap.sdc.workflow.api.types.Parameter; +import org.onap.sdc.workflow.api.types.WorkflowVersionRequest; +import org.onap.sdc.workflow.api.types.WorkflowVersionResponse; +import org.onap.sdc.workflow.persistence.types.ParameterType; +import org.onap.sdc.workflow.services.WorkflowVersionManager; +import org.onap.sdc.workflow.services.types.WorkflowVersion; +import org.onap.sdc.workflow.services.utilities.JsonUtil; +import org.springframework.http.HttpStatus; +import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +@RunWith(MockitoJUnitRunner.class) +public class WorkflowVersionControllerTest { + + private static final String USER_ID = "cs0008"; + private static final String ITEM1_ID = "item_id_1"; + private static final String VERSION1_ID = "version_id_1"; + private static final String VERSION2_ID = "version_id_2"; + + private MockMvc mockMvc; + + @Mock + private WorkflowVersionManager workflowVersionManagerMock; + @Mock + private WorkflowVersionDtoMapper versionDtoMapperMock; + @InjectMocks + private WorkflowVersionController workflowVersionController; + + @Before + public void setUp() { + mockMvc = MockMvcBuilders.standaloneSetup(workflowVersionController).build(); + } + + @Test + public void shouldReturnWorkflowVersionListWhenCallingVersionGetREST() throws Exception { + WorkflowVersion version1 = new WorkflowVersion(VERSION1_ID); + WorkflowVersion version2 = new WorkflowVersion(VERSION2_ID); + doReturn(Arrays.asList(version1, version2)).when(workflowVersionManagerMock).list(ITEM1_ID, null); + + WorkflowVersionResponse response1 = new WorkflowVersionResponse(); + response1.setId(VERSION1_ID); + doReturn(response1).when(versionDtoMapperMock).workflowVersionToResponse(version1); + WorkflowVersionResponse response2 = new WorkflowVersionResponse(); + response2.setId(VERSION2_ID); + doReturn(response2).when(versionDtoMapperMock).workflowVersionToResponse(version2); + + mockMvc.perform(get(RestPath.getWorkflowVersions(ITEM1_ID)).header(RestParams.USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON)).andExpect(status().isOk()) + .andExpect(jsonPath("$.items", hasSize(2))).andExpect(jsonPath("$.items[0].id", is(VERSION1_ID))) + .andExpect(jsonPath("$.items[1].id", is(VERSION2_ID))); + + verify(workflowVersionManagerMock).list(ITEM1_ID, null); + } + + @Test + public void shouldCreateWorkflowVersionWhenCallingVersionsPostREST() throws Exception { + + WorkflowVersionRequest request = new WorkflowVersionRequest(); + request.setDescription("Updated"); + WorkflowVersion version = new WorkflowVersion(); + version.setDescription("Updated"); + doReturn(version).when(versionDtoMapperMock).requestToWorkflowVersion(request); + + mockMvc.perform(post(RestPath.getWorkflowVersions(ITEM1_ID)).header(RestParams.USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON).content(JsonUtil.object2Json(request))) + .andExpect(status().isCreated()); + + verify(workflowVersionManagerMock).create(ITEM1_ID, null, version); + } + + @Test + public void shouldFailCreateWorkflowVersionWhenCallingVersionsPostRESTWithDuplicateInput() throws Exception { + + WorkflowVersionRequest version = new WorkflowVersionRequest(); + Collection<Parameter> inputs = Arrays.asList(createParameter("name1"), createParameter("name1")); + version.setInputs(inputs); + version.setDescription("VersionDescription"); + mockMvc.perform(post(RestPath.getWorkflowVersions(ITEM1_ID)).header(RestParams.USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON).content(JsonUtil.object2Json(version))) + .andExpect(status().isBadRequest()); + } + + @Test + public void shouldReturnWorkflowVersionWhenExists() throws Exception { + WorkflowVersion version = new WorkflowVersion(VERSION1_ID); + doReturn(version).when(workflowVersionManagerMock).get(ITEM1_ID, VERSION1_ID); + WorkflowVersionResponse response = new WorkflowVersionResponse(); + response.setId(VERSION1_ID); + doReturn(response).when(versionDtoMapperMock).workflowVersionToResponse(version); + + mockMvc.perform( + get(RestPath.getWorkflowVersion(ITEM1_ID, VERSION1_ID)).header(RestParams.USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON)).andExpect(status().isOk()) + .andExpect(jsonPath("$.id", is(VERSION1_ID))); + verify(workflowVersionManagerMock).get(ITEM1_ID, VERSION1_ID); + } + + @Test + public void shouldUpdateWorkflowVersionWhenCallingPutREST() throws Exception { + WorkflowVersionRequest request = new WorkflowVersionRequest(); + request.setDescription("Updated"); + WorkflowVersion version = new WorkflowVersion(); + version.setDescription("Updated"); + doReturn(version).when(versionDtoMapperMock).requestToWorkflowVersion(request); + + MockHttpServletResponse result = mockMvc.perform( + put(RestPath.getWorkflowVersion(ITEM1_ID, VERSION1_ID)).header(RestParams.USER_ID_HEADER, USER_ID) + .contentType(APPLICATION_JSON).content(JsonUtil.object2Json(request))).andReturn() + .getResponse(); + + assertEquals(HttpStatus.OK.value(), result.getStatus()); + + verify(workflowVersionManagerMock).update(ITEM1_ID, version); + } + + private Parameter createParameter(String name) { + Parameter parameter = new Parameter(); + parameter.setName(name); + parameter.setMandatory(false); + parameter.setType(ParameterType.STRING); + return parameter; + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/swagger/UserIdReaderTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/swagger/UserIdReaderTest.java new file mode 100644 index 00000000..6899e984 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/swagger/UserIdReaderTest.java @@ -0,0 +1,81 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.swagger; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.fasterxml.classmate.TypeResolver; +import com.google.common.base.Optional; +import java.lang.annotation.Annotation; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.onap.sdc.workflow.services.annotations.UserId; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.service.ResolvedMethodParameter; +import springfox.documentation.spi.service.contexts.ParameterContext; + +@RunWith(SpringJUnit4ClassRunner.class) +public class UserIdReaderTest { + + private static final UserId USER_ID_ANNOTATION = new UserId() { + + @Override + public Class<? extends Annotation> annotationType() { + return UserId.class; + } + }; + + @Mock + TypeResolver resolver; // do not delete. this is used in the injection of UserIdReader constructor + @Mock + ResolvedMethodParameter resolvedMethodParameter; + @Mock + ParameterBuilder parameterBuilder; + @Mock + ParameterContext parameterContext; + @InjectMocks + UserIdReader userIdReader; + + @Test + public void shouldNotCallToParameterBuilderIfUserIdAnnotationNotFound() { + when(parameterContext.resolvedMethodParameter()).thenReturn(resolvedMethodParameter); + when(resolvedMethodParameter.findAnnotation(UserId.class)).thenReturn(Optional.absent()); + userIdReader.apply(parameterContext); + verify(parameterContext, times(0)).parameterBuilder(); + } + + @Test + public void shouldCallToParameterBuilderIfUserIdAnnotationFound() { + + doReturn(resolvedMethodParameter).when(parameterContext).resolvedMethodParameter(); + doReturn(parameterBuilder).when(parameterContext).parameterBuilder(); + doReturn(parameterBuilder).when(parameterBuilder).parameterType(any()); + doReturn(parameterBuilder).when(parameterBuilder).name(any()); + doReturn(parameterBuilder).when(parameterBuilder).type(any()); + doReturn(Optional.of(USER_ID_ANNOTATION)).when(resolvedMethodParameter).findAnnotation(UserId.class); + + userIdReader.apply(parameterContext); + verify(parameterContext, times(1)).parameterBuilder(); + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/PagingTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/PagingTest.java new file mode 100644 index 00000000..a0392eb5 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/PagingTest.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class PagingTest { + + @InjectMocks + private Paging paging; + + @Test + public void setOffsetNotNumber() { + paging.setOffset("aaa"); + assertNull(paging.getOffset()); + } + + @Test + public void setOffsetNegative() { + paging.setOffset("-5"); + assertNull(paging.getOffset()); + } + + @Test + public void setOffsetZero() { + paging.setOffset("0"); + assertEquals(Integer.valueOf(0), paging.getOffset()); + } + + @Test + public void setOffsetPositive() { + paging.setOffset("8"); + assertEquals(Integer.valueOf(8), paging.getOffset()); + } + + @Test + public void setLimitNotNumber() { + paging.setLimit("aaa"); + assertNull(paging.getLimit()); + } + + @Test + public void setLimitNegative() { + paging.setLimit("-5"); + assertNull(paging.getLimit()); + } + + @Test + public void setLimitZero() { + paging.setLimit("0"); + assertNull(paging.getLimit()); + } + + @Test + public void setLimitPositive() { + paging.setLimit("8"); + assertEquals(Integer.valueOf(8), paging.getLimit()); + } + + @Test + public void setLimitGreaterThanMax() { + paging.setLimit("7000"); + assertEquals(Integer.valueOf(MAX_LIMIT), paging.getLimit()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/SortingTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/SortingTest.java new file mode 100644 index 00000000..9cd95a5d --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/SortingTest.java @@ -0,0 +1,67 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.Collections; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.onap.sdc.workflow.services.types.Sort; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class SortingTest { + + @InjectMocks + private Sorting sorting; + + @Test + public void setSortInvalid() { + sorting.setSort("name:asc:a,:,"); + assertEquals(Collections.emptyList(), sorting.getSorts()); + } + + @Test + public void setSortAscByDefault() { + sorting.setSort("name"); + assertEquals(Collections.singletonList(new Sort("name", true)), sorting.getSorts()); + } + + @Test + public void setSortAsc() { + sorting.setSort("name:asc"); + assertEquals(Collections.singletonList(new Sort("name", true)), sorting.getSorts()); + } + + @Test + public void setSortDesc() { + sorting.setSort("name:desc"); + assertEquals(Collections.singletonList(new Sort("name", false)), sorting.getSorts()); + } + + @Test + public void setSortMoreThanOne() { + sorting.setSort("name:asc,type,date:desc"); + assertEquals(Arrays.asList( + new Sort("name", true), + new Sort("type", true), + new Sort("date", false)), sorting.getSorts()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/VersionStatesFormatterTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/VersionStatesFormatterTest.java new file mode 100644 index 00000000..294577fe --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/types/VersionStatesFormatterTest.java @@ -0,0 +1,61 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.types; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.onap.sdc.workflow.services.types.WorkflowVersionState.CERTIFIED; +import static org.onap.sdc.workflow.services.types.WorkflowVersionState.DRAFT; + +import java.util.Collections; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class VersionStatesFormatterTest { + + @InjectMocks + private VersionStatesFormatter versionStateSet; + + @Test + public void setVersionStateInvalid() { + versionStateSet.setVersionState(",,a"); + assertEquals(Collections.emptySet() ,versionStateSet.getVersionStates()); + } + + @Test + public void setVersionStateDraft() { + versionStateSet.setVersionState("DRAFT"); + assertEquals(Collections.singleton(DRAFT), versionStateSet.getVersionStates()); + } + + @Test + public void setVersionStateCertified() { + versionStateSet.setVersionState("CERTIFIED"); + assertEquals(Collections.singleton(CERTIFIED), versionStateSet.getVersionStates()); + } + + @Test + public void setVersionStateBoth() { + versionStateSet.setVersionState("DRAFT,CERTIFIED"); + assertEquals(Stream.of(DRAFT, CERTIFIED).collect(Collectors.toSet()), versionStateSet.getVersionStates()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/ActivitySpecParameterNameValidatorTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/ActivitySpecParameterNameValidatorTest.java new file mode 100644 index 00000000..75fb5a29 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/ActivitySpecParameterNameValidatorTest.java @@ -0,0 +1,128 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import javax.validation.ConstraintValidatorContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.sdc.workflow.persistence.types.ActivitySpecParameter; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ActivitySpecParameterNameValidatorTest { + + class AnnotationWrapper { + + @ValidName(message = "test message") + public ActivitySpecParameter parameter; + } + + private String noSpacesMessage = "Input and output names must not contain any spaces"; + private String matchPatternMessage = "Input and output names must match the validation pattern"; + + @Mock + private ConstraintValidatorContext context; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder constraintViolationBuilder; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext nodeBuilderCustomizableContext; + + private ActivitySpecParameterNameValidator validator; + + + @Before + public void setup() throws NoSuchFieldException { + MockitoAnnotations.initMocks(this); + when(context.buildConstraintViolationWithTemplate(anyString())).thenReturn(constraintViolationBuilder); + when(constraintViolationBuilder.addPropertyNode(anyString())).thenReturn(nodeBuilderCustomizableContext); + validator = initializeValidator(ActivitySpecParameterNameValidatorTest.AnnotationWrapper.class); + } + + @Test + public void shouldPassIfNoSpaces() { + validator.setValidationRegex("^\\S*$"); + assertTrue(validator.isValid(createParameter("validName"), context)); + } + + @Test + public void shouldFailIfNameHasSpaces() { + validator.setValidationRegex("^\\S*$"); + validator.setValidationMessage(noSpacesMessage); + assertFalse(validator.isValid(createParameter("not a valid name"), context)); + verify(context).disableDefaultConstraintViolation(); + verify(context).buildConstraintViolationWithTemplate(noSpacesMessage); + } + + + @Test + public void shouldFailIfNameHasSpacesInStart() { + validator.setValidationRegex("^\\S*$"); + validator.setValidationMessage(noSpacesMessage); + assertFalse(validator.isValid(createParameter(" name"), context)); + verify(context).disableDefaultConstraintViolation(); + verify(context).buildConstraintViolationWithTemplate(noSpacesMessage); + } + + @Test + public void shouldFailIfNameHasSpacesInEnd() { + validator.setValidationRegex("^\\S*$"); + validator.setValidationMessage(noSpacesMessage); + assertFalse(validator.isValid(createParameter("name "), context)); + verify(context).disableDefaultConstraintViolation(); + verify(context).buildConstraintViolationWithTemplate(noSpacesMessage); + } + + @Test + public void shouldFailIfDoesNotMatchRegex() { + validator.setValidationRegex("^[a-zA-Z0-9-]*$"); + validator.setValidationMessage(matchPatternMessage); + assertFalse(validator.isValid(createParameter("NotValid$$##"), context)); + verify(context).disableDefaultConstraintViolation(); + verify(context).buildConstraintViolationWithTemplate(matchPatternMessage); + } + + @Test + public void shouldPassIfMatchRegex() { + validator.setValidationRegex("^[a-zA-Z0-9-]*$"); + assertTrue(validator.isValid(createParameter("validName"), context)); + } + + private ActivitySpecParameterNameValidator initializeValidator(Class<?> classWithAnnotation) + throws NoSuchFieldException { + ValidName constraint = classWithAnnotation.getField("parameter").getAnnotation(ValidName.class); + ActivitySpecParameterNameValidator validator = new ActivitySpecParameterNameValidator(); + validator.initialize(constraint); + return validator; + } + + private ActivitySpecParameter createParameter(String name) { + ActivitySpecParameter parameter = new ActivitySpecParameter(); + parameter.setName(name); + parameter.setValue("value"); + parameter.setType("type"); + return parameter; + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/ArchivingStatusValidatorTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/ArchivingStatusValidatorTest.java new file mode 100644 index 00000000..d5e5f20d --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/ArchivingStatusValidatorTest.java @@ -0,0 +1,91 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import javax.validation.ConstraintValidatorContext; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class ArchivingStatusValidatorTest { + + class AnnotationWrapper { + + @ValidName(message = "test message") + public String status; + } + + @Mock + private ConstraintValidatorContext context; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder constraintViolationBuilder; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext nodeBuilderCustomizableContext; + + private ArchivingStatusValidator validator; + + @Before + public void setup() throws NoSuchFieldException { + MockitoAnnotations.initMocks(this); + when(context.buildConstraintViolationWithTemplate(anyString())).thenReturn(constraintViolationBuilder); + when(constraintViolationBuilder.addPropertyNode(anyString())).thenReturn(nodeBuilderCustomizableContext); + validator = initializeValidator(ArchivingStatusValidatorTest.AnnotationWrapper.class); + } + + @Test + public void shouldFailIfValueIsNull() { + assertFalse(validator.isValid(null, context)); + } + + @Test + public void shouldFailIfValueInvalid() { + assertFalse(validator.isValid("blahblah", context)); + } + + @Test + public void shouldPassIfValueIsActive() { + assertTrue(validator.isValid("ACTIVE", context)); + } + + @Test + public void shouldPassIfValueIsArchived() { + assertTrue(validator.isValid("ARCHIVED", context)); + } + + + + + private ArchivingStatusValidator initializeValidator(Class<?> classWithAnnotation) + throws NoSuchFieldException { + ValidStatus constraint = classWithAnnotation.getField("status").getAnnotation(ValidStatus.class); + ArchivingStatusValidator validator = new ArchivingStatusValidator(); + validator.initialize(constraint); + return validator; + } + + +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/NoDuplicatesValidatorTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/NoDuplicatesValidatorTest.java new file mode 100644 index 00000000..f8f6b743 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/api/validation/NoDuplicatesValidatorTest.java @@ -0,0 +1,104 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.api.validation; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import javax.validation.ConstraintValidatorContext; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.sdc.workflow.api.types.Parameter; + +public class NoDuplicatesValidatorTest { + + class AnnotationWrapper { + + @NoDuplicates(message = "test message") + public Collection<Parameter> collection; + } + + private NoDuplicatesValidator noDuplicatesValidator; + + @Mock + private ConstraintValidatorContext context; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder constraintViolationBuilder; + @Mock + private ConstraintValidatorContext.ConstraintViolationBuilder.NodeBuilderCustomizableContext + nodeBuilderCustomizableContext; + + @Before + public void init() throws NoSuchFieldException { + MockitoAnnotations.initMocks(this); + when(context.buildConstraintViolationWithTemplate(anyString())).thenReturn(constraintViolationBuilder); + when(constraintViolationBuilder.addPropertyNode(anyString())).thenReturn(nodeBuilderCustomizableContext); + noDuplicatesValidator = initializeValidator(AnnotationWrapper.class); + } + + @Test + public void shouldFailIfCollectionHaveMoreThen1ParameterEntityWithSameName() { + Collection<Parameter> inputs = Arrays.asList(createParameter("name1"), createParameter("name1")); + + assertFalse(noDuplicatesValidator.isValid(inputs, context)); + } + + @Test + public void shouldPassIfCollectionDontHaveMoreThen1ParameterEntityWithSameName() { + Collection<Parameter> inputs = Arrays.asList(createParameter("name2"), createParameter("name1")); + + assertTrue(noDuplicatesValidator.isValid(inputs, context)); + } + + @Test + public void shouldPassIfCollectionContainsOnlyOneObject() { + Collection<Parameter> inputs = Collections.singletonList(createParameter("name2")); + + assertTrue(noDuplicatesValidator.isValid(inputs, context)); + } + + @Test + public void shouldPassIfCollectionIsNull() { + assertTrue(noDuplicatesValidator.isValid(null, context)); + } + + @Test + public void shouldPassIfCollectionIsEmpty() { + assertTrue(noDuplicatesValidator.isValid(new ArrayList<>(), context)); + } + + private NoDuplicatesValidator initializeValidator(Class<?> classWithAnnotation) throws NoSuchFieldException { + NoDuplicates constraint = classWithAnnotation.getField("collection").getAnnotation(NoDuplicates.class); + NoDuplicatesValidator validator = new NoDuplicatesValidator(); + validator.initialize(constraint); + return validator; + } + + private Parameter createParameter(String name) { + Parameter parameter = new Parameter(); + parameter.setName(name); + return parameter; + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ActivitySpecRepositoryImplTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ActivitySpecRepositoryImplTest.java new file mode 100644 index 00000000..e69d4984 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ActivitySpecRepositoryImplTest.java @@ -0,0 +1,180 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.ELEMENT_TYPE_PROPERTY; + +import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement; +import com.amdocs.zusammen.datatypes.Id; +import com.amdocs.zusammen.datatypes.item.Action; +import com.amdocs.zusammen.datatypes.item.ElementContext; +import com.amdocs.zusammen.datatypes.item.Info; +import com.amdocs.zusammen.datatypes.item.ItemVersion; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.common.versioning.persistence.zusammen.ZusammenSessionContextCreator; +import org.onap.sdc.common.zusammen.services.ZusammenAdaptor; +import org.onap.sdc.workflow.persistence.impl.ActivitySpecRepositoryImpl.InfoPropertyName; +import org.onap.sdc.workflow.persistence.impl.types.ActivitySpecData; +import org.onap.sdc.workflow.persistence.impl.types.ActivitySpecElementType; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; +import org.onap.sdc.workflow.persistence.types.ActivitySpecParameter; +import org.onap.sdc.workflow.services.utilities.JsonUtil; + +@RunWith(MockitoJUnitRunner.class) +public class ActivitySpecRepositoryImplTest { + + private static final String versionId = "1234"; + private static final String itemId = "5678"; + + @Mock + private ZusammenAdaptor zusammenAdaptor; + @Mock + private ZusammenSessionContextCreator contextCreator; + @InjectMocks + private ActivitySpecRepositoryImpl daoImpl; + + private ActivitySpecEntity entity; + private final Map<String, Element> elementMap = new HashMap<>(); + private String elementId; + + @Before + public void setUp() { + daoImpl = new ActivitySpecRepositoryImpl(zusammenAdaptor, contextCreator); + entity = new ActivitySpecEntity(); + entity = new ActivitySpecEntity(); + + entity.setId(itemId); + entity.setVersionId(versionId); + entity.setName("activitySpec"); + List<String> categoryList = new ArrayList<>(); + categoryList.add("category1"); + entity.setCategoryList(categoryList); + ActivitySpecParameter inputParams = new ActivitySpecParameter("dbhost", "String", null); + inputParams.setValue("localhost"); + List<ActivitySpecParameter> inputs = new ArrayList<>(); + inputs.add(inputParams); + entity.setInputs(inputs); + + + mockZusammenAdapter(); + } + + @Test + public void testCreate() { + ItemVersion itemVersionmock = new ItemVersion(); + itemVersionmock.setId(new Id()); + + daoImpl.create(entity); + ElementContext elementContext = new ElementContext(entity.getId(), entity.getVersionId()); + Optional<ElementInfo> testElementInfo = zusammenAdaptor + .getElementInfoByName(contextCreator.create(), elementContext, + Id.ZERO, ActivitySpecElementType.ACTIVITYSPEC.name()); + Assert.assertTrue(testElementInfo.isPresent()); + Assert.assertEquals(testElementInfo.get().getInfo().getName(), ActivitySpecElementType.ACTIVITYSPEC.name()); + Assert.assertEquals(testElementInfo.get().getInfo() + .getProperty(ActivitySpecRepositoryImpl.InfoPropertyName.DESCRIPTION.getValue()), + entity.getDescription()); + Assert.assertEquals(testElementInfo.get().getInfo().getProperty(InfoPropertyName.CATEGORY.getValue()), + entity.getCategoryList()); + Assert.assertEquals(testElementInfo.get().getInfo() + .getProperty(ActivitySpecRepositoryImpl.InfoPropertyName.NAME.getValue()), + entity.getName()); + + final Optional<Element> testElement = + zusammenAdaptor.getElement(contextCreator.create(), elementContext, new Id(elementId)); + final InputStream data = testElement.get().getData(); + final ActivitySpecData activitySpecData = JsonUtil.json2Object(data, ActivitySpecData.class); + Assert.assertEquals(activitySpecData.getInputs().get(0).getName(), entity.getInputs().get(0).getName()); + } + + @Test + public void testGet() { + final ActivitySpecEntity retrieved = daoImpl.get(entity); + Assert.assertEquals(retrieved.getName(), entity.getName()); + Assert.assertEquals(retrieved.getDescription(), entity.getDescription()); + Assert.assertEquals(retrieved.getCategoryList(), entity.getCategoryList()); + } + + @Test + public void testUpdate() { + entity.setDescription("Update AS version1"); + daoImpl.update(entity); + final ActivitySpecEntity retrieved = daoImpl.get(entity); + Assert.assertEquals(retrieved.getName(), entity.getName()); + Assert.assertEquals(retrieved.getDescription(), entity.getDescription()); + Assert.assertEquals(retrieved.getCategoryList(), entity.getCategoryList()); + } + + + private void mockZusammenAdapter() { + + doAnswer(invocationOnMock -> { + Id elementId = invocationOnMock.getArgument(2); + return Optional.of(elementMap.get(elementId.getValue())); + }).when(zusammenAdaptor).getElement(any(), any(), any()); + + doAnswer(invocationOnMock -> { + ZusammenElement element = new ZusammenElement(); + Info info = new Info(); + element.setElementId(Id.ZERO); + info.addProperty("name", entity.getName()); + info.addProperty("description", entity.getDescription()); + info.addProperty("category", entity.getCategoryList()); + element.setInfo(info); + return Optional.of(element); + }).when(zusammenAdaptor).getElementByName(any(), any(), any(), any()); + + doAnswer(invocationOnMock -> { + String elementName = invocationOnMock.getArgument(3); + return elementMap.values().stream() + .filter(element -> elementName.equals(element.getInfo().getProperty(ELEMENT_TYPE_PROPERTY))) + .map(element -> { + ElementInfo elementInfo = new ElementInfo(); + elementInfo.setId(element.getElementId()); + elementInfo.setInfo(element.getInfo()); + return elementInfo; + }).findAny(); + }).when(zusammenAdaptor).getElementInfoByName(any(), any(), any(), any()); + + doAnswer(invocationOnMock -> { + ZusammenElement element = invocationOnMock.getArgument(2); + if (element.getAction().equals(Action.CREATE) || element.getAction().equals(Action.UPDATE)) { + element.setElementId(new Id(UUID.randomUUID().toString())); + } + elementMap.put(element.getElementId().getValue(), element); + elementId = element.getElementId().getValue(); + return element; + }).when(zusammenAdaptor).saveElement(any(), any(), any(), any()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ArtifactRepositoryTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ArtifactRepositoryTest.java new file mode 100644 index 00000000..96f74d58 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ArtifactRepositoryTest.java @@ -0,0 +1,148 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.onap.sdc.common.zusammen.services.ZusammenElementUtil.buildStructuralElement; + +import com.amdocs.zusammen.adaptor.inbound.api.types.item.Element; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement; +import com.amdocs.zusammen.datatypes.Id; +import com.amdocs.zusammen.datatypes.SessionContext; +import com.amdocs.zusammen.datatypes.item.Action; +import com.amdocs.zusammen.datatypes.item.ElementContext; +import com.amdocs.zusammen.datatypes.item.Info; +import java.io.IOException; +import java.io.InputStream; +import java.util.Optional; +import org.apache.commons.io.IOUtils; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.common.versioning.persistence.zusammen.ZusammenSessionContextCreator; +import org.onap.sdc.common.zusammen.services.ZusammenAdaptor; +import org.onap.sdc.workflow.persistence.impl.types.WorkflowElementType; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; + +@RunWith(MockitoJUnitRunner.class) +public class ArtifactRepositoryTest { + + private static final String FILE_NAME_PROPERTY = "fileName"; + private static final String FILE_NAME = "fileName.txt"; + private static final String ITEM1_ID = "item_id_1"; + private static final String VERSION1_ID = "version_id_1"; + private static final SessionContext SESSION_CONTEXT = new SessionContext(); + + + @Mock + private ZusammenAdaptor zusammenAdaptorMock; + @Mock + private ZusammenSessionContextCreator contextCreatorMock; + @InjectMocks + private ArtifactRepositoryImpl artifactRepository; + + @Before + public void setUp() { + doReturn(SESSION_CONTEXT).when(contextCreatorMock).create(); + } + + @Test + public void shouldUpdateArtifact() throws IOException { + + InputStream inputStreamMock = IOUtils.toInputStream("some test data for my input stream", "UTF-8"); + ArtifactEntity artifactMock = new ArtifactEntity(FILE_NAME, inputStreamMock); + + artifactRepository.update(ITEM1_ID, VERSION1_ID, artifactMock); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Update WorkflowVersion Artifact Element")); + } + + @Test + public void shouldGetArtifactWhenExist() throws IOException { + + ZusammenElement artifactElement = buildStructuralElement(WorkflowElementType.ARTIFACT.name(), Action.UPDATE); + artifactElement.setData(IOUtils.toInputStream("some test data for my input stream", "UTF-8")); + artifactElement.getInfo().addProperty(FILE_NAME_PROPERTY, FILE_NAME); + Optional<Element> elementOptional = Optional.of(artifactElement); + + doReturn(elementOptional).when(zusammenAdaptorMock) + .getElementByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.ARTIFACT.name())); + + Optional<ArtifactEntity> result = artifactRepository.get(ITEM1_ID, VERSION1_ID); + assertTrue(result.isPresent()); + assertEquals(FILE_NAME,result.get().getFileName()); + verify(zusammenAdaptorMock).getElementByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.ARTIFACT.name())); + } + + @Test + public void shouldReturnOptionalEmptyWhenDoesNotExist() { + + doReturn(Optional.empty()).when(zusammenAdaptorMock) + .getElementByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.ARTIFACT.name())); + + Optional<ArtifactEntity> result = artifactRepository.get(ITEM1_ID, VERSION1_ID); + verify(zusammenAdaptorMock).getElementByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.ARTIFACT.name())); + assertFalse(result.isPresent()); + } + + @Test + public void shouldCreateArtifactStructure() { + artifactRepository.createStructure(ITEM1_ID, VERSION1_ID); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Create WorkflowVersion Artifact Element")); + } + + @Test + public void shouldDeleteArtifact() { + artifactRepository.delete(ITEM1_ID,VERSION1_ID); + verify(zusammenAdaptorMock).saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Delete WorkflowVersion Artifact Data")); + } + + @Test + public void shouldReturnTrueIfExists() { + ElementInfo elementInfo = new ElementInfo(); + elementInfo.setId(new Id("test_id")); + Info info = new Info(); + info.addProperty(FILE_NAME_PROPERTY, "test_fileName"); + elementInfo.setInfo(info); + + doReturn(Optional.of(elementInfo)).when(zusammenAdaptorMock) + .getElementInfoByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.ARTIFACT.name())); + + assertTrue(artifactRepository.isExist(ITEM1_ID, VERSION1_ID)); + } + +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java new file mode 100644 index 00000000..4112ab4e --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/persistence/impl/ParameterRepositoryTest.java @@ -0,0 +1,214 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.persistence.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; + +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ElementInfo; +import com.amdocs.zusammen.adaptor.inbound.api.types.item.ZusammenElement; +import com.amdocs.zusammen.datatypes.Id; +import com.amdocs.zusammen.datatypes.SessionContext; +import com.amdocs.zusammen.datatypes.item.ElementContext; +import com.amdocs.zusammen.datatypes.item.Info; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mapstruct.ap.internal.util.Collections; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.common.versioning.persistence.zusammen.ZusammenSessionContextCreator; +import org.onap.sdc.common.zusammen.services.ZusammenAdaptor; +import org.onap.sdc.workflow.persistence.impl.types.ParameterPropertyName; +import org.onap.sdc.workflow.persistence.impl.types.WorkflowElementType; +import org.onap.sdc.workflow.persistence.types.ParameterEntity; +import org.onap.sdc.workflow.persistence.types.ParameterRole; +import org.onap.sdc.workflow.persistence.types.ParameterType; + +@RunWith(MockitoJUnitRunner.class) +public class ParameterRepositoryTest { + + private static final String ITEM1_ID = "item_id_1"; + private static final String VERSION1_ID = "version_id_1"; + private static final String PARAMETER1_ID = "parameter_id_1"; + private static final String PARAMETER2_ID = "parameter_id_2"; + private static final String PARAMETERS_PARENT_ID = "parameters_id"; + private static final SessionContext SESSION_CONTEXT = new SessionContext(); + + @Mock + private ZusammenAdaptor zusammenAdaptorMock; + @Mock + private ZusammenSessionContextCreator contextCreatorMock; + @Spy + @InjectMocks + private ParameterRepositoryImpl parameterRepository; + + @Before + public void setUp() { + doReturn(SESSION_CONTEXT).when(contextCreatorMock).create(); + } + + @Test + public void shouldGetParameterById() { + + ElementInfo element = new ElementInfo(); + element.setId(new Id(PARAMETER1_ID)); + Info info = new Info(); + info.setName("testInput"); + info.addProperty(ParameterPropertyName.TYPE.name(), ParameterType.FLOAT.name()); + info.addProperty(ParameterPropertyName.MANDATORY.name(), true); + element.setInfo(info); + doReturn(Optional.of(element)).when(zusammenAdaptorMock) + .getElementInfo(eq(SESSION_CONTEXT), any(ElementContext.class), + eq(new Id(PARAMETER1_ID))); + ParameterEntity result = parameterRepository.get(ITEM1_ID, VERSION1_ID, PARAMETER1_ID); + verify(zusammenAdaptorMock) + .getElementInfo(eq(SESSION_CONTEXT), any(ElementContext.class), eq(new Id(PARAMETER1_ID))); + assertEquals("testInput", result.getName()); + + } + + + @Test + public void shouldUpdateParameter() { + ParameterEntity parameterEntityToUpdate = new ParameterEntity(); + parameterEntityToUpdate.setId(PARAMETER1_ID); + parameterEntityToUpdate.setName("Input1"); + parameterEntityToUpdate.setMandatory(true); + parameterEntityToUpdate.setType(ParameterType.STRING); + + parameterRepository.update(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT, parameterEntityToUpdate); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Update WorkflowVersion Parameter")); + + } + + @Test + public void shouldCreateParameterStructure() { + parameterRepository.createStructure(ITEM1_ID, VERSION1_ID); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Create WorkflowVersion INPUTS Element")); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Create WorkflowVersion OUTPUTS Element")); + } + + @Test + public void shouldDeleteParameter() { + parameterRepository.delete(ITEM1_ID, VERSION1_ID, PARAMETER1_ID); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Delete Parameter with id parameter_id_1")); + } + + + @Test + public void shouldListParametersByType() { + + ElementInfo parameter1 = new ElementInfo(); + parameter1.setId(new Id(PARAMETER1_ID)); + Info info1 = new Info(); + info1.setName("input1"); + info1.addProperty(ParameterPropertyName.TYPE.name(), "INTEGER"); + info1.addProperty(ParameterPropertyName.MANDATORY.name(), true); + parameter1.setInfo(info1); + ElementInfo parameter2 = new ElementInfo(); + parameter2.setId(new Id(PARAMETER2_ID)); + Info info2 = new Info(); + info2.setName("input2"); + info2.addProperty(ParameterPropertyName.TYPE.name(), "STRING"); + info2.addProperty(ParameterPropertyName.MANDATORY.name(), false); + parameter2.setInfo(info2); + Collection<ElementInfo> parameters = Collections.asSet(parameter1, parameter2); + doReturn(parameters).when(zusammenAdaptorMock) + .listElementsByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); + Collection<ParameterEntity> results = parameterRepository.list(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); + + verify(zusammenAdaptorMock).listElementsByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); + assertTrue(results.stream().anyMatch(parameterEntity -> parameterEntity.getId().equals(PARAMETER1_ID))); + assertTrue(results.stream().anyMatch(parameterEntity -> parameterEntity.getId().equals(PARAMETER2_ID))); + } + + @Test + public void shouldDeleteAllParametersByType() { + ElementInfo parameterParentElement = new ElementInfo(); + parameterParentElement.setId(new Id(PARAMETERS_PARENT_ID)); + ElementInfo parameter1 = new ElementInfo(); + parameter1.setId(new Id(PARAMETER1_ID)); + ElementInfo parameter2 = new ElementInfo(); + parameter2.setId(new Id(PARAMETER2_ID)); + parameterParentElement.setSubElements(new ArrayList<>()); + parameterParentElement.getSubElements().add(parameter1); + parameterParentElement.getSubElements().add(parameter2); + + Optional<ElementInfo> elementOptional = Optional.of(parameterParentElement); + + doReturn(elementOptional).when(zusammenAdaptorMock) + .getElementInfoByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); + + parameterRepository.deleteAll(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Delete all INPUT")); + } + + @Test(expected = IllegalStateException.class) + public void shouldFailIfParentElementDoesNotExist() { + doReturn(Optional.empty()).when(zusammenAdaptorMock) + .getElementInfoByName(eq(SESSION_CONTEXT), any(ElementContext.class), isNull(), + eq(WorkflowElementType.INPUTS.name())); + parameterRepository.deleteAll(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); + } + + @Test + public void shouldCreateParameter() { + ZusammenElement zusammenParentElement = new ZusammenElement(); + zusammenParentElement.setElementId(new Id(PARAMETERS_PARENT_ID)); + ZusammenElement zusammenElement = new ZusammenElement(); + zusammenElement.setElementId(new Id(PARAMETER1_ID)); + zusammenParentElement.addSubElement(zusammenElement); + doReturn(zusammenParentElement).when(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), + any(ZusammenElement.class), eq("Create WorkflowVersion Parameter Element")); + ParameterEntity parameterEntity = new ParameterEntity("test_input_parameter"); + parameterEntity.setType(ParameterType.INTEGER); + parameterEntity.setMandatory(true); + + ParameterEntity returnedParameter = + parameterRepository.create(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT, parameterEntity); + verify(zusammenAdaptorMock) + .saveElement(eq(SESSION_CONTEXT), any(ElementContext.class), any(ZusammenElement.class), + eq("Create WorkflowVersion Parameter Element")); + assertEquals(PARAMETER1_ID, returnedParameter.getId()); + } + +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/server/resolvers/UserIdResolverTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/server/resolvers/UserIdResolverTest.java new file mode 100644 index 00000000..464af465 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/server/resolvers/UserIdResolverTest.java @@ -0,0 +1,92 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.server.resolvers; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.onap.sdc.workflow.api.RestParams.USER_ID_HEADER; + +import javax.servlet.http.HttpServletRequest; +import org.junit.Test; +import org.onap.sdc.workflow.services.annotations.UserId; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.ServletRequestBindingException; +import org.springframework.web.context.request.NativeWebRequest; + +/** + * Tests injection of user ID from HTTP headers. + * + * @author evitaliy + * @since 21 Aug 2018 + */ +public class UserIdResolverTest { + + @Test + public void oneHeaderSelectedWhenMultipleUserIdHeadersSent() throws ServletRequestBindingException { + + final String headerValue = "UserIdValueFromHeader"; + + HttpServletRequest servletRequestMock = mock(HttpServletRequest.class); + when(servletRequestMock.getHeader(USER_ID_HEADER)).thenReturn(headerValue); + + NativeWebRequest webRequestMock = mock(NativeWebRequest.class); + when(webRequestMock.getNativeRequest(HttpServletRequest.class)).thenReturn(servletRequestMock); + + Object resolved = new UserIdResolver().resolveArgument(null, null, webRequestMock, null); + assertEquals(headerValue, resolved); + } + + @Test(expected = IllegalStateException.class) + public void illegalTypeErrorThrownWhenAnnotatedParameterIsNotOfTypeString() { + MethodParameter methodParameterMock = mock(MethodParameter.class); + when(methodParameterMock.hasParameterAnnotation(UserId.class)).thenReturn(true); + //noinspection unchecked + when(methodParameterMock.getParameterType()).thenReturn((Class)String[].class); + new UserIdResolver().supportsParameter(methodParameterMock); + } + + @Test(expected = ServletRequestBindingException.class) + public void missingHeaderErrorThrownWhenUserIdHeaderNotPopulated() throws ServletRequestBindingException { + NativeWebRequest webRequestMock = mock(NativeWebRequest.class); + when(webRequestMock.getNativeRequest(HttpServletRequest.class)).thenReturn(mock(HttpServletRequest.class)); + new UserIdResolver().resolveArgument(null, null, webRequestMock, null); + } + + @Test(expected = NullPointerException.class) + public void exceptionThrownWhenRequestTypeIsNotHttpRequest() throws ServletRequestBindingException { + NativeWebRequest webRequestMock = mock(NativeWebRequest.class); + new UserIdResolver().resolveArgument(null, null, webRequestMock, null); + } + + @Test + public void parameterNotSupportedWhenNotAnnotatedWithUserIdAnnotation() { + MethodParameter methodParameterMock = mock(MethodParameter.class); + assertFalse(new UserIdResolver().supportsParameter(methodParameterMock)); + } + + @Test + public void parameterSupportedWhenAnnotatedWithUserIdAnnotationAndOfTypeString() { + MethodParameter methodParameterMock = mock(MethodParameter.class); + when(methodParameterMock.hasParameterAnnotation(UserId.class)).thenReturn(true); + //noinspection unchecked + when(methodParameterMock.getParameterType()).thenReturn((Class) String.class); + assertTrue(new UserIdResolver().supportsParameter(methodParameterMock)); + } +}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/UniqueValueServiceTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/UniqueValueServiceTest.java new file mode 100644 index 00000000..da2d8fa5 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/UniqueValueServiceTest.java @@ -0,0 +1,114 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import java.util.Optional; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.onap.sdc.workflow.persistence.UniqueValueRepository; +import org.onap.sdc.workflow.persistence.types.UniqueValueEntity; +import org.onap.sdc.workflow.services.exceptions.UniqueValueViolationException; + +public class UniqueValueServiceTest { + + private static final String TYPE = "ss"; + private static final String DUMMY_COMBINATION = "dummy"; + + @Mock + private UniqueValueRepository uniqueValueRepositoryMock; + + @Spy + @InjectMocks + private UniqueValueService uniqueValueService; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void shouldCallRepositoryInsertIfValueUnique() { + doReturn(Optional.empty()).when(uniqueValueRepositoryMock).findById(any()); + uniqueValueService.createUniqueValue(TYPE, DUMMY_COMBINATION); + verify(uniqueValueRepositoryMock, times(1)).insert(any(UniqueValueEntity.class)); + } + + @Test + public void shouldNotCheckValueIfNoUniqueCombination() { + uniqueValueService.createUniqueValue(TYPE); + verify(uniqueValueRepositoryMock, never()).findById(any(UniqueValueEntity.class)); + } + + @Test(expected = UniqueValueViolationException.class) + public void shouldThrowExceptionIfValueIsNotUnique() { + doReturn(Optional.of("xxx")).when(uniqueValueRepositoryMock).findById(any()); + uniqueValueService.createUniqueValue(TYPE, DUMMY_COMBINATION); + } + + @Test + public void shouldCallRepositoryDeleteIfValueValid() { + uniqueValueService.deleteUniqueValue(TYPE, DUMMY_COMBINATION); + verify(uniqueValueRepositoryMock, times(1)).delete(any(UniqueValueEntity.class)); + } + + @Test + public void shouldNotCallRepositoryDeleteIfValueNouniqueCombination() { + uniqueValueService.deleteUniqueValue(TYPE); + verify(uniqueValueRepositoryMock, never()).delete(any(UniqueValueEntity.class)); + } + + @Test + public void shouldNotUpdateIfNewAndOldValueAreEqualsCaseIgnore() { + String value = "value"; + uniqueValueService.updateUniqueValue(TYPE, value, value.toUpperCase()); + verify(uniqueValueService, never()).createUniqueValue(anyString(), any()); + } + + @Test + public void shouldUpdateIfNewAndOldValueAreNotEqualsCaseIgnore() { + String oldValue = "oldValue"; + String newValue = "newValue"; + uniqueValueService.updateUniqueValue(TYPE, oldValue, newValue); + verify(uniqueValueService, times(1)).createUniqueValue(anyString(), any()); + verify(uniqueValueService, times(1)).deleteUniqueValue(anyString(), any()); + } + + @Test + public void shouldReturnTrueIfValueExist() { + doReturn(Optional.of("xxx")).when(uniqueValueRepositoryMock).findById(any()); + assertTrue(uniqueValueService.isUniqueValueOccupied(TYPE, DUMMY_COMBINATION)); + } + + @Test + public void shouldReturnFalseIfValueNotExist() { + doReturn(Optional.empty()).when(uniqueValueRepositoryMock).findById(any()); + assertFalse(uniqueValueService.isUniqueValueOccupied(TYPE, DUMMY_COMBINATION)); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/ActivitySpecManagerImplTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/ActivitySpecManagerImplTest.java new file mode 100644 index 00000000..3166e06f --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/ActivitySpecManagerImplTest.java @@ -0,0 +1,293 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import static org.onap.sdc.workflow.TestUtil.createRetrievedVersion; +import static org.onap.sdc.workflow.services.ActivitySpecConstant.ACTIVITY_SPEC_NOT_FOUND; +import static org.onap.sdc.workflow.services.ActivitySpecConstant.VERSION_ID_DEFAULT_VALUE; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.Spy; +import org.onap.sdc.common.versioning.persistence.types.InternalItem; +import org.onap.sdc.common.versioning.persistence.types.InternalVersion; +import org.onap.sdc.common.versioning.services.ItemManager; +import org.onap.sdc.common.versioning.services.VersioningManager; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.Version; +import org.onap.sdc.common.versioning.services.types.VersionCreationMethod; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.api.types.activityspec.ActivitySpecAction; +import org.onap.sdc.workflow.persistence.ActivitySpecRepository; +import org.onap.sdc.workflow.persistence.types.ActivitySpecEntity; +import org.onap.sdc.workflow.persistence.types.ActivitySpecParameter; +import org.onap.sdc.workflow.services.UniqueValueService; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.VersionStatusModificationException; +import org.onap.sdc.workflow.services.impl.mappers.ActivitySpecMapper; + +public class ActivitySpecManagerImplTest { + + private static final String STRING_TYPE = "String"; + private static final String TEST_ERROR_MSG = "Test Error"; + private static final String ID = "ID1"; + private String version01 = "12345"; + private ActivitySpecEntity input; + + @Spy + @InjectMocks + private ActivitySpecManagerImpl activitySpecManager; + @Mock + private ItemManager itemManagerMock; + @Mock + private VersioningManager versionManagerMock; + @Mock + private ActivitySpecRepository activitySpecRepositoryMock; + @Mock + private UniqueValueService uniqueValueServiceMock; + @Mock + private ActivitySpecMapper activitySpecMapperMock; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @After + public void tearDown() { + activitySpecManager = null; + } + + @Test + public void testCreate() { + ActivitySpecEntity activitySpecToCreate = new ActivitySpecEntity(); + activitySpecToCreate.setName("startserver"); + activitySpecToCreate.setDescription("start the server"); + activitySpecToCreate.setVersionId(version01); + + List<String> categoryList = new ArrayList<>(); + categoryList.add("category1"); + categoryList.add("category2"); + activitySpecToCreate.setCategoryList(categoryList); + + ActivitySpecParameter inputParams = new ActivitySpecParameter("dbhost", STRING_TYPE, null); + inputParams.setValue("localhost"); + ActivitySpecParameter inputParams1 = new ActivitySpecParameter("dbname", STRING_TYPE, null); + inputParams.setValue("prod"); + List<ActivitySpecParameter> inputs = new ArrayList<>(); + inputs.add(inputParams); + inputs.add(inputParams1); + activitySpecToCreate.setInputs(inputs); + + ActivitySpecParameter outputParams = new ActivitySpecParameter("status", STRING_TYPE, null); + outputParams.setValue("started"); + List<ActivitySpecParameter> outputs = new ArrayList<>(); + outputs.add(outputParams); + activitySpecToCreate.setOutputs(outputs); + + activitySpecToCreate.setVersionId(version01); + + String itemId = "ID1"; + + InternalItem createdItem = new InternalItem(); + createdItem.setId(itemId); + doReturn(createdItem).when(itemManagerMock).create(any()); + + doReturn(createRetrievedVersion(version01, VersionStatus.Draft)).when(versionManagerMock) + .create(eq(itemId), isNull(), any(Version.class), eq(VersionCreationMethod.major)); + + ActivitySpecEntity activitySpec = activitySpecManager.createActivitySpec(activitySpecToCreate); + + Assert.assertNotNull(activitySpec); + activitySpec.setId(itemId); + activitySpec.setStatus(VersionStatus.Draft.name()); + assertActivitySpecEquals(activitySpec, activitySpecToCreate); + } + + private void assertActivitySpecEquals(ActivitySpecEntity actual, ActivitySpecEntity expected) { + Assert.assertEquals(actual.getId(), expected.getId()); + Assert.assertEquals(actual.getName(), expected.getName()); + Assert.assertEquals(actual.getDescription(), expected.getDescription()); + Assert.assertEquals(actual.getCategoryList(), expected.getCategoryList()); + Assert.assertEquals(actual.getInputs(), expected.getInputs()); + Assert.assertEquals(actual.getOutputs(), expected.getOutputs()); + } + + @Test + public void testList() { + Item item = new Item(); + doReturn(Collections.singletonList(item)).when(itemManagerMock).list(any()); + doReturn(new ActivitySpecEntity(ID, null)).when(activitySpecMapperMock).itemToActivitySpec(item); + + final Collection<ActivitySpecEntity> activitySpecs = activitySpecManager.list("Certified"); + Assert.assertEquals(1, activitySpecs.size()); + Assert.assertEquals(ID, activitySpecs.iterator().next().getId()); + } + + @Test + public void testListInvalidFilter() { + final Collection<ActivitySpecEntity> activitySpecs = activitySpecManager.list("invalid_status"); + Assert.assertEquals(0, activitySpecs.size()); + } + + @Test + public void testListNoFilter() { + final Collection<ActivitySpecEntity> activitySpecs = activitySpecManager.list(null); + Assert.assertEquals(0, activitySpecs.size()); + } + + @Test + public void testGet() { + input = new ActivitySpecEntity(); + input.setId(ID); + input.setVersionId(version01); + + mockListVersions(); + doReturn(input).when(activitySpecRepositoryMock).get(any()); + doReturn(createRetrievedVersion(version01,VersionStatus.Draft)).when(versionManagerMock).get(any(), any()); + ActivitySpecEntity retrieved = activitySpecManager.get(input); + assertActivitySpecEquals(retrieved, input); + Assert.assertEquals(retrieved.getStatus(), VersionStatus.Draft.name()); + + + retrieved = activitySpecManager.get(input); + assertActivitySpecEquals(retrieved, input); + Assert.assertEquals(retrieved.getStatus(), VersionStatus.Draft.name()); + } + + private void mockListVersions() { + doReturn(Collections.singletonList((Version)createRetrievedVersion(version01,VersionStatus.Draft))).when(versionManagerMock).list(any()); + } + + @Test + public void testGetActivitySpecDaoFail() { + input = new ActivitySpecEntity(); + input.setId(ID); + input.setVersionId(version01); + mockListVersions(); + doReturn(input).when(activitySpecRepositoryMock).get(any()); + Mockito.doThrow(new RuntimeException(TEST_ERROR_MSG)).when(activitySpecRepositoryMock).get(any()); + try { + activitySpecManager.get(input); + Assert.fail(); + } catch (EntityNotFoundException exception) { + Assert.assertEquals(ACTIVITY_SPEC_NOT_FOUND, exception.getMessage()); + } + } + + @Test + public void testListVersionFail() { + input = new ActivitySpecEntity(); + input.setId(ID); + input.setVersionId(VERSION_ID_DEFAULT_VALUE); + Mockito.doThrow(new RuntimeException(TEST_ERROR_MSG)).when(versionManagerMock).list(any()); + try { + activitySpecManager.get(input); + Assert.fail(); + } catch (EntityNotFoundException exception) { + Assert.assertEquals(ACTIVITY_SPEC_NOT_FOUND, exception.getMessage()); + } + } + + @Test(expected = VersionStatusModificationException.class) + public void testInvalidDeprecate() { + InternalVersion version = createRetrievedVersion(version01, VersionStatus.Draft); + doReturn(version).when(versionManagerMock).get(ID, version01); + activitySpecManager.actOnAction(new ActivitySpecEntity(ID, version01), ActivitySpecAction.DEPRECATE); + } + + @Test(expected = VersionStatusModificationException.class) + public void testInvalidDelete() { + mockCertifiedVersion(); + activitySpecManager.actOnAction(new ActivitySpecEntity(ID, version01), ActivitySpecAction.DELETE); + } + + private void mockCertifiedVersion() { + InternalVersion version = createRetrievedVersion(version01, VersionStatus.Certified); + doReturn(version).when(versionManagerMock).get(ID, version01); + } + + @Test(expected = VersionStatusModificationException.class) + public void testInvalidCertify() { + mockCertifiedVersion(); + activitySpecManager.actOnAction(new ActivitySpecEntity(ID, version01), ActivitySpecAction.CERTIFY); + } + + @Test + public void testCertify() { + InternalVersion retrievedVersion = createRetrievedVersion(version01, VersionStatus.Draft); + doReturn(Collections.singletonList(retrievedVersion)).when(versionManagerMock).list(any()); + doReturn(retrievedVersion).when(versionManagerMock).get(any(), any()); + + activitySpecManager.actOnAction(new ActivitySpecEntity(ID, version01), ActivitySpecAction.CERTIFY); + + verify(versionManagerMock).updateStatus(eq(ID), eq(version01), eq(VersionStatus.Certified), anyString()); + } + + @Test + public void testGetVersionFailOnStatusChangeAction() { + mockListVersions(); + try { + activitySpecManager.actOnAction(new ActivitySpecEntity(ID, version01), ActivitySpecAction.CERTIFY); + Assert.fail(); + } catch (EntityNotFoundException exception) { + Assert.assertEquals(ACTIVITY_SPEC_NOT_FOUND, exception.getMessage()); + } + } + + @Test + public void testDeprecate() { + InternalVersion retrievedVersion = createRetrievedVersion(version01, VersionStatus.Certified); + mockListVersions(); + doReturn(retrievedVersion).when(versionManagerMock).get(any(), any()); + activitySpecManager + .actOnAction(new ActivitySpecEntity(ID, VERSION_ID_DEFAULT_VALUE), ActivitySpecAction.DEPRECATE); + + verify(versionManagerMock).updateStatus(eq(ID), eq(version01), eq(VersionStatus.Deprecated), anyString()); + } + + @Test + public void testDelete() { + ActivitySpecEntity activitySpec = new ActivitySpecEntity(); + activitySpec.setName("stopServer"); + activitySpec.setVersionId(version01); + + mockListVersions(); + doReturn(createRetrievedVersion(version01, VersionStatus.Deprecated)).when(versionManagerMock).get(any(), any()); + doReturn(activitySpec).when(activitySpecRepositoryMock).get(any()); + activitySpecManager + .actOnAction(new ActivitySpecEntity(ID, VERSION_ID_DEFAULT_VALUE), ActivitySpecAction.DELETE); + + verify(versionManagerMock).updateStatus(eq(ID), eq(version01), eq(VersionStatus.Deleted), anyString()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java new file mode 100644 index 00000000..1db24092 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowManagerImplTest.java @@ -0,0 +1,359 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.onap.sdc.common.versioning.services.types.VersionStatus.Certified; +import static org.onap.sdc.workflow.TestUtil.createItem; +import static org.onap.sdc.workflow.TestUtil.createWorkflow; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_LIMIT; +import static org.onap.sdc.workflow.services.types.PagingConstants.DEFAULT_OFFSET; +import static org.onap.sdc.workflow.services.types.PagingConstants.MAX_LIMIT; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.onap.sdc.common.versioning.services.ItemManager; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.ItemStatus; +import org.onap.sdc.workflow.services.UniqueValueService; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; +import org.onap.sdc.workflow.services.impl.mappers.WorkflowMapper; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.workflow.services.types.Page; +import org.onap.sdc.workflow.services.types.Paging; +import org.onap.sdc.workflow.services.types.PagingRequest; +import org.onap.sdc.workflow.services.types.RequestSpec; +import org.onap.sdc.workflow.services.types.Sort; +import org.onap.sdc.workflow.services.types.SortingRequest; +import org.onap.sdc.workflow.services.types.Workflow; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +public class WorkflowManagerImplTest { + + + private static final String ITEM1_ID = "1"; + private static final String WORKFLOW_TYPE = "WORKFLOW"; + private static final String WORKFLOW_NAME_UNIQUE_TYPE = "WORKFLOW_NAME"; + private static final List<Item> ITEMS; + private static final List<Workflow> MAPPED_WORKFLOWS; + private static final String SORT_FIELD_NAME = "name"; + + static { + List<Item> items = new ArrayList<>(); + List<Workflow> mappedWorkflows = new ArrayList<>(); + for (int i = 0; i < 5; i++) { + items.add(createItem(i, true, true, ItemStatus.ACTIVE)); + mappedWorkflows.add(createWorkflow(i, true, ArchivingStatus.ACTIVE)); + } + ITEMS = Collections.unmodifiableList(items); + MAPPED_WORKFLOWS = Collections.unmodifiableList(mappedWorkflows); + } + + @Mock + private ItemManager itemManagerMock; + @Mock + private UniqueValueService uniqueValueServiceMock; + @Mock + private WorkflowMapper workflowMapperMock; + @Mock + private VersionStateMapper versionStateMapperMock; + @InjectMocks + private WorkflowManagerImpl workflowManager; + + @Test + public void shouldReturnWorkflowVersionList() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + RequestSpec requestSpec = createRequestSpec(0, 20, true); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + + Map<String, Workflow> workflowById = + workflows.getItems().stream().collect(Collectors.toMap(Workflow::getId, Function.identity())); + assertEquals(ITEMS.size(), workflows.getItems().size()); + for (int i = 0; i < ITEMS.size(); i++) { + assertTrue(workflowById.containsKey(String.valueOf(i))); + } + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + @Test + public void listWithVersionStateFilter() { + doReturn(Certified).when(versionStateMapperMock) + .workflowVersionStateToVersionStatus(WorkflowVersionState.CERTIFIED); + doReturn(Arrays.asList(ITEMS.get(0), ITEMS.get(2))).when(itemManagerMock).list(any()); + doReturn(MAPPED_WORKFLOWS.get(0)).when(workflowMapperMock).fromItem(ITEMS.get(0)); + doReturn(MAPPED_WORKFLOWS.get(2)).when(workflowMapperMock).fromItem(ITEMS.get(2)); + + RequestSpec requestSpec = createRequestSpec(0, 20, true); + Page<Workflow> workflows = + workflowManager.list(null, null, Collections.singleton(WorkflowVersionState.CERTIFIED), requestSpec); + + Map<String, Workflow> workflowById = + workflows.getItems().stream().collect(Collectors.toMap(Workflow::getId, Function.identity())); + assertEquals(2, workflows.getItems().size()); + assertTrue(workflowById.containsKey("0")); + assertTrue(workflowById.containsKey("2")); + + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), 2); + } + + @Test(expected = EntityNotFoundException.class) + public void shouldThrowExceptionWhenWorkflowDontExist() { + Workflow nonExistingWorkflow = new Workflow(); + nonExistingWorkflow.setId(ITEM1_ID); + doReturn(null).when(itemManagerMock).get(ITEM1_ID); + workflowManager.get(nonExistingWorkflow); + verify(workflowMapperMock, times(3)).fromItem(any(Item.class)); + } + + @Test + public void shouldReturnWorkflow() { + Item retrievedItem = createItem(1, true, true, ItemStatus.ACTIVE); + doReturn(retrievedItem).when(itemManagerMock).get(ITEM1_ID); + Workflow workflow = createWorkflow(1, true, ArchivingStatus.ACTIVE); + workflowManager.get(workflow); + verify(itemManagerMock).get(ITEM1_ID); + verify(workflowMapperMock).fromItem(retrievedItem); + } + + @Test + public void shouldCreateWorkflowItemFromWorkflow() { + Workflow workflowToBeCreated = createWorkflow(1, false, ArchivingStatus.ACTIVE); + workflowManager.create(workflowToBeCreated); + verify(itemManagerMock).create(any(Item.class)); + verify(uniqueValueServiceMock).validateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflowToBeCreated.getName()); + } + + @Test + public void shouldUpdateWorkflow() { + Item workflowItem = createItem(1, true, true, ItemStatus.ACTIVE); + doReturn(workflowItem).when(itemManagerMock).get(ITEM1_ID); + Workflow workflowToBeUpdated = createWorkflow(1, true, ArchivingStatus.ACTIVE); + workflowManager.update(workflowToBeUpdated); + verify(itemManagerMock).update(eq(ITEM1_ID),any(Item.class)); + verify(uniqueValueServiceMock) + .updateUniqueValue(WORKFLOW_NAME_UNIQUE_TYPE, workflowItem.getName(), workflowToBeUpdated.getName()); + + } + + @Test(expected = EntityNotFoundException.class) + public void shouldThrowExceptionWhenWorkflowToUpdateNotFound() { + doReturn(null).when(itemManagerMock).get(ITEM1_ID); + workflowManager.update(createWorkflow(1, true, ArchivingStatus.ACTIVE)); + } + + @Test + public void listWhenRequestSpecIsNull() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, null); + + assertEquals(ITEMS.size(), workflows.getItems().size()); + assertPaging(workflows.getPaging(), DEFAULT_OFFSET, DEFAULT_LIMIT, ITEMS.size()); + + // verify sorted ascending by name + for (int i = DEFAULT_OFFSET; i < ITEMS.size(); i++) { + assertEquals("Workflow_" + i, workflows.getItems().get(i).getName()); + } + } + + @Test + public void listWhenPagingIsNull() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, + new RequestSpec(null, SortingRequest.builder().sort(new Sort(SORT_FIELD_NAME, true)).build())); + + assertEquals(ITEMS.size(), workflows.getItems().size()); + assertPaging(workflows.getPaging(), DEFAULT_OFFSET, DEFAULT_LIMIT, ITEMS.size()); + } + + @Test + public void listWhenOffsetAndLimitAreNull() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + RequestSpec requestSpec = new RequestSpec(new PagingRequest(-2, -8), + SortingRequest.builder().sort(new Sort(SORT_FIELD_NAME, true)).build()); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + + assertEquals(ITEMS.size(), workflows.getItems().size()); + assertPaging(workflows.getPaging(), DEFAULT_OFFSET, DEFAULT_LIMIT, ITEMS.size()); + } + + @Test + public void listWhenSortingIsNull() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + RequestSpec requestSpec = new RequestSpec(new PagingRequest(2, 8), null); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + + assertEquals(3, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + + // verify sorted ascending by name + assertEquals("Workflow_2", workflows.getItems().get(0).getName()); + assertEquals("Workflow_3", workflows.getItems().get(1).getName()); + assertEquals("Workflow_4", workflows.getItems().get(2).getName()); + } + + @Test + public void listWhenSortingIsEmpty() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + RequestSpec requestSpec = new RequestSpec(new PagingRequest(2, 8), SortingRequest.builder().build()); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + + assertEquals(3, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + + // verify sorted ascending by name + assertEquals("Workflow_2", workflows.getItems().get(0).getName()); + assertEquals("Workflow_3", workflows.getItems().get(1).getName()); + assertEquals("Workflow_4", workflows.getItems().get(2).getName()); + } + + @Test + public void listWhenRequestSpecIsValid() { + RequestSpec requestSpec = createRequestSpec(0, 5, true); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + + assertEquals(5, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + @Test + public void listWhenLimitIsLessThanTotal() { + RequestSpec requestSpec = createRequestSpec(0, 3, true); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + assertEquals(3, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + + @Test + public void listWhenOffsetIsNotFirst() { + RequestSpec requestSpec = createRequestSpec(3, 1, true); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + assertEquals(1, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + @Test + public void listWhenLimitIsMoreThanTotal() { + RequestSpec requestSpec = createRequestSpec(0, 10, true); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + assertEquals(5, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + @Test + public void listWhenOffsetIsMoreThanTotal() { + RequestSpec requestSpec = createRequestSpec(6, 3, true); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + assertEquals(0, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + @Test + public void listWhenOffsetIsMoreThanMax() { + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + RequestSpec requestSpec = createRequestSpec(0, 5555, true); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + + assertEquals(ITEMS.size(), workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), MAX_LIMIT, ITEMS.size()); + } + + @Test + public void listWhenOffsetAndLimitAreMoreThanTotal() { + RequestSpec requestSpec = createRequestSpec(10, 10, true); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + assertEquals(0, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + } + + @Test + public void listWhenSortedDesc() { + RequestSpec requestSpec = createRequestSpec(2, 1, false); + doReturn(ITEMS).when(itemManagerMock).list(any()); + mockItemToWorkflowMaps(); + Page<Workflow> workflows = workflowManager.list(null, null, null, requestSpec); + assertEquals(1, workflows.getItems().size()); + assertPaging(workflows.getPaging(), requestSpec.getPaging().getOffset(), requestSpec.getPaging().getLimit(), + ITEMS.size()); + Iterator<Workflow> workflowIterator = workflows.getItems().iterator(); + assertEquals("Workflow_2", workflowIterator.next().getName()); + } + + private void mockItemToWorkflowMaps() { + for (int i = 0; i < ITEMS.size(); i++) { + doReturn(MAPPED_WORKFLOWS.get(i)).when(workflowMapperMock).fromItem(ITEMS.get(i)); + } + } + + private static RequestSpec createRequestSpec(int offset, int limit, boolean isAscending) { + return new RequestSpec(new PagingRequest(offset, limit), + SortingRequest.builder().sort(new Sort(SORT_FIELD_NAME, isAscending)).build()); + } + + private static void assertPaging(Paging paging, int expectedOffset, int expectedLimit, int expectedTotal) { + assertEquals(expectedOffset, paging.getOffset()); + assertEquals(expectedLimit, paging.getLimit()); + assertEquals(expectedTotal, paging.getTotal()); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java new file mode 100644 index 00000000..6648f376 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/WorkflowVersionManagerImplTest.java @@ -0,0 +1,441 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.onap.sdc.workflow.TestUtil.createRetrievedVersion; +import static org.onap.sdc.workflow.services.types.WorkflowVersionState.CERTIFIED; +import static org.onap.sdc.workflow.services.types.WorkflowVersionState.DRAFT; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import org.apache.commons.io.IOUtils; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Spy; +import org.mockito.junit.MockitoJUnitRunner; +import org.onap.sdc.common.versioning.persistence.types.InternalItem; +import org.onap.sdc.common.versioning.persistence.types.InternalVersion; +import org.onap.sdc.common.versioning.services.ItemManager; +import org.onap.sdc.common.versioning.services.VersioningManager; +import org.onap.sdc.common.versioning.services.types.ItemStatus; +import org.onap.sdc.common.versioning.services.types.Version; +import org.onap.sdc.common.versioning.services.types.VersionCreationMethod; +import org.onap.sdc.common.versioning.services.types.VersionState; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.persistence.ArtifactRepository; +import org.onap.sdc.workflow.persistence.ParameterRepository; +import org.onap.sdc.workflow.persistence.types.ArtifactEntity; +import org.onap.sdc.workflow.persistence.types.ParameterEntity; +import org.onap.sdc.workflow.persistence.types.ParameterRole; +import org.onap.sdc.workflow.services.exceptions.EntityNotFoundException; +import org.onap.sdc.workflow.services.exceptions.VersionCreationException; +import org.onap.sdc.workflow.services.exceptions.VersionModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationException; +import org.onap.sdc.workflow.services.exceptions.VersionStateModificationMissingArtifactException; +import org.onap.sdc.workflow.services.exceptions.WorkflowModificationException; +import org.onap.sdc.workflow.services.impl.mappers.VersionMapper; +import org.onap.sdc.workflow.services.impl.mappers.VersionStateMapper; +import org.onap.sdc.workflow.services.types.WorkflowVersion; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.springframework.mock.web.MockMultipartFile; + +@RunWith(MockitoJUnitRunner.class) +public class WorkflowVersionManagerImplTest { + + private static final String ITEM1_ID = "item_id_1"; + private static final String VERSION1_ID = "version_id_1"; + private static final String VERSION2_ID = "version_id_2"; + + @Mock + private ItemManager itemManagerMock; + @Mock + private VersioningManager versioningManagerMock; + @Mock + private ParameterRepository parameterRepositoryMock; + @Mock + private ArtifactRepository artifactRepositoryMock; + @Mock + private VersionMapper versionMapperMock; + @Mock + private VersionStateMapper versionStateMapperMock; + @Rule + public ExpectedException exceptionRule = ExpectedException.none(); + @Spy + @InjectMocks + private WorkflowVersionManagerImpl workflowVersionManager; + + @Test(expected = EntityNotFoundException.class) + public void shouldThrowExceptionWhenVersionDontExist() { + doThrow(new RuntimeException()).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + workflowVersionManager.get(ITEM1_ID, VERSION1_ID); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenCreatingVersionForArchivedWorkflow() { + InternalItem mockItem = new InternalItem(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowVersionManager.create(ITEM1_ID, null, new WorkflowVersion(VERSION1_ID)); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenUpdatingVersionForArchivedWorkflow() { + InternalItem mockItem = new InternalItem(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowVersionManager.update(ITEM1_ID, new WorkflowVersion(VERSION1_ID)); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenUploadingArtifactForArchivedWorkflow() { + InternalItem mockItem = new InternalItem(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + MockMultipartFile mockFile = new MockMultipartFile("data", "filename.txt", "text/plain", "some xml".getBytes()); + workflowVersionManager.uploadArtifact(ITEM1_ID, VERSION1_ID, mockFile); + } + + @Test(expected = WorkflowModificationException.class) + public void shouldThrowExceptionWhenDeletingArtifactForArchivedWorkflow() { + InternalItem mockItem = new InternalItem(); + mockItem.setId(ITEM1_ID); + mockItem.setStatus(ItemStatus.ARCHIVED); + doReturn(mockItem).when(itemManagerMock).get(ITEM1_ID); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + } + + @Test + public void shouldReturnWorkflowVersionWhenExist() { + WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); + doReturn(workflowVersion).when(versionMapperMock).fromVersion(any(Version.class)); + doReturn(new Version()).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), eq(VERSION1_ID), any(ParameterRole.class)); + workflowVersionManager.get(ITEM1_ID, VERSION1_ID); + verify(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + } + + @Test + public void shouldReturnWorkflowVersionList() { + InternalVersion version1 = createRetrievedVersion(VERSION1_ID, VersionStatus.Certified); + InternalVersion version2 = createRetrievedVersion(VERSION2_ID, VersionStatus.Draft); + List<Version> versionList = Arrays.asList(version1, version2); + doReturn(versionList).when(versioningManagerMock).list(ITEM1_ID); + + WorkflowVersion workflowVersion1 = new WorkflowVersion(); + workflowVersion1.setId(VERSION1_ID); + workflowVersion1.setName(VERSION1_ID); + doReturn(workflowVersion1).when(versionMapperMock).fromVersion(version1); + + WorkflowVersion workflowVersion2 = new WorkflowVersion(); + workflowVersion2.setId(VERSION2_ID); + workflowVersion2.setName(VERSION2_ID); + doReturn(workflowVersion2).when(versionMapperMock).fromVersion(version2); + + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.INPUT)); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.OUTPUT)); + + workflowVersionManager.list(ITEM1_ID, null); + verify(versioningManagerMock).list(ITEM1_ID); + verify(versionMapperMock, times(2)).fromVersion(any(Version.class)); + } + + @Test + public void shouldReturnCertifiedWorkflowVersionList() { + InternalVersion version1 = createRetrievedVersion(VERSION1_ID, VersionStatus.Certified); + InternalVersion version2 = createRetrievedVersion(VERSION2_ID, VersionStatus.Draft); + List<Version> versionList = Arrays.asList(version1, version2); + + doReturn(versionList).when(versioningManagerMock).list(ITEM1_ID); + WorkflowVersion workflowVersion1 = new WorkflowVersion(); + workflowVersion1.setId(VERSION1_ID); + workflowVersion1.setName(VERSION1_ID); + doReturn(workflowVersion1).when(versionMapperMock).fromVersion(version1); + + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.INPUT)); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(eq(ITEM1_ID), anyString(), eq(ParameterRole.OUTPUT)); + doReturn(VersionStatus.Certified).when(versionStateMapperMock) + .workflowVersionStateToVersionStatus(WorkflowVersionState.CERTIFIED); + + assertEquals(1, + workflowVersionManager.list(ITEM1_ID, Collections.singleton(WorkflowVersionState.CERTIFIED)).size()); + verify(versioningManagerMock).list(ITEM1_ID); + verify(versionMapperMock, times(1)).fromVersion(any(Version.class)); + + } + + @Test + public void shouldUpdateWorkflowVersion() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + String updatedDescription = "WorkflowVersion description updated"; + InternalVersion retrievedVersion = new InternalVersion(); + retrievedVersion.setId(VERSION1_ID); + retrievedVersion.setName("1.0"); + retrievedVersion.setDescription("WorkflowVersion description"); + retrievedVersion.setStatus(VersionStatus.Draft); + VersionState versionState = new VersionState(); + versionState.setDirty(true); + retrievedVersion.setState(versionState); + doReturn(retrievedVersion).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(retrievedVersion.getStatus()); + doReturn(Collections.emptyList()).when(parameterRepositoryMock) + .list(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT); + + WorkflowVersion inputVersion = new WorkflowVersion(VERSION1_ID); + inputVersion.setName("1.0"); + inputVersion.setDescription(updatedDescription); + ParameterEntity toBeCreated = new ParameterEntity("Input1"); + inputVersion.setInputs(Collections.singleton(toBeCreated)); + ParameterEntity toBeUpdated = new ParameterEntity("Output1"); + inputVersion.setOutputs(Collections.singleton(toBeUpdated)); + + ParameterEntity toBeDeleted = new ParameterEntity("Output2"); + toBeDeleted.setId("parameter_id_1"); + Collection<ParameterEntity> currentOutputs = Arrays.asList(toBeDeleted, toBeUpdated); + doReturn(currentOutputs).when(parameterRepositoryMock).list(ITEM1_ID, VERSION1_ID, ParameterRole.OUTPUT); + + doAnswer(invocationOnMock -> { + WorkflowVersion workflowVersion = invocationOnMock.getArgument(0); + Version version = invocationOnMock.getArgument(1); + version.setDescription(workflowVersion.getDescription()); + return null; + }).when(versionMapperMock).toVersion(inputVersion, retrievedVersion); + + ArgumentCaptor<Version> versionArgCaptor = ArgumentCaptor.forClass(Version.class); + workflowVersionManager.update(ITEM1_ID, inputVersion); + + verify(versioningManagerMock).update(eq(ITEM1_ID), eq(VERSION1_ID), versionArgCaptor.capture()); + Version captorVersion = versionArgCaptor.getValue(); + assertEquals("1.0", captorVersion.getName()); + assertEquals(updatedDescription, captorVersion.getDescription()); + assertEquals(VersionStatus.Draft, captorVersion.getStatus()); + verify(versioningManagerMock).publish(ITEM1_ID, VERSION1_ID, "Update version"); + + verify(parameterRepositoryMock).delete(ITEM1_ID, VERSION1_ID, "parameter_id_1"); + verify(parameterRepositoryMock).create(ITEM1_ID, VERSION1_ID, ParameterRole.INPUT, toBeCreated); + verify(parameterRepositoryMock).update(ITEM1_ID, VERSION1_ID, ParameterRole.OUTPUT, toBeUpdated); + + } + + + @Test + public void shouldCreateWorkflowVersion() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + Version version = createRetrievedVersion(VERSION1_ID, VersionStatus.Draft); + doReturn(version).when(versioningManagerMock) + .create(eq(ITEM1_ID), isNull(), any(Version.class), eq(VersionCreationMethod.major)); + + WorkflowVersion versionRequest = new WorkflowVersion(); + versionRequest.setDescription("version desc"); + versionRequest.setInputs(Collections.emptyList()); + versionRequest.setOutputs(Collections.emptyList()); + WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); + doReturn(workflowVersion).when(workflowVersionManager).get(ITEM1_ID, VERSION1_ID); + + workflowVersionManager.create(ITEM1_ID, null, versionRequest); + } + + @Test(expected = VersionCreationException.class) + public void shouldTrowExceptionWhenDraftVersionExists() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + WorkflowVersion versionRequestDto = new WorkflowVersion(); + + Version baseVersion = createRetrievedVersion(VERSION2_ID, VersionStatus.Draft); + List<Version> versions = Collections.singletonList(baseVersion); + doReturn(versions).when(versioningManagerMock).list(ITEM1_ID); + + workflowVersionManager.create(ITEM1_ID, VERSION2_ID, versionRequestDto); + } + + @Test(expected = VersionCreationException.class) + public void shouldTrowExceptionWhenInputsSupplied() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + WorkflowVersion versionRequestDto = new WorkflowVersion(); + versionRequestDto.setInputs(Collections.singleton(new ParameterEntity())); + InternalVersion baseVersion = createRetrievedVersion(VERSION2_ID, VersionStatus.Draft); + List<Version> versions = Collections.singletonList(baseVersion); + doReturn(versions).when(versioningManagerMock).list(ITEM1_ID); + + workflowVersionManager.create(ITEM1_ID, VERSION2_ID, versionRequestDto); + } + + + @Test(expected = EntityNotFoundException.class) + public void getStateOfNonExisting() { + doThrow(new RuntimeException()).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + workflowVersionManager.getState(ITEM1_ID, VERSION1_ID); + } + + @Test + public void getState() { + InternalVersion version = createRetrievedVersion(VERSION1_ID, VersionStatus.Certified); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(CERTIFIED).when(versionStateMapperMock).versionStatusToWorkflowVersionState(version.getStatus()); + + WorkflowVersionState state = workflowVersionManager.getState(ITEM1_ID, VERSION1_ID); + assertEquals(CERTIFIED, state); + } + + @Test(expected = EntityNotFoundException.class) + public void updateStateOfNonExisting() { + doThrow(new RuntimeException()).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); + } + + @Test(expected = VersionStateModificationException.class) + public void updateStateToCurrentState() { + InternalVersion version = createRetrievedVersion(VERSION1_ID, VersionStatus.Draft); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(version.getStatus()); + + workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, DRAFT); + } + + @Test(expected = VersionStateModificationMissingArtifactException.class) + public void updateStateWhenCertified() { + InternalVersion version = createRetrievedVersion(VERSION1_ID, VersionStatus.Certified); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(CERTIFIED).when(versionStateMapperMock).versionStatusToWorkflowVersionState(version.getStatus()); + + workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); + } + + @Test + public void shouldFailUpdateStateWhenNoArtifact() { + InternalVersion retrievedVersion = createRetrievedVersion(VERSION1_ID, VersionStatus.Draft); + doReturn(retrievedVersion).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(VersionStatus.Draft); + + exceptionRule.expect(VersionStateModificationMissingArtifactException.class); + exceptionRule.expectMessage(String.format( + VersionStateModificationMissingArtifactException.WORKFLOW_MODIFICATION_STATE_MISSING_ARTIFACT_TEMPLATE, + ITEM1_ID, VERSION1_ID, DRAFT, CERTIFIED)); + workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); + + verify(versioningManagerMock).updateStatus(ITEM1_ID, VERSION1_ID, VersionStatus.Certified, anyString()); + } + + @Test + public void shouldSuccessUpdateStateWhenArtifactExist() { + InternalVersion retrievedVersion = createRetrievedVersion(VERSION1_ID, VersionStatus.Draft); + doReturn(retrievedVersion).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(VersionStatus.Draft); + doReturn(true).when(artifactRepositoryMock).isExist(ITEM1_ID, VERSION1_ID); + workflowVersionManager.updateState(ITEM1_ID, VERSION1_ID, CERTIFIED); + verify(versioningManagerMock) + .updateStatus(eq(ITEM1_ID), eq(VERSION1_ID), eq(VersionStatus.Certified), anyString()); + } + + @Test + public void shouldUploadArtifact() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + InternalVersion version = createRetrievedVersion(VERSION1_ID, VersionStatus.Draft); + VersionState versionState = new VersionState(); + versionState.setDirty(false); + version.setState(versionState); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + doReturn(DRAFT).when(versionStateMapperMock).versionStatusToWorkflowVersionState(version.getStatus()); + + MockMultipartFile mockFile = new MockMultipartFile("data", "filename.txt", "text/plain", "some xml".getBytes()); + workflowVersionManager.uploadArtifact(ITEM1_ID, VERSION1_ID, mockFile); + + verify(artifactRepositoryMock).update(eq(ITEM1_ID), eq(VERSION1_ID), any(ArtifactEntity.class)); + } + + @Test(expected = EntityNotFoundException.class) + public void shouldThrowExceptionWhenArtifactNotFound() { + doReturn(new Version()).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + + doReturn(Optional.empty()).when(artifactRepositoryMock).get(ITEM1_ID, VERSION1_ID); + workflowVersionManager.getArtifact(ITEM1_ID, VERSION1_ID); + } + + @Test + public void shouldReturnArtifact() throws IOException { + doReturn(new Version()).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + + InputStream inputStreamMock = IOUtils.toInputStream("some test data for my input stream", "UTF-8"); + ArtifactEntity artifactMock = new ArtifactEntity("fileName.txt", inputStreamMock); + doReturn(Optional.of(artifactMock)).when(artifactRepositoryMock).get(ITEM1_ID, VERSION1_ID); + ArtifactEntity returnedArtifact = workflowVersionManager.getArtifact(ITEM1_ID, VERSION1_ID); + assertEquals(artifactMock, returnedArtifact); + } + + @Test(expected = VersionModificationException.class) + public void shouldThrowExceptionInDeleteArtifactWhenVersionIsCertified() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + Version version = new Version(); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); + workflowVersion.setState(WorkflowVersionState.CERTIFIED); + doReturn(workflowVersion).when(versionMapperMock).fromVersion(version); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + } + + @Test + public void shouldNotDeleteArtifactIfNotExist() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + Version version = new Version(); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); + doReturn(workflowVersion).when(versionMapperMock).fromVersion(version); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + verify(artifactRepositoryMock, times(0)).delete(ITEM1_ID, VERSION1_ID); + verify(versioningManagerMock, times(0)).publish(ITEM1_ID, VERSION1_ID, "Delete Artifact"); + } + + @Test + public void shouldDeleteArtifactIfExist() { + doNothing().when(workflowVersionManager).validateWorkflowStatus(ITEM1_ID); + Version version = new Version(); + doReturn(version).when(versioningManagerMock).get(ITEM1_ID, VERSION1_ID); + WorkflowVersion workflowVersion = new WorkflowVersion(VERSION1_ID); + doReturn(true).when(artifactRepositoryMock).isExist(ITEM1_ID, VERSION1_ID); + doReturn(workflowVersion).when(versionMapperMock).fromVersion(version); + workflowVersionManager.deleteArtifact(ITEM1_ID, VERSION1_ID); + verify(artifactRepositoryMock, times(1)).delete(ITEM1_ID, VERSION1_ID); + verify(versioningManagerMock, times(1)).publish(ITEM1_ID, VERSION1_ID, "Delete Artifact"); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/VersionMapperTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/VersionMapperTest.java new file mode 100644 index 00000000..8bffc3e1 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/VersionMapperTest.java @@ -0,0 +1,93 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import static org.junit.Assert.assertEquals; + +import java.util.Date; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.sdc.common.versioning.persistence.types.InternalVersion; +import org.onap.sdc.common.versioning.services.types.Version; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.onap.sdc.workflow.services.types.WorkflowVersion; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@ContextConfiguration(classes = VersionMapperTest.VersionMapperSpringTestConfig.class) +@RunWith(SpringJUnit4ClassRunner.class) +public class VersionMapperTest { + + @Configuration + @ComponentScan(basePackageClasses = {VersionMapper.class, VersionStateMapper.class}) + public static class VersionMapperSpringTestConfig { } + + @Autowired + VersionMapper versionMapper; + + @Test + public void shouldMapVersionToWorkflowVersion() { + Version version = createVersion(); + WorkflowVersion mappedWorkflowVersion = versionMapper.fromVersion(version); + assertEquals(mappedWorkflowVersion.getId(), version.getId()); + assertEquals(mappedWorkflowVersion.getBaseId(), version.getBaseId()); + assertEquals(mappedWorkflowVersion.getDescription(), version.getDescription()); + assertEquals(mappedWorkflowVersion.getName(), version.getName()); + assertEquals(mappedWorkflowVersion.getCreationTime(), version.getCreationTime()); + assertEquals(mappedWorkflowVersion.getModificationTime(), version.getModificationTime()); + } + + @Test + public void shouldMapWorkflowVersionToVersion() { + WorkflowVersion workflowVersion = createWorkflowVersion(); + Version mappedVersion = new Version(); + versionMapper.toVersion(workflowVersion, mappedVersion); + assertEquals(mappedVersion.getDescription(), workflowVersion.getDescription()); + + } + + private Version createVersion() { + InternalVersion version = new InternalVersion(); + version.setId("version_id"); + version.setBaseId("base_version_id"); + version.setName("1.0"); + version.setCreationTime(new Date()); + version.setModificationTime(new Date()); + version.setDescription("version_description"); + version.setStatus(VersionStatus.Draft); + + return version; + + } + + private WorkflowVersion createWorkflowVersion() { + WorkflowVersion workflowVersion = new WorkflowVersion(); + workflowVersion.setId("wf_version_id"); + workflowVersion.setBaseId("wf_base_version_id"); + workflowVersion.setName("1.0"); + workflowVersion.setCreationTime(new Date()); + workflowVersion.setModificationTime(new Date()); + workflowVersion.setDescription("version_description"); + workflowVersion.setState(WorkflowVersionState.CERTIFIED); + + return workflowVersion; + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapperTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapperTest.java new file mode 100644 index 00000000..c0804eb8 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/VersionStateMapperTest.java @@ -0,0 +1,84 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.sdc.workflow.services.types.WorkflowVersionState; +import org.onap.sdc.common.versioning.services.types.VersionStatus; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@ContextConfiguration(classes = VersionStateMapperTest.VersionStatusMapperSpringTestConfig.class) +@RunWith(SpringJUnit4ClassRunner.class) +public class VersionStateMapperTest { + + @Configuration + @ComponentScan(basePackageClasses = {VersionStateMapper.class}) + public static class VersionStatusMapperSpringTestConfig { } + + + @Autowired + VersionStateMapper versionStateMapper; + + @Test + public void shouldMapCertifiedVersionStatusToWorkflowVersionStatus() { + WorkflowVersionState mappedVersionStatus = + versionStateMapper.versionStatusToWorkflowVersionState(VersionStatus.Certified); + assertEquals(WorkflowVersionState.CERTIFIED, mappedVersionStatus); + } + + @Test + public void shouldMapDraftVersionStatusToWorkflowVersionStatus() { + WorkflowVersionState mappedVersionStatus = + versionStateMapper.versionStatusToWorkflowVersionState(VersionStatus.Draft); + assertEquals(WorkflowVersionState.DRAFT, mappedVersionStatus); + } + + @Test + public void shouldMapDeletedVersionStatusToWorkflowVersionStatus() { + WorkflowVersionState mappedVersionStatus = + versionStateMapper.versionStatusToWorkflowVersionState(VersionStatus.Deleted); + assertEquals(WorkflowVersionState.DRAFT, mappedVersionStatus); + } + + @Test + public void shouldMapDeprecatedVersionStatusToWorkflowVersionStatus() { + WorkflowVersionState mappedVersionStatus = + versionStateMapper.versionStatusToWorkflowVersionState(VersionStatus.Deprecated); + assertEquals(WorkflowVersionState.DRAFT, mappedVersionStatus); + } + + @Test + public void shouldMapCertifiedWorkflowVersionStatusToVersionStatus() { + VersionStatus mappedVersionStatus = + versionStateMapper.workflowVersionStateToVersionStatus(WorkflowVersionState.CERTIFIED); + assertEquals(VersionStatus.Certified, mappedVersionStatus); + } + + @Test + public void shouldMapDraftWorkflowVersionStatusToVersionStatus() { + VersionStatus mappedVersionStatus = + versionStateMapper.workflowVersionStateToVersionStatus(WorkflowVersionState.DRAFT); + assertEquals(VersionStatus.Draft, mappedVersionStatus); + } +} diff --git a/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapperTest.java b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapperTest.java new file mode 100644 index 00000000..ef84190a --- /dev/null +++ b/sdc-workflow-designer-be/src/test/java/org/onap/sdc/workflow/services/impl/mappers/WorkflowMapperTest.java @@ -0,0 +1,70 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.onap.sdc.workflow.services.impl.mappers; + + +import static org.junit.Assert.assertEquals; +import static org.onap.sdc.workflow.TestUtil.createItem; +import static org.onap.sdc.workflow.TestUtil.createWorkflow; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.sdc.common.versioning.services.types.Item; +import org.onap.sdc.common.versioning.services.types.ItemStatus; +import org.onap.sdc.workflow.services.impl.ItemType; +import org.onap.sdc.workflow.services.types.ArchivingStatus; +import org.onap.sdc.workflow.services.types.Workflow; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@ContextConfiguration(classes = WorkflowMapperTest.WorkflowMapperSpringTestConfig.class) +@RunWith(SpringJUnit4ClassRunner.class) +public class WorkflowMapperTest { + + @Configuration + @ComponentScan(basePackageClasses = {WorkflowMapper.class}) + public static class WorkflowMapperSpringTestConfig { } + + @Autowired + WorkflowMapper workflowMapper; + + @Test + public void shouldMapItemToWorkflow() { + + Item item = createItem(1, false, true, ItemStatus.ACTIVE); + Workflow mappedWorkflow = workflowMapper.fromItem(item); + assertEquals(mappedWorkflow.getId(), item.getId()); + assertEquals(mappedWorkflow.getDescription(), item.getDescription()); + assertEquals(mappedWorkflow.getName(), item.getName()); + assertEquals(mappedWorkflow.getArchiving().name(), item.getStatus().name()); + } + + @Test + public void shouldMapWorkflowToItem() { + + Workflow workflow = createWorkflow(1, true, ArchivingStatus.ARCHIVED); + Item mappedItem = new Item(); + workflowMapper.toItem(workflow, mappedItem); + assertEquals(ItemType.WORKFLOW.name(), mappedItem.getType()); + assertEquals(workflow.getDescription(), mappedItem.getDescription()); + assertEquals(workflow.getName(), mappedItem.getName()); + } + +} diff --git a/sdc-workflow-designer-be/src/test/resources/application-test.properties b/sdc-workflow-designer-be/src/test/resources/application-test.properties new file mode 100644 index 00000000..686013f0 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/resources/application-test.properties @@ -0,0 +1,10 @@ +sdc.be.protocol=${SDC_PROTOCOL:http} +sdc.be.endpoint=${SDC_ENDPOINT:localhost:8080} +sdc.be.external.user=${SDC_USER:cs0008} +sdc.be.external.password=${SDC_PASSWORD:Aa123456} + +#CASSANDRA +spring.data.cassandra.contact-points=${CS_HOSTS:localhost} +spring.data.cassandra.keyspace-name=workflow +spring.data.cassandra.port=${CS_PORT:9042} +zusammen.cassandra.isAuthenticate=${CS_AUTHENTICATE:false}
\ No newline at end of file diff --git a/sdc-workflow-designer-be/src/test/resources/logback-test.xml b/sdc-workflow-designer-be/src/test/resources/logback-test.xml new file mode 100644 index 00000000..f9fa3d88 --- /dev/null +++ b/sdc-workflow-designer-be/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ +<configuration> + + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> + </encoder> + </appender> + + <root level="OFF"> + <appender-ref ref="STDOUT" /> + </root> + +</configuration>
\ No newline at end of file |