diff options
Diffstat (limited to 'src/main')
11 files changed, 203 insertions, 52 deletions
diff --git a/src/main/bin/start.sh b/src/main/bin/start.sh index 155cb55..d68d6c8 100644 --- a/src/main/bin/start.sh +++ b/src/main/bin/start.sh @@ -19,36 +19,40 @@ # limitations under the License. # ============LICENSE_END========================================================= -# jre-alpine image has $JAVA_HOME set and added to $PATH -# ubuntu image requires to set $JAVA_HOME and add java to $PATH manually -if ( uname -v | grep -i "ubuntu" ); then - export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-`dpkg --print-architecture | awk -F- '{ print $NF }'` - export PATH=${JAVA_HOME}:$PATH -fi - APP_HOME="${APP_HOME:-/opt/app/babel}" +mkdir -p ${APP_HOME}/logs/gc if [ -z "${CONFIG_HOME}" ]; then echo "CONFIG_HOME must be set in order to start the process" exit 1 fi -if [ -z "${KEY_STORE_PASSWORD}" ]; then - echo "KEY_STORE_PASSWORD must be set in order to start the process" +#Either keystore password or server certs location must be passed. Both cannot be null +if [ -z "${KEY_STORE_PASSWORD}" -a -z "${SERVER_CERTS_LOCATION}" ]; then + echo "KEY_STORE_PASSWORD or SERVER_CERTS_LOCATION must be set in order to start the process" exit 1 fi PROPS="-DAPP_HOME=${APP_HOME}" PROPS="${PROPS} -DCONFIG_HOME=${CONFIG_HOME}" PROPS="${PROPS} -Dtosca.mappings.config=${CONFIG_HOME}/tosca-mappings.json" -PROPS="${PROPS} -DKEY_STORE_PASSWORD=${KEY_STORE_PASSWORD}" + +if [ ! -z "$KEY_STORE_PASSWORD" ]; then + PROPS="${PROPS} -DKEY_STORE_PASSWORD=${KEY_STORE_PASSWORD}" +fi + PROPS="${PROPS} -Dlogging.config=${APP_HOME}/config/logback.xml" + if [ ! -z "$REQUIRE_CLIENT_AUTH" ]; then PROPS="$PROPS -Dserver.ssl.client-auth=${REQUIRE_CLIENT_AUTH}" fi +if [ ! -z "$SERVER_CERTS_LOCATION" ]; then + PROPS="$PROPS -Dserver.certs.location=${SERVER_CERTS_LOCATION}" + PROPS="$PROPS -Dserver.ssl.key-store=${SERVER_CERTS_LOCATION}/${SERVER_KEY_STORE}" + PROPS="$PROPS -Dserver.ssl.trust-store=${SERVER_CERTS_LOCATION}/${SERVER_TRUST_STORE}" +fi +PROPS="${PROPS} -Dspring.profiles.active=${SPRING_PROFILES_ACTIVE}" +PROPS="${PROPS} -Daaf.cadi.file=${CONFIG_HOME}/cadi.properties" -JVM_MAX_HEAP=${MAX_HEAP:-1024} - -JARFILE=$(ls ./babel*.jar); +exec java ${JVM_OPTS} ${PROPS} -jar ${APP_HOME}/babel*.jar -exec java -Xmx${JVM_MAX_HEAP}m ${PROPS} -jar ${APP_HOME}/${JARFILE} diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile index 369d1b5..623cfd8 100644 --- a/src/main/docker/Dockerfile +++ b/src/main/docker/Dockerfile @@ -1,21 +1,23 @@ -FROM @aai.docker.namespace@/aai-common-@aai.base.image@:@aai.base.image.version@ +FROM @docker.push.registry@/@aai.docker.namespace@/aai-common-@aai.base.image@:@aai.base.image.version@ ARG MICRO_HOME=/opt/app/babel # Build up the deployment folder structure -RUN mkdir -p $MICRO_HOME $MICRO_HOME/logs - -RUN groupadd aaiadmin -g 1000 -RUN adduser -u 1000 -h /opt/aaihome/aaiadmin -S -D -G aaiadmin -s /bin/bash aaiadmin +#RUN groupadd aaiadmin -g 1000 +#RUN adduser -u 1000 -h /opt/aaihome/aaiadmin -S -D -G aaiadmin -s /bin/bash aaiadmin WORKDIR $MICRO_HOME -RUN chown -R aaiadmin:aaiadmin $MICRO_HOME $MICRO_HOME/logs +USER root -COPY --chown=aaiadmin:aaiadmin /maven/babel/ . +# Create the aai user +RUN mkdir -p /opt/aaihome $MICRO_HOME /logs && \ + ln -s /logs $MICRO_HOME/logs && \ + chown -R aaiadmin:aaiadmin $MICRO_HOME && \ + chown -R aaiadmin:aaiadmin /logs -USER aaiadmin +COPY --chown=aaiadmin:aaiadmin /maven/babel/ . +# The start script is executable and can be run directly. -RUN chmod 755 bin/* \ - && ln -s /logs $MICRO_HOME/logs +ENTRYPOINT ["/sbin/tini", "--", "/bin/bash", "/opt/app/babel/bin/start.sh"] -CMD ["/opt/app/babel/bin/start.sh"] +USER aaiadmin diff --git a/src/main/java/org/onap/aai/babel/BabelApplication.java b/src/main/java/org/onap/aai/babel/BabelApplication.java index b3eaee4..71fe7e0 100644 --- a/src/main/java/org/onap/aai/babel/BabelApplication.java +++ b/src/main/java/org/onap/aai/babel/BabelApplication.java @@ -21,17 +21,20 @@ package org.onap.aai.babel; -import com.google.common.collect.ImmutableMap; -import org.eclipse.jetty.util.security.Password; +import org.onap.aai.babel.config.PropertyPasswordConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.ImportResource; @SpringBootApplication @ImportResource("classpath:babel-beans.xml") +@ComponentScan(basePackages = { + "org.onap.aai.aaf", + "org.onap.aai.babel" +}) public class BabelApplication extends SpringBootServletInitializer { private static ConfigurableApplicationContext context; @@ -47,12 +50,17 @@ public class BabelApplication extends SpringBootServletInitializer { if (keyStorePassword == null || keyStorePassword.isEmpty()) { throw new IllegalArgumentException("Mandatory property KEY_STORE_PASSWORD not set"); } - ImmutableMap<String, Object> defaults = - ImmutableMap.of("server.ssl.key-store-password", new Password(keyStorePassword).toString()); - - context = new BabelApplication() // - .configure(new SpringApplicationBuilder(BabelApplication.class).properties(defaults)) // - .run(args); + try { + SpringApplication app = new SpringApplication(BabelApplication.class); + app.setLogStartupInfo(false); + app.setRegisterShutdownHook(true); + app.addInitializers(new PropertyPasswordConfiguration()); + context = app.run(args); + } + catch(Exception ex){ + ex.printStackTrace(); + throw ex; + } } public static void exit() { diff --git a/src/main/java/org/onap/aai/babel/config/PropertyPasswordConfiguration.java b/src/main/java/org/onap/aai/babel/config/PropertyPasswordConfiguration.java new file mode 100644 index 0000000..c8efa01 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/config/PropertyPasswordConfiguration.java @@ -0,0 +1,121 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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========================================================= + */ +package org.onap.aai.babel.config; + +import org.apache.commons.io.IOUtils; +import org.eclipse.jetty.util.security.Password; +import org.onap.aai.babel.logging.LogHelper; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.MapPropertySource; +import org.springframework.core.env.PropertySource; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +public class PropertyPasswordConfiguration implements ApplicationContextInitializer<ConfigurableApplicationContext> { + + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + + Map<String, Object> sslProps = new LinkedHashMap<>(); + ConfigurableEnvironment environment = applicationContext.getEnvironment(); + String certPath = environment.getProperty("server.certs.location"); + File passwordFile = null; + File passphrasesFile = null; + InputStream passwordStream = null; + InputStream passphrasesStream = null; + String keystorePassword = null; + String truststorePassword = null; + + if (certPath != null) { + try { + passwordFile = new File(certPath + ".password"); + passwordStream = new FileInputStream(passwordFile); + + if (passwordStream != null) { + keystorePassword = IOUtils.toString(passwordStream); + if (keystorePassword != null) { + keystorePassword = keystorePassword.trim(); + } + sslProps.put("server.ssl.key-store-password", keystorePassword); + } + } catch (IOException e) { + } finally { + if (passwordStream != null) { + try { + passwordStream.close(); + } catch (Exception e) { + } + } + } + try { + passphrasesFile = new File(certPath + ".passphrases"); + passphrasesStream = new FileInputStream(passphrasesFile); + + if (passphrasesStream != null) { + Properties passphrasesProps = new Properties(); + passphrasesProps.load(passphrasesStream); + truststorePassword = passphrasesProps.getProperty("cadi_truststore_password"); + if (truststorePassword != null) { + truststorePassword = truststorePassword.trim(); + } + sslProps.put("server.ssl.trust-store-password", truststorePassword); + } else { + } + } catch (IOException e) { + } finally { + if (passphrasesStream != null) { + try { + passphrasesStream.close(); + } catch (Exception e) { + } + } + } + } + if (keystorePassword == null || keystorePassword.isEmpty()) { + keystorePassword = System.getProperty("KEY_STORE_PASSWORD"); + if (keystorePassword != null && (!keystorePassword.isEmpty()) ) { + System.setProperty("server.ssl.key-store-password", new Password(keystorePassword).toString()); + } + if (keystorePassword == null || keystorePassword.isEmpty()) { + throw new IllegalArgumentException("Mandatory property KEY_STORE_PASSWORD not set"); + } + } + else { + sslProps.put("server.ssl.key-store-password", keystorePassword); + } + if (truststorePassword == null || truststorePassword.isEmpty()) { + } + else { + sslProps.put("server.ssl.trust-store-password", truststorePassword); + } + if (!sslProps.isEmpty()) { + PropertySource<?> additionalProperties = new MapPropertySource("additionalProperties", sslProps); + environment.getPropertySources().addFirst(additionalProperties); + } + } +} diff --git a/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java b/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java index 6115f8f..18d294e 100644 --- a/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java +++ b/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java @@ -72,7 +72,7 @@ public class CsarToXmlConverter { try { List<Artifact> ymlFiles = yamlExtractor.extract(csarArchive, name, version); xmlArtifacts = new ModelGenerator().generateArtifacts(csarArchive, ymlFiles); - logger.debug(xmlArtifacts.size() + " XML artifact(s) have been generated"); + logger.info(ApplicationMsgs.DISTRIBUTION_EVENT,xmlArtifacts.size() + " XML artifact(s) have been generated"); } catch (InvalidArchiveException e) { throw new CsarConverterException( "An error occurred trying to extract the YAML files from the CSAR file : " + e); @@ -80,7 +80,7 @@ public class CsarToXmlConverter { throw new CsarConverterException( "An error occurred trying to generate XML files from a collection of YAML files : " + e); } finally { - logger.logMetrics(stopwatch, LogHelper.getCallerMethodName(0)); + } return xmlArtifacts; diff --git a/src/main/java/org/onap/aai/babel/csar/vnfcatalog/VnfVendorImageExtractor.java b/src/main/java/org/onap/aai/babel/csar/vnfcatalog/VnfVendorImageExtractor.java index 870c8c3..8973f57 100644 --- a/src/main/java/org/onap/aai/babel/csar/vnfcatalog/VnfVendorImageExtractor.java +++ b/src/main/java/org/onap/aai/babel/csar/vnfcatalog/VnfVendorImageExtractor.java @@ -44,6 +44,8 @@ import org.onap.sdc.tosca.parser.exceptions.SdcToscaParserException; import org.onap.sdc.tosca.parser.impl.SdcToscaParserFactory; import org.onap.sdc.toscaparser.api.NodeTemplate; +import javax.ws.rs.core.Response; + /** * This class is responsible for extracting Virtual Network Function (VNF) information from a TOSCA 1.1 CSAR package. * @@ -158,7 +160,6 @@ public class VnfVendorImageExtractor { } applicationLogger.info(ApplicationMsgs.DISTRIBUTION_EVENT, vendorImageConfigurations.toString()); - applicationLogger.logMetrics(stopwatch, LogHelper.getCallerMethodName(0)); return ConfigurationsToBabelArtifactConverter.convert(vendorImageConfigurations); } @@ -221,6 +222,8 @@ public class VnfVendorImageExtractor { try { return createVendorImageConfigurations(serviceVfList, vnfConfigurationNode); } catch (IllegalArgumentException e) { + applicationLogger.setContextValue(LogHelper.MdcParameter.RESPONSE_CODE, String.valueOf(Response.Status.BAD_REQUEST.getStatusCode())); + applicationLogger.setContextValue(LogHelper.MdcParameter.RESPONSE_DESCRIPTION, "Invalid Csar"); applicationLogger.error(ApplicationMsgs.INVALID_CSAR_FILE, e); throw new ToscaToCatalogException(e.getMessage()); } @@ -240,7 +243,7 @@ public class VnfVendorImageExtractor { * @return a new List of Vendor Image Configurations */ private List<VendorImageConfiguration> createVendorImageConfigurations(List<NodeTemplate> serviceVfList, - NodeTemplate vnfConfigurationNode) { + NodeTemplate vnfConfigurationNode) throws IllegalArgumentException{ List<VendorImageConfiguration> vendorImageConfigurations = Collections.emptyList(); Object allowedFlavorProperties = @@ -276,7 +279,7 @@ public class VnfVendorImageExtractor { * version strings */ Stream<VendorImageConfiguration> buildVendorImageConfigurations( - Collection<Map<String, Map<String, String>>> flavorMaps, NodeTemplate vfNodeTemplate) { + Collection<Map<String, Map<String, String>>> flavorMaps, NodeTemplate vfNodeTemplate) throws IllegalArgumentException { String resourceVendor = vfNodeTemplate.getMetaData().getValue("resourceVendor"); applicationLogger.debug("Resource Vendor " + resourceVendor); diff --git a/src/main/java/org/onap/aai/babel/logging/LogHelper.java b/src/main/java/org/onap/aai/babel/logging/LogHelper.java index c118d8a..b9fa351 100644 --- a/src/main/java/org/onap/aai/babel/logging/LogHelper.java +++ b/src/main/java/org/onap/aai/babel/logging/LogHelper.java @@ -388,7 +388,7 @@ public enum LogHelper implements Logger { @Override public void info(@SuppressWarnings("rawtypes") Enum errorCode, String... args) { if (isInfoEnabled()) { - invokeErrorCodeLogger(errorLogger::info, (EELFResolvableErrorEnum) errorCode, args); + invokeErrorCodeLogger(debugLogger::info, (EELFResolvableErrorEnum) errorCode, args); } } diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java index 6655170..4fac909 100644 --- a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java +++ b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java @@ -29,12 +29,9 @@ import java.util.List; import java.util.UUID; import javax.inject.Inject; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.PathSegment; -import javax.ws.rs.core.Response; +import javax.ws.rs.core.*; import javax.ws.rs.core.Response.Status; -import javax.ws.rs.core.UriInfo; + import org.apache.commons.lang3.time.StopWatch; import org.onap.aai.auth.AAIAuthException; import org.onap.aai.auth.AAIMicroServiceAuth; @@ -99,7 +96,7 @@ public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { applicationLogger.info(ApplicationMsgs.BABEL_REQUEST_PAYLOAD, requestHeaders.toString()); String requestId = requestHeaders.getCorrelationId(); - if (requestId == null) { + if (requestId == null || !isRequestIDValid(requestId)) { requestId = UUID.randomUUID().toString(); applicationLogger.info(ApplicationMsgs.MISSING_REQUEST_ID, requestId); applicationLogger.setContextValue(MdcParameter.REQUEST_ID, requestId); @@ -136,6 +133,15 @@ public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { return response; } + private boolean isRequestIDValid(String requestId) { + try { + UUID.fromString(requestId); + } catch (IllegalArgumentException e) { + return false; + } + return true; + } + /** * Generate XML model artifacts from request body. * @@ -165,6 +171,7 @@ public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { } response = buildResponse(Status.OK, gson.toJson(babelArtifacts)); + applicationLogger.info(ApplicationMsgs.DISTRIBUTION_EVENT,LogHelper.getCallerMethodName(0)); } catch (JsonSyntaxException e) { response = processError(ApplicationMsgs.INVALID_REQUEST_JSON, Status.BAD_REQUEST, e, "Malformed request."); } catch (CsarConverterException e) { @@ -177,15 +184,16 @@ public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { response = processError(ApplicationMsgs.PROCESS_REQUEST_ERROR, Status.BAD_REQUEST, // e, e.getLocalizedMessage()); } finally { - applicationLogger.logMetrics(stopwatch, LogHelper.getCallerMethodName(0)); + applicationLogger.debug(stopwatch + LogHelper.getCallerMethodName(0)); } return response; } private Response processError(ApplicationMsgs applicationMsgs, Status responseStatus, Exception e, String message) { + applicationLogger.setContextValue(MdcParameter.RESPONSE_CODE, String.valueOf(responseStatus.getStatusCode())); + applicationLogger.setContextValue(MdcParameter.RESPONSE_DESCRIPTION, responseStatus.getReasonPhrase()); applicationLogger.error(applicationMsgs, e); - return buildResponse(responseStatus, message); } diff --git a/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java b/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java index 6695241..f94da4a 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java @@ -36,15 +36,17 @@ import org.onap.aai.babel.xml.generator.data.Artifact; import org.onap.aai.babel.xml.generator.data.GenerationData; import org.onap.aai.babel.xml.generator.data.GeneratorUtil; import org.onap.aai.babel.xml.generator.data.GroupType; -import org.onap.aai.cl.api.Logger; +import javax.ws.rs.core.Response; /** * This class is responsible for generating XML model artifacts from a collection of CSAR artifacts. */ public class ModelGenerator implements ArtifactGenerator { - private static final Logger logger = LogHelper.INSTANCE; + private static final LogHelper logger = LogHelper.INSTANCE; + private static final String VERSION_DELIMITER = "."; + private static final String VERSION_DELIMITER_REGEXP = "\\" + VERSION_DELIMITER; private static final String DEFAULT_SERVICE_VERSION = "1.0"; /** @@ -117,6 +119,8 @@ public class ModelGenerator implements ArtifactGenerator { try { return String.valueOf(Float.parseFloat(artifactVersion)); } catch (Exception e) { + logger.setContextValue(LogHelper.MdcParameter.RESPONSE_CODE, String.valueOf(Response.Status.BAD_REQUEST.getStatusCode())); + logger.setContextValue(LogHelper.MdcParameter.RESPONSE_DESCRIPTION, "Invalid Artifact version"); logger.warn(ApplicationMsgs.DISTRIBUTION_EVENT, "Error generating service version from artifact version: " + artifactVersion + ". Using default service version of: " + DEFAULT_SERVICE_VERSION + ". Error details: " diff --git a/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java b/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java index ee04abc..8f71f2b 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java @@ -32,6 +32,8 @@ import org.onap.aai.babel.xml.generator.types.ModelType; public class Widget extends Model { + public static final String GENERATOR_AAI_CONFIGLPROP_NOT_FOUND = "Cannot generate artifacts. Widget configuration not found for %s"; + private Set<String> keys = new HashSet<>(); protected String name; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 9a7d699..6ea9b37 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,8 +2,7 @@ server.port=9516 server.ssl.key-store=${CONFIG_HOME}/auth/tomcat_keystore server.ssl.client-auth=need +spring.main.allow-bean-definition-overriding=true server.servlet.context-path=/services/babel-service - logging.config=${CONFIG_HOME}/logback.xml - tosca.mappings.config=${CONFIG_HOME}/tosca-mappings.json |