From 1433a67a9e3dcad20d0dda8edcaad9403320f4f9 Mon Sep 17 00:00:00 2001 From: Edwin Lawrance Date: Fri, 22 Sep 2017 16:55:07 +0100 Subject: Initial code submit for Babel Change-Id: I3738ebe15eadbbd6d16e24e374c6e40c535b425d Issue-ID: AAI-46 Signed-off-by: Edwin Lawrance --- .../ajsc/babel_v1/babel/v1/conf/babel-beans.xml | 35 +++ src/main/ajsc/babel_v1/babel/v1/docs/README.txt | 1 + src/main/ajsc/babel_v1/babel/v1/lib/README.txt | 1 + src/main/ajsc/babel_v1/babel/v1/props/module.props | 1 + .../babel_v1/babel/v1/routes/babel-service.route | 4 + src/main/assemble/ajsc_module_assembly.xml | 69 +++++ src/main/assemble/ajsc_props_assembly.xml | 26 ++ src/main/assemble/ajsc_runtime_assembly.xml | 47 ++++ src/main/bin/start.sh | 50 ++++ src/main/config/ajsc-chef.jks | Bin 0 -> 5256 bytes src/main/config/ajsc-jetty.xml | 128 +++++++++ src/main/config/ajsc-override-web.xml | 53 ++++ src/main/config/ajscJetty.jks | Bin 0 -> 3736 bytes src/main/config/cadi.properties | 36 +++ src/main/config/jul-redirect.properties | 13 + src/main/config/keyfile | 27 ++ src/main/config/runner-web.xml | 97 +++++++ src/main/docker/Dockerfile | 24 ++ .../java/org/onap/aai/auth/AAIAuthException.java | 39 +++ .../org/onap/aai/auth/AAIMicroServiceAuth.java | 121 +++++++++ .../org/onap/aai/auth/AAIMicroServiceAuthCore.java | 287 +++++++++++++++++++++ src/main/java/org/onap/aai/auth/FileWatcher.java | 63 +++++ .../org/onap/aai/babel/config/BabelAuthConfig.java | 51 ++++ .../aai/babel/csar/CsarConverterException.java | 40 +++ .../onap/aai/babel/csar/CsarToXmlConverter.java | 88 +++++++ .../csar/extractor/InvalidArchiveException.java | 50 ++++ .../aai/babel/csar/extractor/YamlExtractor.java | 149 +++++++++++ .../onap/aai/babel/logging/ApplicationMsgs.java | 50 ++++ .../babel/service/GenerateArtifactsService.java | 51 ++++ .../service/GenerateArtifactsServiceImpl.java | 148 +++++++++++ .../onap/aai/babel/service/data/BabelArtifact.java | 63 +++++ .../onap/aai/babel/service/data/BabelRequest.java | 53 ++++ .../aai/babel/util/RequestValidationException.java | 42 +++ .../org/onap/aai/babel/util/RequestValidator.java | 50 ++++ .../aai/babel/xml/generator/ArtifactGenerator.java | 39 +++ .../aai/babel/xml/generator/ModelGenerator.java | 136 ++++++++++ .../generator/XmlArtifactGenerationException.java | 40 +++ .../resources/babel-logging-resources.properties | 59 +++++ ...ame__#__module.ajsc.namespace.version__.context | 1 + src/main/runtime/context/default#0.context | 1 + ...e.name__#__module.ajsc.namespace.version__.json | 1 + src/main/runtime/shiroRole/ajscadmin.json | 1 + ...ontextadmin#__module.ajsc.namespace.name__.json | 1 + .../runtime/shiroRole/contextadmin#default.json | 1 + src/main/runtime/shiroUser/ajsc.json | 1 + src/main/runtime/shiroUserRole/ajsc#ajscadmin.json | 1 + ...ontextadmin#__module.ajsc.namespace.name__.json | 1 + .../shiroUserRole/ajsc#contextadmin#default.json | 1 + 48 files changed, 2241 insertions(+) create mode 100644 src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml create mode 100644 src/main/ajsc/babel_v1/babel/v1/docs/README.txt create mode 100644 src/main/ajsc/babel_v1/babel/v1/lib/README.txt create mode 100644 src/main/ajsc/babel_v1/babel/v1/props/module.props create mode 100644 src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route create mode 100644 src/main/assemble/ajsc_module_assembly.xml create mode 100644 src/main/assemble/ajsc_props_assembly.xml create mode 100644 src/main/assemble/ajsc_runtime_assembly.xml create mode 100644 src/main/bin/start.sh create mode 100644 src/main/config/ajsc-chef.jks create mode 100644 src/main/config/ajsc-jetty.xml create mode 100644 src/main/config/ajsc-override-web.xml create mode 100644 src/main/config/ajscJetty.jks create mode 100644 src/main/config/cadi.properties create mode 100644 src/main/config/jul-redirect.properties create mode 100644 src/main/config/keyfile create mode 100644 src/main/config/runner-web.xml create mode 100644 src/main/docker/Dockerfile create mode 100644 src/main/java/org/onap/aai/auth/AAIAuthException.java create mode 100644 src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java create mode 100644 src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java create mode 100644 src/main/java/org/onap/aai/auth/FileWatcher.java create mode 100644 src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java create mode 100644 src/main/java/org/onap/aai/babel/csar/CsarConverterException.java create mode 100644 src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java create mode 100644 src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java create mode 100644 src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java create mode 100644 src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java create mode 100644 src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java create mode 100644 src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java create mode 100644 src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java create mode 100644 src/main/java/org/onap/aai/babel/service/data/BabelRequest.java create mode 100644 src/main/java/org/onap/aai/babel/util/RequestValidationException.java create mode 100644 src/main/java/org/onap/aai/babel/util/RequestValidator.java create mode 100644 src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java create mode 100644 src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java create mode 100644 src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java create mode 100644 src/main/resources/babel-logging-resources.properties create mode 100644 src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context create mode 100644 src/main/runtime/context/default#0.context create mode 100644 src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json create mode 100644 src/main/runtime/shiroRole/ajscadmin.json create mode 100644 src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json create mode 100644 src/main/runtime/shiroRole/contextadmin#default.json create mode 100644 src/main/runtime/shiroUser/ajsc.json create mode 100644 src/main/runtime/shiroUserRole/ajsc#ajscadmin.json create mode 100644 src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json create mode 100644 src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json (limited to 'src/main') diff --git a/src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml b/src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml new file mode 100644 index 0000000..f4cc32c --- /dev/null +++ b/src/main/ajsc/babel_v1/babel/v1/conf/babel-beans.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/ajsc/babel_v1/babel/v1/docs/README.txt b/src/main/ajsc/babel_v1/babel/v1/docs/README.txt new file mode 100644 index 0000000..3707179 --- /dev/null +++ b/src/main/ajsc/babel_v1/babel/v1/docs/README.txt @@ -0,0 +1 @@ +Place any docs here that you want to access within the ajsc upon deployment of your service. diff --git a/src/main/ajsc/babel_v1/babel/v1/lib/README.txt b/src/main/ajsc/babel_v1/babel/v1/lib/README.txt new file mode 100644 index 0000000..639e21b --- /dev/null +++ b/src/main/ajsc/babel_v1/babel/v1/lib/README.txt @@ -0,0 +1 @@ +3rd party JAR's needed by your jars (if any) for a ajsc deployment package go here... \ No newline at end of file diff --git a/src/main/ajsc/babel_v1/babel/v1/props/module.props b/src/main/ajsc/babel_v1/babel/v1/props/module.props new file mode 100644 index 0000000..17ebc08 --- /dev/null +++ b/src/main/ajsc/babel_v1/babel/v1/props/module.props @@ -0,0 +1 @@ +EXAMPLE.PROPERTY=EXAMLE_VALUE \ No newline at end of file diff --git a/src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route b/src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route new file mode 100644 index 0000000..c12bc67 --- /dev/null +++ b/src/main/ajsc/babel_v1/babel/v1/routes/babel-service.route @@ -0,0 +1,4 @@ + + + + diff --git a/src/main/assemble/ajsc_module_assembly.xml b/src/main/assemble/ajsc_module_assembly.xml new file mode 100644 index 0000000..359f792 --- /dev/null +++ b/src/main/assemble/ajsc_module_assembly.xml @@ -0,0 +1,69 @@ + + + ${version} + false + + zip + + + + ${project.basedir}/target/versioned-ajsc/routes/ + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/routes/ + + *.route + + + + + + ${project.basedir}/target/versioned-ajsc/docs/ + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/docs/ + + *.* + + + + + + + ${project.basedir}/target/versioned-ajsc/lib/ + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/lib/ + + *.jar + + + + + ${project.basedir}/target/versioned-ajsc/extJars/ + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/extJars/ + + *.jar + + + + + + ${project.basedir}/target/ + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/lib/ + + *.jar + + + + + ${project.basedir}/target/versioned-ajsc/conf/ + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/conf/ + + *.* + + + + + + + diff --git a/src/main/assemble/ajsc_props_assembly.xml b/src/main/assemble/ajsc_props_assembly.xml new file mode 100644 index 0000000..6ee4093 --- /dev/null +++ b/src/main/assemble/ajsc_props_assembly.xml @@ -0,0 +1,26 @@ + + + ${version}_properties + false + + zip + + + + ${project.basedir}/target/versioned-ajsc/props + ${module.ajsc.namespace.name}/${module.ajsc.namespace.version}/props/ + + *.props + + + + + + + + diff --git a/src/main/assemble/ajsc_runtime_assembly.xml b/src/main/assemble/ajsc_runtime_assembly.xml new file mode 100644 index 0000000..c86d265 --- /dev/null +++ b/src/main/assemble/ajsc_runtime_assembly.xml @@ -0,0 +1,47 @@ + + + runtimeEnvironment + false + + zip + + + + ${project.basedir}/target/versioned-runtime/context/ + runtime/context/ + + *.context + + + + ${project.basedir}/target/versioned-runtime/serviceProperties/ + runtime/serviceProperties/ + + *.props + + + ${project.basedir}/target/versioned-runtime/shiroRole + runtime/shiroRole/ + + *.json + + + ${project.basedir}/target/versioned-runtime/shiroUser + runtime/shiroUser/ + + *.json + + + ${project.basedir}/target/versioned-runtime/shiroUserRole + runtime/shiroUserRole + + *.json + + + + \ No newline at end of file diff --git a/src/main/bin/start.sh b/src/main/bin/start.sh new file mode 100644 index 0000000..1854884 --- /dev/null +++ b/src/main/bin/start.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# ============LICENSE_START======================================================= +# org.onap.aai +# ================================================================================ +# Copyright © 2017 AT&T Intellectual Property. All rights reserved. +# Copyright © 2017 European Software Marketing Ltd. +# ================================================================================ +# 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========================================================= +# +# ECOMP is a trademark and service mark of AT&T Intellectual Property. + +BASEDIR="/opt/app/babel/" +AJSC_HOME="$BASEDIR" + +if [ -z "$CONFIG_HOME" ]; then + echo "CONFIG_HOME must be set in order to start up process" + exit 1 +fi + +CLASSPATH="$AJSC_HOME/lib/*" +CLASSPATH="$CLASSPATH:$AJSC_HOME/extJars/" +CLASSPATH="$CLASSPATH:$AJSC_HOME/etc/" +PROPS="-DAJSC_HOME=$AJSC_HOME" +PROPS="$PROPS -DAJSC_CONF_HOME=$BASEDIR/bundleconfig/" +PROPS="$PROPS -Dlogback.configurationFile=$BASEDIR/bundleconfig/etc/logback.xml" +PROPS="$PROPS -DAJSC_SHARED_CONFIG=$AJSC_CONF_HOME" +PROPS="$PROPS -DAJSC_SERVICE_NAMESPACE=babel" +PROPS="$PROPS -DAJSC_SERVICE_VERSION=v1" +PROPS="$PROPS -Dserver.port=9516" +PROPS="$PROPS -DCONFIG_HOME=$CONFIG_HOME" +PROPS="$PROPS -Dartifactgenerator.config=$CONFIG_HOME/artifact-generator.properties" +PROPS="$PROPS -DKEY_STORE_PASSWORD=$KEY_STORE_PASSWORD" +PROPS="$PROPS -DKEY_MANAGER_PASSWORD=$KEY_MANAGER_PASSWORD" +JVM_MAX_HEAP=${MAX_HEAP:-1024} + +echo $CLASSPATH + +exec java -Xmx${JVM_MAX_HEAP}m $PROPS -classpath $CLASSPATH com.att.ajsc.runner.Runner context=// sslport=9516 diff --git a/src/main/config/ajsc-chef.jks b/src/main/config/ajsc-chef.jks new file mode 100644 index 0000000..aeca770 Binary files /dev/null and b/src/main/config/ajsc-chef.jks differ diff --git a/src/main/config/ajsc-jetty.xml b/src/main/config/ajsc-jetty.xml new file mode 100644 index 0000000..68306d4 --- /dev/null +++ b/src/main/config/ajsc-jetty.xml @@ -0,0 +1,128 @@ + + + + + + + + true + + + /etc/runner-web.xml + /etc/ajsc-override-web.xml + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + /extApps + 10 + true + + + + + + + + + + + + + + + + + + + + + /auth/tomcat_keystore + + + + + + + + + + + true + true + + + + + + + + + + + + + http/1.1 + + + + + + + + + + + + + + + + + + + + + + 30000 + + + + + + + \ No newline at end of file diff --git a/src/main/config/ajsc-override-web.xml b/src/main/config/ajsc-override-web.xml new file mode 100644 index 0000000..84a7920 --- /dev/null +++ b/src/main/config/ajsc-override-web.xml @@ -0,0 +1,53 @@ + + + + + + InterceptorFilter + /services/* + + + InterceptorFilter + /rest/* + + + + springSecurityFilterChain + /* + + + + ManagementServlet + /mgmt + + + + RestletServlet + /rest/* + + + + CamelServlet + /services/* + + + + jsp + *.jsp + *.jspf + *.jspx + *.xsp + *.JSP + *.JSPF + *.JSPX + *.XSP + + + default + /* + + \ No newline at end of file diff --git a/src/main/config/ajscJetty.jks b/src/main/config/ajscJetty.jks new file mode 100644 index 0000000..48cdbff Binary files /dev/null and b/src/main/config/ajscJetty.jks differ diff --git a/src/main/config/cadi.properties b/src/main/config/cadi.properties new file mode 100644 index 0000000..d250fec --- /dev/null +++ b/src/main/config/cadi.properties @@ -0,0 +1,36 @@ +#This properties file is used for defining AAF properties related to the CADI framework. This file is used for running AAF framework + +#In order to test functionality of cadi-ajsc-plugin locally cross domain cookie. Cadi "should" find your hostname for you. +#However, we have seen some situations where this fails. A Local testing +#modification can include modifying your hosts file so that you can use "mywebserver.att.com" for your localhost in order +#to test/verify GLO functionality locally. If you are on a Windows machine, you will already have a machine name associated with +#it that will utilize an AT&T domain such as "sbc.com". You may need to add your domain to this as a comma separated list depending +#upon your particular machine domain. This property is commented out as cadi SHOULD find your machine name. With version 1.2.1 of cadi, +#it appears to resolve Mac machine names as well, now. But, this can be somewhat inconsistent depending on your specific working envrironment. +hostname=mywebserver.att.com + +#Setting csp_domain to PROD will allow for testing using your attuid and password through GLO. +csp_domain=PROD +csp_devl_localhost=true + +basic_realm=csp.att.com +#basic_realm=aaf.att.com +basic_warn=TRUE + +cadi_loglevel=WARN +cadi_keyfile=target/swm/package/nix/dist_files/appl/babel/etc/keyfile + +# Configure AAF +#These are dummy values add appropriate values required +aaf_url=url + +#AJSC - MECHID +#These are dummy values add appropriate values required +aaf_id=dummyid@ajsc.att.com +aaf_password=enc:277edqJCjT0RlUI3BtbDQa-3Ha-CQGd +aaf_timeout=5000 +aaf_clean_interval=30000 +aaf_user_expires=5000 +aaf_high_count=1000 + + diff --git a/src/main/config/jul-redirect.properties b/src/main/config/jul-redirect.properties new file mode 100644 index 0000000..8b6624d --- /dev/null +++ b/src/main/config/jul-redirect.properties @@ -0,0 +1,13 @@ + +# Bridge JUL->slf4j Logging Configuration File +# +# This file bridges the JUL logging infrastructure into +# SLF4J so JUL logs go to logback implementation provided +# in this project. SLF4J also captures log4j and has +# other framework options as well providing a common +# logging infrastructure for capturing all logs from different +# libraries using different frameworks in one place. + +# Global properties +handlers=org.slf4j.bridge.SLF4JBridgeHandler +.level= ALL diff --git a/src/main/config/keyfile b/src/main/config/keyfile new file mode 100644 index 0000000..882e86a --- /dev/null +++ b/src/main/config/keyfile @@ -0,0 +1,27 @@ +ZuIwp0TkyVPDeX1Up-8JtkMWvjsCpoiu1_VKeWrtrvxunvAke8_tiFyHPPyb2nkhepFYj6tXzpfS +rGz5XF_TH9NbsKaP8u0HV5clz2WriYQRvHS85vjY7hXxkpFuLb7zkLAPqTyIDpj7FiW61NzsRUAq +TM8jH16jr7mBNnb56w24mNGOwznMPcIZKcjgZU1ekaPDFpWyhQElU7Y0q_94P_Gkk45r66Hj22sU +OiOaaftmudZlswLw8-8Zaakqf2yW9HjMVfuYCwSodBHCW5rdB3Ctb5W36rnD_AQco3Ky2PgPmqvk +QkJYuUHpbuDqVHqLOajlKSIGMTIqAIBg51fRaaONtD-Q5xzY8E5wO1YWTLKcP5tsNvUpzM8Wu3NS +ynpGpUcvlTqWWsGzTbzOyamyKkdNdx97sSqjM25Zh1-ps48h6cddGYWpab7SUvqRCS11QBUyLTry +2iwTEHMhHRIbo7PO99ALQfuq9gI1zKGfurJdvLBeBaFs5SCF0AiCZ3WcDO8Rv3HpxVZ2_ShbDxb0 +eMoO6SotXu51fj8Y3-WqsfZziQyEsHyqpg5uQ6yUtz01h5YHLEoVuotF1U4agmQR6kEkYk-wNOiZ +v-8gaA9gtbLoAdKhuKFxQgQLNMf6GzVzZNujbmDzLoZAP_mXAv29aBPaf64Ugzv-Oa5GZdBgD-Xd +_pahML-ionw99r0TnkpShYmDqMKhMdjaP3m87WIAZkIB-L-VTyKcEsJ4340VSzCOsv3waiM0S89u +4cMcG5y-PLY8IoipIlLUPTWD3SjcQ9DV1Dt3T5KjdWLsj48D3W4K4e9PB8yxs0gtUjgVUR2_xEir +G5eDO9Ac1eHFWGDFFP0SgG-TbHJUKlvy9mwLzmU0fC3xPjhqmIr-v0HxF7HN-tmb1LHDorno8tSN +u7kUGcKSchIiFfvkd066crUb2mH7PnXTaWmAjyVj9VsBExFUYEdpHMAV4sAP9-RxZGDRt46UhrDK +QZvvNhBVyOEjHPHWI4vl1r1v8HNH1_2jZu5DVJWyHWR56aCo1lhFH9_X6UAHUHbnXViDONZOVXlT +9-WD0tk2zJGuwrhdZDAnPnAmjfwbwbpnr5Hmex1i1JiD7WVyP1kbfoej2TmdiYbxr9oBYaGQ29JI +aHod7MQCLtvL1z5XgnDPLZ4y3_9SbqHKYbNa8UgZkTLF5EacGThYVFDLA9cbafHDtR1kMGE3vv4D +EJ-0pAYTOGmKlVI7DwNyKsY9JTyudrxTqhOxi9jgcJNWiUaNe9yhL8Pyc2YBqUTTYhh_a2d1rvkZ +0Gh1crviVxqBrIkRKaMRXZ4f1vDLz-3NvG_vwPOo8WRFo5nGmSdTw7CjBaigJ_cYCfDhoP11pEnw +cndsZNcHs-v05LlxeIIMDD_f5Bvz-il_DLA4eK2HqgLdxh8ziSDl2azk14MJY4amzz6reEXUuKLV +RsZGf_jbDGKhE2HuDQ5ovoLOi4OqE1oRuqh-dGxitrYouP2SN1l_1tCEMRth86FMV-6AQtZsvdUo +y9MtQ7e35atjA8nHtgADlDTmJBKQiUHUsOZ77p1qp17HAFMovUkc739opfEYnKUn6Itpw5Ipm_Is +ra6chJUfMpOFof5rb5OjqFAN27c_-mPo1lQU3ndYlKGh_n5V8ufX6v2Yri8WzOPf6hjVYotkmoMP +NPAICDCB8W5ddBjsopzLVVEtaXDu9Qj6-zf77hT4iQ7rBd2Ner8iLqN3Kis0dvkNM3_uH8onau1G +Y_YYw7PPSZyd2S_7Dd6G-IG4ayO6e5DD6oUwwekyiQI_3rTXNa_wldGxqW9u818010ekE4Qdlfcj +beIn7fAeaOjReZ87hRgWyMs-EgTVHw8RL3yI_O6VvRTVRONRF1Y4C_-IYa8z-bfrwXx3BBd9TTgb +EnS9wVOyC2OgUN6BhPLGLhxzkJ05nEjizXEc9t5EPYoSRwesajGGrrG_0-qWbuU5hKLPLkyeJLHb +5HXOTVsrUR59Vov2M3_EswkxcImblox3k3VS2yihZMGyfqLzZIUXgd8ufkevKKU6DxwacGTb \ No newline at end of file diff --git a/src/main/config/runner-web.xml b/src/main/config/runner-web.xml new file mode 100644 index 0000000..b51aff4 --- /dev/null +++ b/src/main/config/runner-web.xml @@ -0,0 +1,97 @@ + + + + + + contextConfigLocation + /WEB-INF/spring-servlet.xml, + classpath:applicationContext.xml + + + + + spring.profiles.default + nooauth + + + + org.springframework.web.context.ContextLoaderListener + + + + ManagementServlet + ajsc.ManagementServlet + + + + + InterceptorFilter + ajsc.filters.InterceptorFilter + + preProcessor_interceptor_config_file + /etc/PreProcessorInterceptors.properties + + + postProcessor_interceptor_config_file + /etc/PostProcessorInterceptors.properties + + + + + + RestletServlet + ajsc.restlet.RestletSpringServlet + + org.restlet.component + restletComponent + + + + + CamelServlet + ajsc.servlet.AjscCamelServlet + + + + + springSecurityFilterChain + org.springframework.web.filter.DelegatingFilterProxy + + + + spring + org.springframework.web.servlet.DispatcherServlet + 1 + + + + + + + + jsp + org.apache.jasper.servlet.JspServlet + + + + + + + + + default + org.eclipse.jetty.servlet.DefaultServlet + + dirAllowed + true + + + + diff --git a/src/main/docker/Dockerfile b/src/main/docker/Dockerfile new file mode 100644 index 0000000..6fac6e2 --- /dev/null +++ b/src/main/docker/Dockerfile @@ -0,0 +1,24 @@ +FROM ubuntu:14.04 + +ARG MICRO_HOME=/opt/app/babel +ARG BIN_HOME=$MICRO_HOME/bin + +RUN apt-get update + +# Install and setup java8 +RUN apt-get update && apt-get install -y software-properties-common +## sudo -E is required to preserve the environment. If you remove that line, it will most like freeze at this step +RUN sudo -E add-apt-repository ppa:openjdk-r/ppa && apt-get update && apt-get install -y openjdk-8-jdk +## Setup JAVA_HOME, this is useful for docker commandline +ENV JAVA_HOME usr/lib/jvm/java-8-openjdk-amd64 +RUN export JAVA_HOME + +# Build up the deployment folder structure +RUN mkdir -p $MICRO_HOME +ADD swm/package/nix/dist_files/appl/babel/* $MICRO_HOME/ +RUN mkdir -p $BIN_HOME +COPY *.sh $BIN_HOME +RUN chmod 755 $BIN_HOME/* +RUN ln -s /logs $MICRO_HOME/logs + +CMD ["/opt/app/babel/bin/start.sh"] diff --git a/src/main/java/org/onap/aai/auth/AAIAuthException.java b/src/main/java/org/onap/aai/auth/AAIAuthException.java new file mode 100644 index 0000000..13593ab --- /dev/null +++ b/src/main/java/org/onap/aai/auth/AAIAuthException.java @@ -0,0 +1,39 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.auth; + +public class AAIAuthException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + + public AAIAuthException(String string) { + super(string); + } + + public AAIAuthException(String string, Exception e) { + super(string, e); + } + +} diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java new file mode 100644 index 0000000..f678498 --- /dev/null +++ b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java @@ -0,0 +1,121 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.auth; + +import java.security.cert.X509Certificate; +import javax.inject.Inject; +import javax.security.auth.x500.X500Principal; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.HttpHeaders; +import org.onap.aai.babel.config.BabelAuthConfig; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; + + +/** + * Public class for authentication and authorization operations. Authorization is applied according to user and role + */ +public class AAIMicroServiceAuth { + + private static Logger applicationLogger = LoggerFactory.getInstance().getLogger(AAIMicroServiceAuth.class); + + private BabelAuthConfig babelAuthConfig; + + /** + * @param babelAuthConfig + * @throws AAIAuthException + */ + @Inject + public AAIMicroServiceAuth(final BabelAuthConfig babelAuthConfig) throws AAIAuthException { + this.babelAuthConfig = babelAuthConfig; + if (!babelAuthConfig.isAuthenticationDisable()) { + AAIMicroServiceAuthCore.init(babelAuthConfig.getAuthPolicyFile()); + } + } + + /** + * @param username + * @param policyFunction + * @return + * @throws AAIAuthException + */ + public boolean authorize(String username, String policyFunction) throws AAIAuthException { + return AAIMicroServiceAuthCore.authorize(username, policyFunction); + } + + /** + * @param authUser + * @param policyFunction + * @return + * @throws AAIAuthException + */ + public String authenticate(String authUser, String policyFunction) throws AAIAuthException { + if (authorize(authUser, policyFunction)) { + return "OK"; + } else { + return "AAI_9101"; + } + } + + /** + * @param headers + * @param req + * @param action + * @param apiPath + * @return + * @throws AAIAuthException + */ + public boolean validateRequest(HttpHeaders headers /* NOSONAR */, HttpServletRequest req, + AAIMicroServiceAuthCore.HTTP_METHODS action, String apiPath) throws AAIAuthException { + + applicationLogger.debug("validateRequest: " + apiPath); + applicationLogger + .debug("babelAuthConfig.isAuthenticationDisable(): " + babelAuthConfig.isAuthenticationDisable()); + + if (babelAuthConfig.isAuthenticationDisable()) { + return true; + } + + String[] ps = apiPath.split("/"); + String authPolicyFunctionName = ps[0]; + if (ps.length > 1 && authPolicyFunctionName.matches("v\\d+")) { + authPolicyFunctionName = ps[1]; + } + + String cipherSuite = (String) req.getAttribute("javax.servlet.request.cipher_suite"); + String authUser = null; + + if (cipherSuite != null) { + X509Certificate[] certChain = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); + X509Certificate clientCert = certChain[0]; + X500Principal subjectDN = clientCert.getSubjectX500Principal(); + authUser = subjectDN.toString(); + } + + if (authUser != null) { + return "OK".equals(authenticate(authUser.toLowerCase(), action.toString() + ":" + authPolicyFunctionName)); + } else { + return false; + } + } +} diff --git a/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java new file mode 100644 index 0000000..b148440 --- /dev/null +++ b/src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java @@ -0,0 +1,287 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.auth; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.TimeUnit; +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; + +/** + * Authentication and authorization by user and role. + * + */ +public class AAIMicroServiceAuthCore { + + private static Logger applicationLogger = LoggerFactory.getInstance().getLogger(AAIMicroServiceAuthCore.class); + + public static final String FILESEP = + (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator"); + public static final String APPCONFIG_DIR = (System.getProperty("CONFIG_HOME") == null) + ? System.getProperty("AJSC_HOME") + FILESEP + "appconfig" : System.getProperty("CONFIG_HOME"); + + private static String appConfigAuthDir = APPCONFIG_DIR + FILESEP + "auth"; + private static String defaultAuthFileName = appConfigAuthDir + FILESEP + "auth_policy.json"; + + private static boolean usersInitialized = false; + private static HashMap users; + private static boolean timerSet = false; + private static Timer timer = null; + private static String policyAuthFileName; + + public enum HTTP_METHODS { + GET, + PUT, + DELETE, + HEAD, + POST + } + + // Don't instantiate + private AAIMicroServiceAuthCore() {} + + public static String getDefaultAuthFileName() { + return defaultAuthFileName; + } + + public static void setDefaultAuthFileName(String defaultAuthFileName) { + AAIMicroServiceAuthCore.defaultAuthFileName = defaultAuthFileName; + } + + public static synchronized void init(String authPolicyFile) throws AAIAuthException { + + try { + policyAuthFileName = AAIMicroServiceAuthCore.getConfigFile(authPolicyFile); + } catch (IOException e) { + applicationLogger.debug("Exception while retrieving policy file."); + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + throw new AAIAuthException(e.getMessage()); + } + if (policyAuthFileName == null) { + throw new AAIAuthException("Auth policy file could not be found"); + } + AAIMicroServiceAuthCore.reloadUsers(); + + TimerTask task = new FileWatcher(new File(policyAuthFileName)) { + @Override + protected void onChange(File file) { + // here we implement the onChange + applicationLogger.debug("File " + file.getName() + " has been changed!"); + try { + AAIMicroServiceAuthCore.reloadUsers(); + } catch (AAIAuthException e) { + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + } + applicationLogger.debug("File " + file.getName() + " has been reloaded!"); + } + }; + + if (!timerSet) { + timerSet = true; + timer = new Timer(); + long period = TimeUnit.SECONDS.toMillis(1); + timer.schedule(task, new Date(), period); + applicationLogger.debug("Config Watcher Interval = " + period); + } + } + + public static void cleanup() { + timer.cancel(); + } + + public static String getConfigFile(String authPolicyFile) throws IOException { + File authFile = new File(authPolicyFile); + if (authFile.exists()) { + return authFile.getCanonicalPath(); + } + authFile = new File(appConfigAuthDir + FILESEP + authPolicyFile); + if (authFile.exists()) { + return authFile.getCanonicalPath(); + } + if (defaultAuthFileName != null) { + authFile = new File(defaultAuthFileName); + if (authFile.exists()) { + return defaultAuthFileName; + } + } + return null; + } + + public static synchronized void reloadUsers() throws AAIAuthException { + users = new HashMap<>(); + + ObjectMapper mapper = new ObjectMapper(); + try { + applicationLogger.debug("Reading from " + policyAuthFileName); + JsonNode rootNode = mapper.readTree(new File(policyAuthFileName)); + for (JsonNode roleNode : rootNode.path("roles")) { + String roleName = roleNode.path("name").asText(); + AAIAuthRole r = new AAIAuthRole(); + installFunctionOnRole(roleNode.path("functions"), roleName, r); + assignRoleToUsers(roleNode.path("users"), roleName, r); + } + } catch (FileNotFoundException e) { + throw new AAIAuthException("Auth policy file could not be found", e); + } catch (JsonProcessingException e) { + throw new AAIAuthException("Error processing Auth policy file ", e); + } catch (IOException e) { + throw new AAIAuthException("Error reading Auth policy file", e); + } + + usersInitialized = true; + } + + private static void installFunctionOnRole(JsonNode functionsNode, String roleName, AAIAuthRole r) { + for (JsonNode functionNode : functionsNode) { + String function = functionNode.path("name").asText(); + JsonNode methodsNode = functionNode.path("methods"); + boolean hasMethods = false; + for (JsonNode method_node : methodsNode) { + String methodName = method_node.path("name").asText(); + hasMethods = true; + String func = methodName + ":" + function; + applicationLogger.debug("Installing function " + func + " on role " + roleName); + r.addAllowedFunction(func); + } + + if (!hasMethods) { + for (HTTP_METHODS meth : HTTP_METHODS.values()) { + String func = meth.toString() + ":" + function; + applicationLogger.debug("Installing (all methods) " + func + " on role " + roleName); + r.addAllowedFunction(func); + } + } + } + } + + private static void assignRoleToUsers(JsonNode usersNode, String roleName, AAIAuthRole r) { + for (JsonNode userNode : usersNode) { + String name = userNode.path("username").asText().toLowerCase(); + AAIAuthUser user; + if (users.containsKey(name)) { + user = users.get(name); + } else { + user = new AAIAuthUser(); + } + applicationLogger.debug("Assigning " + roleName + " to user " + name); + user.setUser(name); + user.addRole(roleName, r); + users.put(name, user); + } + } + + public static class AAIAuthUser { + private String username; + private HashMap roles; + + public AAIAuthUser() { + this.roles = new HashMap<>(); + } + + public String getUser() { + return this.username; + } + + public Map getRoles() { + return this.roles; + } + + public void addRole(String roleName, AAIAuthRole r) { + this.roles.put(roleName, r); + } + + public boolean checkAllowed(String checkFunc) { + for (Entry role_entry : roles.entrySet()) { + AAIAuthRole role = role_entry.getValue(); + if (role.hasAllowedFunction(checkFunc)) { + return true; + } + } + return false; + } + + public void setUser(String myuser) { + this.username = myuser; + } + + } + + public static class AAIAuthRole { + + private List allowedFunctions; + + public AAIAuthRole() { + this.allowedFunctions = new ArrayList<>(); + } + + public void addAllowedFunction(String func) { + this.allowedFunctions.add(func); + } + + public void delAllowedFunction(String delFunc) { + if (this.allowedFunctions.contains(delFunc)) { + this.allowedFunctions.remove(delFunc); + } + } + + public boolean hasAllowedFunction(String afunc) { + return this.allowedFunctions.contains(afunc) ? true : false; + } + } + + public static boolean authorize(String username, String authFunction) throws AAIAuthException { + if (!usersInitialized || users == null) { + throw new AAIAuthException("Auth module not initialized"); + } + if (users.containsKey(username)) { + if (users.get(username).checkAllowed(authFunction)) { + logAuthenticationResult(username, authFunction, "AUTH ACCEPTED"); + return true; + } else { + logAuthenticationResult(username, authFunction, "AUTH FAILED"); + return false; + } + } else { + logAuthenticationResult(username, authFunction, "User not found"); + return false; + } + } + + private static void logAuthenticationResult(String username, String authFunction, String result) { + applicationLogger.debug(result + ": " + username + " on function " + authFunction); + } +} diff --git a/src/main/java/org/onap/aai/auth/FileWatcher.java b/src/main/java/org/onap/aai/auth/FileWatcher.java new file mode 100644 index 0000000..e3b9923 --- /dev/null +++ b/src/main/java/org/onap/aai/auth/FileWatcher.java @@ -0,0 +1,63 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.auth; + +import java.io.File; +import java.util.TimerTask; + +public abstract class FileWatcher extends TimerTask { + private long timeStamp; + private File file; + + /** + * Instantiates a new file watcher. + * + * @param file the file + */ + public FileWatcher(File file) { + this.file = file; + this.timeStamp = file.lastModified(); + } + + /** + * runs a timer task + * + * @see java.util.TimerTask.run + */ + @Override + public final void run() { + long newTimeStamp = file.lastModified(); + + if ((newTimeStamp - this.timeStamp) > 500) { + this.timeStamp = newTimeStamp; + onChange(file); + } + } + + /** + * On change. + * + * @param file the file + */ + protected abstract void onChange(File file); +} diff --git a/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java b/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java new file mode 100644 index 0000000..5fdc01f --- /dev/null +++ b/src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java @@ -0,0 +1,51 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.config; + +import org.springframework.beans.factory.annotation.Value; + +public class BabelAuthConfig { + + @Value("${auth.authentication.disable}") + private boolean authenticationDisable; + + @Value("${auth.policy.file}") + private String authPolicyFile; + + public boolean isAuthenticationDisable() { + return authenticationDisable; + } + + public void setAuthenticationDisable(boolean authenticationDisable) { + this.authenticationDisable = authenticationDisable; + } + + public String getAuthPolicyFile() { + return authPolicyFile; + } + + public void setAuthPolicyFile(String authPolicyFile) { + this.authPolicyFile = authPolicyFile; + } + +} diff --git a/src/main/java/org/onap/aai/babel/csar/CsarConverterException.java b/src/main/java/org/onap/aai/babel/csar/CsarConverterException.java new file mode 100644 index 0000000..b9316fc --- /dev/null +++ b/src/main/java/org/onap/aai/babel/csar/CsarConverterException.java @@ -0,0 +1,40 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.csar; + +/** + * This class represents an exception encountered when attempting to convert the yml files in a csar archive into xml. + */ +public class CsarConverterException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for an instance of this exception with just a message. + * + * @param message information about the exception + */ + public CsarConverterException(String message) { + super(message); + } +} diff --git a/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java b/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java new file mode 100644 index 0000000..55cf652 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java @@ -0,0 +1,88 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.csar; + +import java.util.List; +import java.util.Objects; +import org.onap.aai.babel.csar.extractor.InvalidArchiveException; +import org.onap.aai.babel.csar.extractor.YamlExtractor; +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.babel.xml.generator.XmlArtifactGenerationException; +import org.onap.aai.babel.xml.generator.ArtifactGenerator; +import org.onap.aai.babel.xml.generator.ModelGenerator; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; + +import org.openecomp.sdc.generator.data.Artifact; + +/** + * This class is responsible for converting content in a csar archive into one or more xml artifacts. + */ +public class CsarToXmlConverter { + private static Logger logger = LoggerFactory.getInstance().getLogger(CsarToXmlConverter.class); + + /** + * This method is responsible for extracting one or more yaml files from the given csarArtifact and then using them + * to generate xml artifacts. + * + * @param csarArchive the artifact that contains the csar archive to generate xml artifacts from + * @param name the name of the archive file + * @param version the version of the archive file + * @return List a list of generated xml artifacts + * @throws CsarConverterException if there is an error either extracting the yaml files or generating xml artifacts + */ + public List generateXmlFromCsar(byte[] csarArchive, String name, String version) + throws CsarConverterException { + validateArguments(csarArchive, name, version); + + logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, + "Starting to process csarArchive to convert contents to xml artifacts"); + List xmlArtifacts; + + try { + logger.debug("Calling YamlExtractor to extract ymlFiles"); + List ymlFiles = YamlExtractor.extract(csarArchive, name, version); + + logger.debug("Calling XmlArtifactGenerator to generateXmlArtifacts"); + ArtifactGenerator modelGenerator = new ModelGenerator(); + xmlArtifacts = modelGenerator.generateArtifacts(ymlFiles); + + logger.debug(xmlArtifacts.size() + " xml artifacts have been generated"); + } catch (InvalidArchiveException e) { + throw new CsarConverterException( + "An error occurred trying to extract the yml files from the csar file : " + e); + } catch (XmlArtifactGenerationException e) { + throw new CsarConverterException( + "An error occurred trying to generate xml files from a collection of yml files : " + e); + } + + return xmlArtifacts; + } + + private void validateArguments(byte[] csarArchive, String name, String version) { + Objects.requireNonNull(csarArchive); + Objects.requireNonNull(name); + Objects.requireNonNull(version); + } +} diff --git a/src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java b/src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java new file mode 100644 index 0000000..aac893b --- /dev/null +++ b/src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java @@ -0,0 +1,50 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.csar.extractor; + +/** + * This class represents an exception encountered when processing an archive in memory. + */ +public class InvalidArchiveException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for an instance of this exception with just a message. + * + * @param message information about the exception + */ + InvalidArchiveException(String message) { + super(message); + } + + /** + * Constructor for an instance of this exception with a message and actual exception encountered. + * + * @param message information about the exception + * @param cause the actual exception that was encountered + */ + InvalidArchiveException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java b/src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java new file mode 100644 index 0000000..fb51933 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java @@ -0,0 +1,149 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.csar.extractor; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.babel.xml.generator.ModelGenerator; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.openecomp.sdc.generator.data.Artifact; +import org.yaml.snakeyaml.Yaml; + +/** + * The purpose of this class is to process a .csar file in the form of a byte array and extract yaml files from it. + * + * A .csar file is a compressed archive like a zip file and this class will treat the byte array as it if were a zip + * file. + */ +public class YamlExtractor { + private static Logger logger = LoggerFactory.getInstance().getLogger(YamlExtractor.class); + + private static final String TYPE = "type"; + private static final Pattern YAMLFILE_EXTENSION_REGEX = Pattern.compile("(?i).*\\.ya?ml$"); + private static final Set INVALID_TYPES = new HashSet<>(); + + static { + Collections.addAll(INVALID_TYPES, "CP", "VL", "VFC", "VFCMT", "ABSTRACT"); + } + + /** + * Private constructor + */ + private YamlExtractor() { + throw new IllegalAccessError("Utility class"); + } + + /** + * This method is responsible for filtering the contents of the supplied archive and returning a collection of + * {@link Artifact}s that represent the yml files that have been found in the archive.
+ *
+ * If the archive contains no yml files it will return an empty list.
+ * + * @param archive the zip file in the form of a byte array containing one or more yml files + * @param name the name of the archive file + * @param version the version of the archive file + * @return List collection of yml files found in the archive + * @throws InvalidArchiveException if an error occurs trying to extract the yml files from the archive, if the + * archive is not a zip file or there are no yml files + */ + public static List extract(byte[] archive, String name, String version) throws InvalidArchiveException { + validateRequest(archive, name, version); + + logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, "Extracting CSAR archive: " + name); + + List ymlFiles = new ArrayList<>(); + try (SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(archive); + ZipFile zipFile = new ZipFile(inMemoryByteChannel)) { + for (Enumeration enumeration = zipFile.getEntries(); enumeration.hasMoreElements();) { + ZipArchiveEntry entry = enumeration.nextElement(); + if (fileShouldBeExtracted(zipFile, entry)) { + ymlFiles.add(ModelGenerator.createArtifact(IOUtils.toByteArray(zipFile.getInputStream(entry)), + entry.getName(), version)); + } + } + if (ymlFiles.isEmpty()) { + throw new InvalidArchiveException("No valid yml files were found in the csar file."); + } + } catch (IOException e) { + throw new InvalidArchiveException( + "An error occurred trying to create a ZipFile. Is the content being converted really a csar file?", + e); + } + + logger.debug(ApplicationMsgs.DISTRIBUTION_EVENT, ymlFiles.size() + " YAML files extracted."); + + return ymlFiles; + } + + private static void validateRequest(byte[] archive, String name, String version) throws InvalidArchiveException { + if (archive == null || archive.length == 0) { + throw new InvalidArchiveException("An archive must be supplied for processing."); + } else if (StringUtils.isBlank(name)) { + throw new InvalidArchiveException("The name of the archive must be supplied for processing."); + } else if (StringUtils.isBlank(version)) { + throw new InvalidArchiveException("The version must be supplied for processing."); + } + } + + @SuppressWarnings("unchecked") + private static boolean fileShouldBeExtracted(ZipFile zipFile, ZipArchiveEntry entry) throws IOException { + logger.debug(ApplicationMsgs.DISTRIBUTION_EVENT, "Checking if " + entry.getName() + " should be extracted..."); + + boolean extractFile = false; + if (YAMLFILE_EXTENSION_REGEX.matcher(entry.getName()).matches()) { + try { + Yaml yamlParser = new Yaml(); + HashMap yaml = + (LinkedHashMap) yamlParser.load(zipFile.getInputStream(entry)); + HashMap metadata = (LinkedHashMap) yaml.get("metadata"); + + extractFile = metadata != null && metadata.containsKey(TYPE) + && !INVALID_TYPES.contains(metadata.get(TYPE).toString().toUpperCase()) + && !metadata.get(TYPE).toString().isEmpty(); + } catch (Exception e) { + logger.error(ApplicationMsgs.DISTRIBUTION_EVENT, + "Unable to verify " + entry.getName() + " contains a valid resource type: " + e.getMessage()); + } + } + + logger.debug(ApplicationMsgs.DISTRIBUTION_EVENT, "Keeping file: " + entry.getName() + "? : " + extractFile); + + return extractFile; + } +} + diff --git a/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java b/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java new file mode 100644 index 0000000..9b9f9d5 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java @@ -0,0 +1,50 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.logging; + +import com.att.eelf.i18n.EELFResourceManager; +import org.onap.aai.cl.eelf.LogMessageEnum; + +public enum ApplicationMsgs implements LogMessageEnum { + //@formatter:off + /** + * Arguments: {0} = message. + */ + DISTRIBUTION_EVENT, + + PROCESS_REQUEST_ERROR, + + INVALID_CSAR_FILE, + + INVALID_REQUEST_JSON; + + //@formatter:on + + /** + * Static initializer to ensure the resource bundles for this class are loaded... Here this application loads + * messages from three bundles + */ + static { + EELFResourceManager.loadMessageBundle("babel-logging-resources"); + } +} diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java new file mode 100644 index 0000000..bb7b721 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java @@ -0,0 +1,51 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.service; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import org.onap.aai.auth.AAIAuthException; + +/** + * Generate artifacts from the specified request content + */ +@Path("/") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface GenerateArtifactsService { + + @POST + @Path("/generateArtifacts") + Response generateArtifacts(@Context UriInfo uriInfo, @Context HttpHeaders headers, + @Context HttpServletRequest servletRequest, String request) throws AAIAuthException; + + +} diff --git a/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java new file mode 100644 index 0000000..bdb45b5 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java @@ -0,0 +1,148 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.service; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonSyntaxException; +import java.util.Base64; +import java.util.List; +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.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.core.UriInfo; +import org.onap.aai.auth.AAIAuthException; +import org.onap.aai.auth.AAIMicroServiceAuth; +import org.onap.aai.auth.AAIMicroServiceAuthCore; +import org.onap.aai.babel.csar.CsarConverterException; +import org.onap.aai.babel.csar.CsarToXmlConverter; +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.babel.service.data.BabelRequest; +import org.onap.aai.babel.util.RequestValidationException; +import org.onap.aai.babel.util.RequestValidator; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; + + +/** + * Generate SDC Artifacts by passing in a CSAR payload, Artifact Name and Artifact version + */ +public class GenerateArtifactsServiceImpl implements GenerateArtifactsService { + private static Logger applicationLogger = LoggerFactory.getInstance().getLogger(GenerateArtifactsServiceImpl.class); + + private AAIMicroServiceAuth aaiMicroServiceAuth; + + /** + * @param authorization + */ + @Inject + public GenerateArtifactsServiceImpl(final AAIMicroServiceAuth authorization) { + this.aaiMicroServiceAuth = authorization; + } + + /* + * (non-Javadoc) + * + * @see org.onap.aai.babel.service.GenerateArtifactsService#generateArtifacts(javax.ws.rs.core.UriInfo, + * javax.ws.rs.core.HttpHeaders, javax.servlet.http.HttpServletRequest, java.lang.String) + */ + @Override + public Response generateArtifacts(UriInfo uriInfo, HttpHeaders headers, HttpServletRequest servletRequest, + String requestBody) throws AAIAuthException { + applicationLogger.debug("Received request: " + requestBody); + + Response response; + try { + boolean authorized = aaiMicroServiceAuth.validateRequest(headers, servletRequest, + AAIMicroServiceAuthCore.HTTP_METHODS.POST, uriInfo.getPath(false)); + + response = authorized ? generateArtifacts(requestBody) + : buildResponse(Status.UNAUTHORIZED, "User not authorized to perform the operation."); + } catch (AAIAuthException e) { + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + throw e; + } + + applicationLogger.debug("Sending response: " + response.getStatus() + " " + response.getEntity().toString()); + return response; + } + + + /** + * Generate XML model artifacts from request body. + * + * @param requestBody the request body in JSON format + * @return response object containing the generated XML models + */ + protected Response generateArtifacts(String requestBody) { + Response response; + + try { + Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + BabelRequest babelRequest = gson.fromJson(requestBody, BabelRequest.class); + RequestValidator.validateRequest(babelRequest); + byte[] csarFile = Base64.getDecoder().decode(babelRequest.getCsar()); + List xmlArtifacts = new CsarToXmlConverter().generateXmlFromCsar(csarFile, + babelRequest.getArtifactName(), babelRequest.getArtifactVersion()); + response = buildResponse(Status.OK, gson.toJson(xmlArtifacts)); + + } catch (JsonSyntaxException e) { + applicationLogger.error(ApplicationMsgs.INVALID_REQUEST_JSON, e); + response = buildResponse(Status.BAD_REQUEST, "Malformed request."); + } catch (CsarConverterException e) { + applicationLogger.error(ApplicationMsgs.INVALID_CSAR_FILE, e); + response = buildResponse(Status.INTERNAL_SERVER_ERROR, "Error converting CSAR artifact to XML model."); + } catch (RequestValidationException e) { + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + response = buildResponse(Status.BAD_REQUEST, e.getLocalizedMessage()); + } catch (Exception e) { + applicationLogger.error(ApplicationMsgs.PROCESS_REQUEST_ERROR, e); + response = buildResponse(Status.INTERNAL_SERVER_ERROR, + "Error while processing request. Please check the babel service logs for more details.\n"); + } + + return response; + } + + /** + * Helper method to create a REST response object. + * + * @param status response status code + * @param entity response payload + * @return + */ + private Response buildResponse(Status status, String entity) { + //@formatter:off + return Response + .status(status) + .entity(entity) + .type(MediaType.TEXT_PLAIN) + .build(); + //@formatter:on + } +} diff --git a/src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java b/src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java new file mode 100644 index 0000000..986aed9 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java @@ -0,0 +1,63 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.service.data; + +/** + * Bean representing the return artifacts of the Babel microservice. + */ +public class BabelArtifact { + String name; + String type; + byte[] payload; + + public BabelArtifact(String name, String type, byte[] payload) { + super(); + this.name = name; + this.type = type; + this.payload = payload; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public byte[] getPayload() { + return payload; + } + + public void setPayload(byte[] payload) { + this.payload = payload; + } +} diff --git a/src/main/java/org/onap/aai/babel/service/data/BabelRequest.java b/src/main/java/org/onap/aai/babel/service/data/BabelRequest.java new file mode 100644 index 0000000..20a101f --- /dev/null +++ b/src/main/java/org/onap/aai/babel/service/data/BabelRequest.java @@ -0,0 +1,53 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.service.data; + +public class BabelRequest { + private String csar; + private String artifactVersion; + private String artifactName; + + public String getCsar() { + return csar; + } + + public void setCsar(String csar) { + this.csar = csar; + } + + public String getArtifactVersion() { + return artifactVersion; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public String getArtifactName() { + return artifactName; + } + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } +} diff --git a/src/main/java/org/onap/aai/babel/util/RequestValidationException.java b/src/main/java/org/onap/aai/babel/util/RequestValidationException.java new file mode 100644 index 0000000..5e3be5e --- /dev/null +++ b/src/main/java/org/onap/aai/babel/util/RequestValidationException.java @@ -0,0 +1,42 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.util; + +/** + * This exception is thrown when the request fails validation. + */ +public class RequestValidationException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for an instance of this exception with just a message. + * + * @param message information about the exception + */ + public RequestValidationException(String message) { + super(message); + } +} + + diff --git a/src/main/java/org/onap/aai/babel/util/RequestValidator.java b/src/main/java/org/onap/aai/babel/util/RequestValidator.java new file mode 100644 index 0000000..ecc9d2b --- /dev/null +++ b/src/main/java/org/onap/aai/babel/util/RequestValidator.java @@ -0,0 +1,50 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.util; + +import org.onap.aai.babel.service.data.BabelRequest; + +public class RequestValidator { + + private RequestValidator() {} + + + /** + * Validates that the request body contains the required attributes + * + * @param request the request body to validate + */ + public static void validateRequest(BabelRequest request) throws RequestValidationException { + if (request.getCsar() == null) { + throw new RequestValidationException("No csar attribute found in the request body."); + } + + if (request.getArtifactVersion() == null) { + throw new RequestValidationException("No artifact version attribute found in the request body."); + } + + if (request.getArtifactName() == null) { + throw new RequestValidationException("No artifact name attribute found in the request body."); + } + } +} diff --git a/src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java b/src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java new file mode 100644 index 0000000..4fd51aa --- /dev/null +++ b/src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java @@ -0,0 +1,39 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.xml.generator; + +import java.util.List; +import org.onap.aai.babel.service.data.BabelArtifact; +import org.openecomp.sdc.generator.data.Artifact; + +public interface ArtifactGenerator { + + /** + * Generate a {@link List} of {@link BabelArtifact}s from the Artifacts obtained from the CSAR + * + * @param csarArtifacts artifacts obtained from the CSAR file + * @return generated {@link BabelArtifact}s + */ + List generateArtifacts(List csarArtifacts) throws XmlArtifactGenerationException; + +} 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 new file mode 100644 index 0000000..c6def3d --- /dev/null +++ b/src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java @@ -0,0 +1,136 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.xml.generator; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import org.onap.aai.babel.logging.ApplicationMsgs; +import org.onap.aai.babel.service.data.BabelArtifact; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.openecomp.sdc.generator.data.AdditionalParams; +import org.openecomp.sdc.generator.data.Artifact; +import org.openecomp.sdc.generator.data.GenerationData; +import org.openecomp.sdc.generator.data.GeneratorUtil; +import org.openecomp.sdc.generator.data.GroupType; +import org.openecomp.sdc.generator.service.ArtifactGenerationService; + +/** + * This class is responsible for generating xml model artifacts from a collection of csar file artifacts + */ +public class ModelGenerator implements ArtifactGenerator { + + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelGenerator.class); + + private static final String GENERATORCONFIG = "{\"artifactTypes\": [\"AAI\"]}"; + private static final Pattern UUID_NORMATIVE_NEW_VERSION = Pattern.compile("^\\d{1,}.0"); + private static final String VERSION_DELIMITER = "."; + private static final String VERSION_DELIMITER_REGEXP = "\\" + VERSION_DELIMITER; + private static final String DEFAULT_SERVICE_VERSION = "1.0"; + + /** + * Invokes the TOSCA artifact generator API with the input artifacts. + * + * @param csarArtifacts the input artifacts + * @return {@link List} of output artifacts + * @throws XmlArtifactGenerationException if there is an error trying to generate xml artifacts + */ + @Override + public List generateArtifacts(List csarArtifacts) throws XmlArtifactGenerationException { + logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, + "Generating XML for " + csarArtifacts.size() + " CSAR artifacts."); + + // Get the service version to pass into the generator + String toscaVersion = csarArtifacts.get(0).getVersion(); + logger.debug( + "Getting the service version for Tosca Version of the yml file. The Tosca Version is " + toscaVersion); + String serviceVersion = getServiceVersion(toscaVersion); + logger.debug("The service version is " + serviceVersion); + Map additionalParams = new HashMap<>(); + additionalParams.put(AdditionalParams.ServiceVersion.getName(), serviceVersion); + + // Call ArtifactGenerator API + logger.debug("Obtaining instance of ArtifactGenerationService"); + ArtifactGenerationService generationService = ArtifactGenerationService.lookup(); + logger.debug("About to call generationService.generateArtifact()"); + GenerationData data = generationService.generateArtifact(csarArtifacts, GENERATORCONFIG, additionalParams); + logger.debug("Call generationService.generateArtifact() has finished"); + + // Convert results into BabelArtifacts + if (data.getErrorData().isEmpty()) { + return data.getResultData().stream().map(a -> new BabelArtifact(a.getName(), a.getType(), a.getPayload())) + .collect(Collectors.toList()); + } else { + throw new XmlArtifactGenerationException( + "Error occurred during artifact generation: " + data.getErrorData().toString()); + } + } + + /** + * Creates an instance of an input artifact for the generator. + * + * @param payload the payload downloaded from SDC + * @param artifactName name of the artifact to create + * @param artifactVersion version of the artifact to create + * @return an {@link Artifact} object constructed from the payload and artifactInfo + */ + public static Artifact createArtifact(byte[] payload, String artifactName, String artifactVersion) { + logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, "Creating artifact for: " + artifactName); + + // Convert payload into an input Artifact + String checksum = GeneratorUtil.checkSum(payload); + byte[] encodedPayload = GeneratorUtil.encode(payload); + Artifact artifact = new Artifact("TOSCA", GroupType.DEPLOYMENT.name(), checksum, encodedPayload); + artifact.setName(artifactName); + artifact.setLabel(artifactName); + artifact.setDescription(artifactName); + artifact.setVersion(artifactVersion); + return artifact; + } + + private static String getServiceVersion(String artifactVersion) { + String serviceVersion; + + try { + if (UUID_NORMATIVE_NEW_VERSION.matcher(artifactVersion).matches()) { + serviceVersion = artifactVersion; + } else { + String[] versionParts = artifactVersion.split(VERSION_DELIMITER_REGEXP); + Integer majorVersion = Integer.parseInt(versionParts[0]); + + serviceVersion = (majorVersion + 1) + VERSION_DELIMITER + "0"; + } + } catch (Exception e) { + logger.warn(ApplicationMsgs.DISTRIBUTION_EVENT, + "Error generating service version from artifact version: " + artifactVersion + + ". Using default service version of: " + DEFAULT_SERVICE_VERSION + ". Error details: " + + e); + return DEFAULT_SERVICE_VERSION; + } + + return serviceVersion; + } +} diff --git a/src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java b/src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java new file mode 100644 index 0000000..bff6ab3 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java @@ -0,0 +1,40 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017 European Software Marketing Ltd. + * ================================================================================ + * 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========================================================= + * + * ECOMP is a trademark and service mark of AT&T Intellectual Property. + */ +package org.onap.aai.babel.xml.generator; + +/** + * This class represents an exception encountered when generating an Artifact. + */ +public class XmlArtifactGenerationException extends Exception { + + private static final long serialVersionUID = 1L; + + /** + * Constructor for an instance of this exception with just a message. + * + * @param message information about the exception + */ + public XmlArtifactGenerationException(String message) { + super(message); + } +} diff --git a/src/main/resources/babel-logging-resources.properties b/src/main/resources/babel-logging-resources.properties new file mode 100644 index 0000000..3cd23ab --- /dev/null +++ b/src/main/resources/babel-logging-resources.properties @@ -0,0 +1,59 @@ +### +# ============LICENSE_START======================================================= +# MODEL LOADER SERVICE +# ================================================================================ +# Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. +# Copyright (C) 2017 European Software Marketing Ltd. +# ================================================================================ +# 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========================================================= +### + +#Resource key=Error Code|Message text|Resolution text |Description text +####### +#Newlines can be utilized to add some clarity ensuring continuing line +#has at least one leading space +#ResourceKey=\ +# ERR0000E\ +# Sample error msg txt\ +# Sample resolution msg\ +# Sample description txt +# +###### +#Error code classification category +#000 Info/Debug +#100 Permission errors +#200 Availability errors/Timeouts +#300 Data errors +#400 Schema Interface type/validation errors +#500 Business process errors +#900 Unknown errors +# +######################################################################## + +DISTRIBUTION_EVENT=\ + BABEL0001I|\ + Distribution event: {0}|\ + A distribution event was received from ASDC|\ + +PROCESS_REQUEST_ERROR=\ + BABEL0002E|\ + Error while processing REST request.|\ + +INVALID_REQUEST_JSON=\ + BABEL0003E|\ + Error while processing JSON in request body.|\ + +INVALID_CSAR_FILE=\ + BABEL0004E|\ + Error while processing CSAR file.|\ \ No newline at end of file diff --git a/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context b/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context new file mode 100644 index 0000000..8514196 --- /dev/null +++ b/src/main/runtime/context/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.context @@ -0,0 +1 @@ +{"context":{"contextClass":"ajsc.Context","contextId":"__module_ajsc_namespace_name__:__module_ajsc_namespace_version__","contextName":"__module_ajsc_namespace_name__","contextVersion":"__module_ajsc_namespace_version__","description":"__module_ajsc_namespace_name__ Context"}} \ No newline at end of file diff --git a/src/main/runtime/context/default#0.context b/src/main/runtime/context/default#0.context new file mode 100644 index 0000000..d1b5ab4 --- /dev/null +++ b/src/main/runtime/context/default#0.context @@ -0,0 +1 @@ +{"context":{"contextClass":"ajsc.Context","contextId":"default:0","contextName":"default","contextVersion":"0","description":"Default Context"}} \ No newline at end of file diff --git a/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json b/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json new file mode 100644 index 0000000..d0954cf --- /dev/null +++ b/src/main/runtime/deploymentPackage/__module.ajsc.namespace.name__#__module.ajsc.namespace.version__.json @@ -0,0 +1 @@ +{"deploymentPackage":{"Class":"ajsc.DeploymentPackage","Id":"__module.ajsc.namespace.name__:__module_ajsc_namespace_version__","namespace":"__module_ajsc_namespace_name__","namespaceVersion":"__module_ajsc_namespace_version__","description":"__module_ajsc_namespace_name__ __module_ajsc_namespace_version__ - default description","userId":"ajsc"}} \ No newline at end of file diff --git a/src/main/runtime/shiroRole/ajscadmin.json b/src/main/runtime/shiroRole/ajscadmin.json new file mode 100644 index 0000000..f5e981e --- /dev/null +++ b/src/main/runtime/shiroRole/ajscadmin.json @@ -0,0 +1 @@ +{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"ajscadmin","name":"ajscadmin","permissions":"[ajscadmin:*, ajsc:*]"} \ No newline at end of file diff --git a/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json b/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json new file mode 100644 index 0000000..2dae9f5 --- /dev/null +++ b/src/main/runtime/shiroRole/contextadmin#__module.ajsc.namespace.name__.json @@ -0,0 +1 @@ +{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"contextadmin:__module_ajsc_namespace_name__","name":"contextadmin:__module_ajsc_namespace_name__","permissions":"[]"} \ No newline at end of file diff --git a/src/main/runtime/shiroRole/contextadmin#default.json b/src/main/runtime/shiroRole/contextadmin#default.json new file mode 100644 index 0000000..5de814e --- /dev/null +++ b/src/main/runtime/shiroRole/contextadmin#default.json @@ -0,0 +1 @@ +{"shiroRoleClass":"ajsc.auth.ShiroRole","shiroRoleId":"contextadmin:default","name":"contextadmin:default","permissions":"[]"} \ No newline at end of file diff --git a/src/main/runtime/shiroUser/ajsc.json b/src/main/runtime/shiroUser/ajsc.json new file mode 100644 index 0000000..f4c7855 --- /dev/null +++ b/src/main/runtime/shiroUser/ajsc.json @@ -0,0 +1 @@ +{"shiroUserClass":"ajsc.auth.ShiroUser","shiroUserId":"ajsc","passwordHash":"9471697417008c880720ba54c6038791ad7e98f3b88136fe34f4d31a462dd27a","permissions":"[*:*]","username":"ajsc"} \ No newline at end of file diff --git a/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json b/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json new file mode 100644 index 0000000..cb8d483 --- /dev/null +++ b/src/main/runtime/shiroUserRole/ajsc#ajscadmin.json @@ -0,0 +1 @@ +{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:ajscadmin","roleId":"ajscadmin","userId":"ajsc"} \ No newline at end of file diff --git a/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json b/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json new file mode 100644 index 0000000..95d2361 --- /dev/null +++ b/src/main/runtime/shiroUserRole/ajsc#contextadmin#__module.ajsc.namespace.name__.json @@ -0,0 +1 @@ +{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:contextadmin:__module_ajsc_namespace_name__","roleId":"contextadmin:__module_ajsc_namespace_name__","userId":"ajsc"} \ No newline at end of file diff --git a/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json b/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json new file mode 100644 index 0000000..2bd5063 --- /dev/null +++ b/src/main/runtime/shiroUserRole/ajsc#contextadmin#default.json @@ -0,0 +1 @@ +{"shiroUserRoleClass":"ajsc.auth.ShiroUserRole","shiroUserRoleId":"ajsc:contextadmin:default","roleId":"contextadmin:default","userId":"ajsc"} \ No newline at end of file -- cgit 1.2.3-korg