aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
authorEdwin Lawrance <Edwin.Lawrance@amdocs.com>2017-09-22 16:55:07 +0100
committerEdwin Lawrance <Edwin.Lawrance@amdocs.com>2017-10-05 11:36:10 +0100
commit1433a67a9e3dcad20d0dda8edcaad9403320f4f9 (patch)
tree91dc94ca6acb183f5c87e3e141f678e1f06b6945 /src/main/java
parent5f3bae5a14b3167d43c3bedf83446cbf5269d5c2 (diff)
Initial code submit for Babel
Change-Id: I3738ebe15eadbbd6d16e24e374c6e40c535b425d Issue-ID: AAI-46 Signed-off-by: Edwin Lawrance <Edwin.Lawrance@amdocs.com>
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/onap/aai/auth/AAIAuthException.java39
-rw-r--r--src/main/java/org/onap/aai/auth/AAIMicroServiceAuth.java121
-rw-r--r--src/main/java/org/onap/aai/auth/AAIMicroServiceAuthCore.java287
-rw-r--r--src/main/java/org/onap/aai/auth/FileWatcher.java63
-rw-r--r--src/main/java/org/onap/aai/babel/config/BabelAuthConfig.java51
-rw-r--r--src/main/java/org/onap/aai/babel/csar/CsarConverterException.java40
-rw-r--r--src/main/java/org/onap/aai/babel/csar/CsarToXmlConverter.java88
-rw-r--r--src/main/java/org/onap/aai/babel/csar/extractor/InvalidArchiveException.java50
-rw-r--r--src/main/java/org/onap/aai/babel/csar/extractor/YamlExtractor.java149
-rw-r--r--src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java50
-rw-r--r--src/main/java/org/onap/aai/babel/service/GenerateArtifactsService.java51
-rw-r--r--src/main/java/org/onap/aai/babel/service/GenerateArtifactsServiceImpl.java148
-rw-r--r--src/main/java/org/onap/aai/babel/service/data/BabelArtifact.java63
-rw-r--r--src/main/java/org/onap/aai/babel/service/data/BabelRequest.java53
-rw-r--r--src/main/java/org/onap/aai/babel/util/RequestValidationException.java42
-rw-r--r--src/main/java/org/onap/aai/babel/util/RequestValidator.java50
-rw-r--r--src/main/java/org/onap/aai/babel/xml/generator/ArtifactGenerator.java39
-rw-r--r--src/main/java/org/onap/aai/babel/xml/generator/ModelGenerator.java136
-rw-r--r--src/main/java/org/onap/aai/babel/xml/generator/XmlArtifactGenerationException.java40
19 files changed, 1560 insertions, 0 deletions
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<String, AAIAuthUser> 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<String, AAIAuthRole> roles;
+
+ public AAIAuthUser() {
+ this.roles = new HashMap<>();
+ }
+
+ public String getUser() {
+ return this.username;
+ }
+
+ public Map<String, AAIAuthRole> getRoles() {
+ return this.roles;
+ }
+
+ public void addRole(String roleName, AAIAuthRole r) {
+ this.roles.put(roleName, r);
+ }
+
+ public boolean checkAllowed(String checkFunc) {
+ for (Entry<String, AAIAuthRole> 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<String> 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<org.openecomp.sdc.generator.data.Artifact> a list of generated xml artifacts
+ * @throws CsarConverterException if there is an error either extracting the yaml files or generating xml artifacts
+ */
+ public List<BabelArtifact> 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<BabelArtifact> xmlArtifacts;
+
+ try {
+ logger.debug("Calling YamlExtractor to extract ymlFiles");
+ List<Artifact> 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<String> 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.<br>
+ * <br>
+ * If the archive contains no yml files it will return an empty list.<br>
+ *
+ * @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<Artifact> 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<Artifact> extract(byte[] archive, String name, String version) throws InvalidArchiveException {
+ validateRequest(archive, name, version);
+
+ logger.info(ApplicationMsgs.DISTRIBUTION_EVENT, "Extracting CSAR archive: " + name);
+
+ List<Artifact> ymlFiles = new ArrayList<>();
+ try (SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(archive);
+ ZipFile zipFile = new ZipFile(inMemoryByteChannel)) {
+ for (Enumeration<ZipArchiveEntry> 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<String, Object> yaml =
+ (LinkedHashMap<String, Object>) yamlParser.load(zipFile.getInputStream(entry));
+ HashMap<String, Object> metadata = (LinkedHashMap<String, Object>) 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<BabelArtifact> 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<BabelArtifact> generateArtifacts(List<Artifact> 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<BabelArtifact> generateArtifacts(List<Artifact> 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<String, String> 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);
+ }
+}