diff options
-rw-r--r-- | workflow-designer-be/docker/Dockerfile | 17 | ||||
-rw-r--r-- | workflow-designer-be/docker/org.onap.sdc.p12 | bin | 0 -> 4459 bytes | |||
-rw-r--r-- | workflow-designer-be/docker/org.onap.sdc.trust.jks | bin | 0 -> 1413 bytes | |||
-rw-r--r-- | workflow-designer-be/docker/startup.sh | 28 | ||||
-rw-r--r-- | workflow-designer-be/pom.xml | 50 | ||||
-rw-r--r-- | workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java | 108 | ||||
-rw-r--r-- | workflow-designer-be/src/main/resources/application.properties | 7 |
7 files changed, 182 insertions, 28 deletions
diff --git a/workflow-designer-be/docker/Dockerfile b/workflow-designer-be/docker/Dockerfile new file mode 100644 index 00000000..ea20fa5c --- /dev/null +++ b/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/workflow-designer-be/docker/org.onap.sdc.p12 b/workflow-designer-be/docker/org.onap.sdc.p12 Binary files differnew file mode 100644 index 00000000..d03ca1c9 --- /dev/null +++ b/workflow-designer-be/docker/org.onap.sdc.p12 diff --git a/workflow-designer-be/docker/org.onap.sdc.trust.jks b/workflow-designer-be/docker/org.onap.sdc.trust.jks Binary files differnew file mode 100644 index 00000000..d07ce1a6 --- /dev/null +++ b/workflow-designer-be/docker/org.onap.sdc.trust.jks diff --git a/workflow-designer-be/docker/startup.sh b/workflow-designer-be/docker/startup.sh new file mode 100644 index 00000000..bc1d6463 --- /dev/null +++ b/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/workflow-designer-be/pom.xml b/workflow-designer-be/pom.xml index 9bf4e75d..601f10ee 100644 --- a/workflow-designer-be/pom.xml +++ b/workflow-designer-be/pom.xml @@ -121,6 +121,10 @@ </exclusions> </dependency> <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpclient</artifactId> + </dependency> + <dependency> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-jdk8</artifactId> <version>${mapstruct.version}</version> @@ -175,6 +179,28 @@ <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> @@ -185,20 +211,26 @@ <tags> <tag>${project.version}</tag> </tags> - <from>openjdk:8-jdk-alpine</from> - <user>root</user> - <assembly> - <targetDir>/</targetDir> - <descriptor>${project.basedir}/src/main/resources/assembly.xml</descriptor> - </assembly> - <entryPoint> - java ${JAVA_OPTIONS} -jar /${project.build.finalName}.jar - </entryPoint> + <dockerFileDir>${project.basedir}/docker</dockerFileDir> + <args> + <ARTIFACT>${project.build.finalName}.jar</ARTIFACT> + </args> </build> </image> </images> </configuration> </plugin> + <plugin> + <groupId>org.sonatype.plugins</groupId> + <artifactId>nexus-staging-maven-plugin</artifactId> + <version>1.6.8</version> + <extensions>true</extensions> + <configuration> + <serverId>onap-staging</serverId> + <nexusUrl>${nexus.proxy}</nexusUrl> + <stagingProfileId>${staging.profile.id}</stagingProfileId> + </configuration> + </plugin> </plugins> </build> </profile> diff --git a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java index 621d1803..2b24577a 100644 --- a/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java +++ b/workflow-designer-be/src/main/java/org/onap/sdc/workflow/api/ArtifactAssociationService.java @@ -19,30 +19,47 @@ 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.Base64; 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.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.Value; import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; +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 { @@ -54,6 +71,8 @@ public class ArtifactAssociationService { 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; @@ -66,12 +85,63 @@ public class ArtifactAssociationService { 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) { - this.restClient = builder.build(); + 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) { + void setRestClient(RestTemplate restClient) { this.restClient = restClient; } @@ -80,12 +150,12 @@ public class ArtifactAssociationService { } ResponseEntity<String> execute(String userId, ArtifactDeliveriesRequestDto deliveriesRequestDto, - ArtifactEntity artifactEntity) { + 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())); + 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; @@ -96,7 +166,7 @@ public class ArtifactAssociationService { return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(e.getMessage()); } - HttpEntity<String> request = new HttpEntity<>(formattedArtifact, createHeaders(userId,formattedArtifact)); + HttpEntity<String> request = new HttpEntity<>(formattedArtifact, createHeaders(userId, formattedArtifact)); return restClient.exchange(sdcBeProtocol + "://" + sdcBeEndpoint + "/" + deliveriesRequestDto.getEndpoint(), HttpMethod.valueOf(deliveriesRequestDto.getMethod()), request, String.class); @@ -117,7 +187,7 @@ public class ArtifactAssociationService { result.add("SDC_PASSWORD"); } - if (result.isEmpty()) { + if (result.isEmpty() || this.restClient == null) { return Optional.empty(); } else { return Optional.of(result.toString()); @@ -143,7 +213,7 @@ public class ArtifactAssociationService { 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.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"); diff --git a/workflow-designer-be/src/main/resources/application.properties b/workflow-designer-be/src/main/resources/application.properties index 44b048ac..5a4b7af7 100644 --- a/workflow-designer-be/src/main/resources/application.properties +++ b/workflow-designer-be/src/main/resources/application.properties @@ -19,8 +19,15 @@ 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:} |