aboutsummaryrefslogtreecommitdiffstats
path: root/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration
diff options
context:
space:
mode:
Diffstat (limited to 'ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration')
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AbstractWriter.java491
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AddNamedPropWildcard.java96
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FMObject.java148
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FitNesseJUnitWriter.java141
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/RelationshipWriter.java405
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuite.java441
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuiteWriter.java375
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/child_test_content_txt.ftl33
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/empty_context_txt.ftl21
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/end_point_suite_content_txt.ftl32
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/junit_class_java.ftl33
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/properties_xml.ftl48
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/recursive_teardown_content_txt.ftl29
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_content_txt.ftl37
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_content_txt.ftl36
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_reversed_content_txt.ftl36
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/remove_children_content_txt.ftl25
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/static_page_content_txt.ftl21
-rw-r--r--ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/version_suite_content_txt.ftl31
19 files changed, 2479 insertions, 0 deletions
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AbstractWriter.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AbstractWriter.java
new file mode 100644
index 0000000..c440c14
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AbstractWriter.java
@@ -0,0 +1,491 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.IntrospectorFactory;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.LoaderFactory;
+import org.openecomp.aai.introspection.ModelType;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.logging.LogLineBuilder;
+import org.openecomp.aai.rest.CustomJacksonJaxBJsonProvider;
+import org.openecomp.aai.testing.LocateEndPoints;
+import org.openecomp.aai.testsuitegeneration.TestSuite.TestSuiteBuilder;
+import org.springframework.web.util.UriUtils;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.Multimap;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+
+public abstract class AbstractWriter {
+
+ protected final String PROPERTIES_XML = "properties_xml.ftl";
+
+ protected final String TEMPLATE_PATH = "src/main/java/org/openecomp/aai/testsuitegeneration/";
+
+ public static final String USERNAME_PLACEHOLDER = "#!#username.placeholder#!#";
+
+ public final Integer START_PORT = 42671;
+ protected Map<String, Object> supplimentalMap = new HashMap<>();
+ protected Configuration configuration = new Configuration();
+ protected String outputPath;
+ protected Version apiVersion;
+ protected Version currentApiVersion;
+ protected String tearDownPath;
+ protected String tearDownPathChildren;
+ protected String deletePage;
+ protected String parentCleanUpPage;
+ protected String classPackagePath;
+ protected String cleanUpPage;
+ protected Multimap<String, String> DeleteScope;
+ protected Multimap<String, String> EdgeRules;
+ protected final LogLineBuilder llBuilder = new LogLineBuilder();
+ protected final Loader loader;
+
+
+ /**
+ * Instantiates a new abstract writer.
+ *
+ * @param file the file
+ * @param builder the builder
+ */
+ // Abstract constructor
+ public AbstractWriter(File file, TestSuiteBuilder builder) {
+ this.outputPath = file.getAbsolutePath();
+ this.apiVersion = builder.getApiVersion();
+ this.currentApiVersion = builder.getCurrentApiVersion();
+ this.DeleteScope = builder.getDeleteScope();
+ this.EdgeRules = builder.getEdgeMap();
+ this.classPackagePath = builder.getPojoPackage();
+ this.deletePage = "";
+ this.tearDownPath = "";
+ this.parentCleanUpPage = "";
+ this.loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, apiVersion, llBuilder);
+ createVersionSuite();
+ }
+
+
+ /**
+ * Creates a suite for the writer's specified API version.
+ */
+ private void createVersionSuite() {
+ Map<String, Object> suiteMap = new HashMap<>();
+
+ // Set the PUT expected result
+ String createStatus = "200";
+ Pattern p = Pattern.compile("v(\\d+)");
+ Matcher m = p.matcher(apiVersion.toString());
+ Integer versionNumber = 0;
+ if (m.find()) {
+ versionNumber = Integer.parseInt(m.group(1));
+ }
+
+ createStatus = "201";
+ // Add the placeholder values to the map
+ suiteMap.put("version", apiVersion);
+ suiteMap.put("currentVersion", currentApiVersion);
+ suiteMap.put("createStatus", createStatus);
+ suiteMap.put("type", "suite");
+ suiteMap.put("slimPort", START_PORT + (versionNumber * 20));
+
+ // Create the directory
+ File dir = new File(this.outputPath);
+ dir.mkdir();
+
+ // Process the freemarker templates
+ this.processDataModel("version_suite_content_txt.ftl", "content.txt", dir, suiteMap);
+ this.processDataModel("properties_xml.ftl", "properties.xml", dir, suiteMap);
+ }
+
+
+ /**
+ * Generates the necessary pages to recursively clean up children objects.
+ *
+ * @param path the path
+ * @param fitnessePath the fitnesse path
+ * @param topLevel the top level
+ * @param lep the lep
+ * @param additionalName the additional name
+ * @param urlVariableName the url variable name
+ * @return the string
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws SecurityException the security exception
+ */
+ protected String generateRecursiveCleanUp(String path, String fitnessePath, Introspector topLevel, LocateEndPoints lep, String additionalName, String urlVariableName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+ String childPath = "";
+ String fitnessePageName = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, topLevel.getDbName());
+
+ String folderName = fitnessePageName + "AdditionalTests";
+ String additionalPath = fitnessePath + "/" + folderName;
+ File dir = new File(additionalPath);
+ dir.mkdir();
+ Map<String, Object> additionalMap = new HashMap<>();
+ additionalMap.put("type", "static");
+ additionalMap.put("skip", "true");
+ processDataModel("static_page_content_txt.ftl", "content.txt", dir, additionalMap);
+ processDataModel("properties_xml.ftl", "properties.xml", dir, additionalMap);
+ List<String> pages = findCascadeDeleteChildren(topLevel, additionalPath, path, lep, additionalName);
+
+ Map<String, Object> map = new HashMap<>();
+
+ String testPageName = "ChildrenTearDown" + additionalName;
+ String tearDownPath = additionalPath + "/" + testPageName;
+ dir = new File(tearDownPath);
+ dir.mkdir();
+
+ map.put("type", "test");
+ map.put("pages", pages);
+ map.put("parentCleanUpPage", ".AAI.Tests.GenericTests.FauxRecursiveDelete");
+ map.put("errorCheckPage", ".AAI.Tests.GenericTests.DeleteErrorCheck");
+ String decodedUrl = urlVariableName;
+ try {
+ decodedUrl = UriUtils.decode(decodedUrl, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ map.put("urlVariableName", this.replaceUsernamePlaceholders(decodedUrl));
+ this.processDataModel("recursive_teardown_content_txt.ftl", "content.txt", dir, map);
+ this.processDataModel("properties_xml.ftl", "properties.xml", dir, map);
+
+
+
+ return folderName + "." + testPageName;
+ }
+
+
+ /**
+ * Searches for children to be deleted via cascade delete.
+ *
+ * @param obj the obj
+ * @param fitNessePath the fit nesse path
+ * @param restPath the rest path
+ * @param lep the lep
+ * @param additionalName the additional name
+ * @return the list
+ */
+ protected List<String> findCascadeDeleteChildren(Introspector obj, String fitNessePath, String restPath, LocateEndPoints lep, String additionalName) {
+ List<String> list = new ArrayList<>();
+ try {
+ findHelper(obj, list, fitNessePath, restPath, lep, additionalName);
+ } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | InstantiationException | UnsupportedEncodingException e) {
+ e.printStackTrace();
+ }
+ return list;
+ }
+
+
+ /**
+ * Helper to the find method.
+ *
+ * @param obj the obj
+ * @param list the list
+ * @param fitNessePath the fit nesse path
+ * @param restPath the rest path
+ * @param lep the lep
+ * @param additionalName the additional name
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws InstantiationException the instantiation exception
+ * @throws UnsupportedEncodingException the unsupported encoding exception
+ */
+ protected void findHelper(Introspector obj, List<String> list, String fitNessePath, String restPath, LocateEndPoints lep, String additionalName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, UnsupportedEncodingException {
+
+ if (obj == null) {
+ return;
+ }
+ List<String> properties = obj.getProperties();
+ properties.remove("relationship-list");
+ for (String prop : properties) {
+
+ if (obj.isComplexType(prop)) {
+ Introspector child = IntrospectorFactory.newInstance(obj.getModelType(), obj.getValue(prop), llBuilder);
+
+ findHelper(IntrospectorFactory.newInstance(obj.getModelType(), obj.getValue(prop), llBuilder), list, fitNessePath, restPath, lep, additionalName);
+ } else if (obj.isListType(prop)) {
+ if (DeleteScope.get(
+ CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, this.trimClassName(obj.getGenericType(prop))))
+ .contains("CASCADE_TO_CHILDREN")) {
+ List<?> children = (List<?>)obj.getValue(prop);
+ Introspector temp = null;
+ List<String> urls = new ArrayList<>();
+ for (Object child : children) {
+ temp = IntrospectorFactory.newInstance(obj.getModelType(), child, llBuilder);
+ String decodedUrl = restPath + temp.getURI();
+ try {
+ decodedUrl = UriUtils.decode(decodedUrl, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ urls.add(replaceUsernamePlaceholders(decodedUrl));
+ }
+
+ Map<String, Object> map = new HashMap<>();
+
+ map.put("deleteChildren", ".AAI.Tests.GenericTests.CleanUp");
+ map.put("urls", urls);
+ map.put("type", "test");
+ String childrenTestPage = "RemoveChildren" + additionalName;
+ String removeChildrenPath = fitNessePath + "/" + childrenTestPage;
+ File dir = new File(removeChildrenPath);
+ dir.mkdir();
+ this.processDataModel("remove_children_content_txt.ftl", "content.txt", dir, map);
+ this.processDataModel("properties_xml.ftl", "properties.xml", dir, map);
+ list.add(childrenTestPage);
+ } else {
+ //still wrong
+ Introspector temp = obj.newIntrospectorInstanceOfNestedProperty(prop);
+ if (this.hasChildren(temp) && DeleteScope.get(
+ CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, this.trimClassName(obj.getGenericType(prop))))
+ .contains("THIS_NODE_ONLY")) {
+ List<?> children = (List<?>)obj.getValue(prop);
+ String result = "";
+ for (int i = 0; i < children.size(); i++) {
+ Introspector child = IntrospectorFactory.newInstance(obj.getModelType(), children.get(i), llBuilder);
+
+ try {
+ result = generateRecursiveCleanUp(restPath + child.getURI(), fitNessePath, child, lep, additionalName + new Integer(i).toString(), "!-" + restPath + child.getURI() + "-!");
+ } catch (NoSuchMethodException | SecurityException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ list.add(result);
+
+ }
+
+ }
+ }
+
+ }
+ }
+
+ }
+
+ /**
+ * Checks for children.
+ *
+ * @param obj the obj
+ * @return true, if successful
+ */
+ protected boolean hasChildren(Introspector obj) {
+
+ for (String prop : obj.getProperties()) {
+ if (!prop.equals("relationship-list")) {
+
+ if (obj.isComplexType(prop) || (obj.isListType(prop) && obj.isComplexGenericType(prop))) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+
+ /**
+ * Processes the template file through freemarker.
+ *
+ * @param templateFilename The filename of the template to process.
+ * @param outputFilename THe filename of the output file to generate.
+ * @param outputDirectory The directory of the output file.
+ * @param variableMap The variable map where key is the placeholder variable name.
+ */
+ protected void processDataModel(String templateFilename, String outputFilename, File outputDirectory, Map<String, Object> variableMap) {
+
+ try {
+ Template template = configuration.getTemplate(TEMPLATE_PATH + templateFilename);
+ Writer file = new FileWriter(new File(outputDirectory.getPath() + "/" + outputFilename));
+ template.process(variableMap, file);
+ file.flush();
+ } catch(Exception e) {
+ System.out.println("Failed to process file {" + outputFilename + "}");
+ e.printStackTrace();
+ }
+ }
+
+
+ /**
+ * Marshals an object into a JSON string.
+ *
+ * @param obj The object to marshal
+ * @return A string representation of the object in JSON format.
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ protected String jsonMarshal(Object obj) throws IOException {
+ CustomJacksonJaxBJsonProvider provider = new CustomJacksonJaxBJsonProvider();
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ provider.writeTo(obj, obj.getClass(), null, null, null, null, os);
+ String output = new String(os.toByteArray(), "UTF-8");
+ ObjectMapper mapper = provider.getMapper();
+ Object json = mapper.readValue(output, obj.getClass());
+ output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
+ return output;
+ }
+
+
+ /**
+ * Retrieves the root to FitNesse from the full path.
+ *
+ * @param fullPath The full output path.
+ * @return The root to FitNesseRoot
+ */
+ protected String getFitNesseRoot(String fullPath) {
+ String result = fullPath;
+ Pattern p = Pattern.compile("Root(?:/|\\\\)(.*)");
+ Matcher m = p.matcher(fullPath);
+ if(m.find()) {
+ result = m.group(1);
+ }
+ return result;
+ }
+
+
+ /**
+ * Converts an UpperCamel class name to a lower-hyphen class name.
+ * @param className The class name in UpperCamel format.
+ * @return The class name is lower-hyphen format.
+ */
+ protected String getHyphenatedClassName(String className) {
+ String output = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, className);
+
+ // Special case for cvlan-tag
+ if(output.equals("cvlan-tag-entry")) {
+ output = "cvlan-tag";
+ }
+
+ return output;
+ }
+
+ /**
+ * Checks if is plural.
+ *
+ * @param word the word
+ * @return true, if is plural
+ */
+ protected boolean isPlural(String word) {
+ return word.matches(".*?(es|(?<!s)s)$");
+ }
+
+ /**
+ * Trim class name.
+ *
+ * @param name the name
+ * @return the string
+ */
+ protected String trimClassName(String name) {
+
+ return name.substring(name.lastIndexOf('.') + 1, name.length());
+ }
+
+ /**
+ * Gets the key from path.
+ *
+ * @param path the path
+ * @return the key from path
+ */
+ protected String getKeyFromPath(String path) {
+ Pattern p = Pattern.compile("(\\{(.+?)\\}\\/?)+$");
+ Matcher m = p.matcher(path);
+ String key = "";
+ if (m.matches()) {
+ key = m.group();
+ }
+ return key;
+ }
+ protected String encodeUsernamePlaceholders(String body) {
+ String encode = "";
+ try {
+ encode = UriUtils.encodePath(USERNAME_PLACEHOLDER, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return body.replace(USERNAME_PLACEHOLDER, encode);
+ }
+ protected String decodeUserNamePlaceholders(String body) {
+ String decode = "";
+ try {
+ decode = UriUtils.decode(body, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return decode;
+ }
+ /**
+ * Replace username placeholders.
+ *
+ * @param body the body
+ * @return the string
+ */
+ protected String replaceUsernamePlaceholders(String body) {
+ return body.replace(USERNAME_PLACEHOLDER, "--!${username}!-");
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AddNamedPropWildcard.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AddNamedPropWildcard.java
new file mode 100644
index 0000000..f043769
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/AddNamedPropWildcard.java
@@ -0,0 +1,96 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.util.List;
+
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.IntrospectorWalker;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.introspection.Wanderer;
+import org.openecomp.aai.logging.LogLineBuilder;
+
+public class AddNamedPropWildcard implements Wanderer {
+
+
+ private final LogLineBuilder llBuilder;
+ private Loader loader;
+ public AddNamedPropWildcard(Loader loader) {
+ this.llBuilder = new LogLineBuilder();
+ this.loader = loader;
+
+ }
+
+ public void process(Introspector obj) {
+
+ IntrospectorWalker walker = new IntrospectorWalker(this, llBuilder);
+ walker.walk(obj);
+
+ }
+ @Override
+ public void processPrimitive(String propName, Introspector obj) {
+ //NO-OP
+ }
+
+ @Override
+ public void processPrimitiveList(String propName, Introspector obj) {
+ //NO-OP
+ }
+
+ @Override
+ public void processComplexObj(Introspector obj) {
+ String nameProp = obj.getMetadata("nameProps");
+ if (nameProp != null && !nameProp.equals("")) {
+ String[] nameProps = nameProp.split(",");
+ for (String prop : nameProps) {
+ if (obj.getClass(prop).equals(String.class)) {
+
+ if (obj.getValue(prop) == null) {
+ if (!isDefaultCloudRegion(obj)) {
+ obj.setValue(prop, "*");
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private boolean isDefaultCloudRegion(Introspector obj) {
+ return false;
+ }
+ @Override
+ public void modifyComplexList(List<Object> list, Introspector parent, Introspector child) {
+ //NO-OP
+ }
+
+ @Override
+ public boolean createComplexObjIfNull() {
+ return false;
+ }
+
+ @Override
+ public int createComplexListSize(Introspector parent, Introspector child) {
+ return 0;
+ }
+
+
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FMObject.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FMObject.java
new file mode 100644
index 0000000..ed6a152
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FMObject.java
@@ -0,0 +1,148 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.MediaType;
+
+import org.openecomp.aai.rest.CustomJacksonJaxBJsonProvider;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+public class FMObject {
+ private Configuration cfg;
+ private Map<String, Object> root;
+ private String jsonString;
+ private String key;
+ private String featureURL;
+ private String className;
+ private String dirPath;
+ private final String templatePath = "src/main/java/org/openecomp/aai/freemarker/";
+
+ /**
+ * Instantiates a new FM object.
+ *
+ * @param obj the obj
+ * @param dirPath the dir path
+ * @param className the class name
+ * @param key the key
+ * @param featureURL the feature URL
+ */
+ public FMObject (Object obj, String dirPath, String className, String key, String featureURL){
+ this.cfg = new Configuration();
+ this.root = new HashMap<String, Object>();
+ this.key = key;
+ this.featureURL = featureURL;
+ this.className = className.substring(className.lastIndexOf('.')+1, className.length());
+ this.dirPath = dirPath;
+ try {
+ this.jsonString = jsonMarshal(obj);
+ } catch (IOException e1) {
+ // TODO Auto-generated catch block
+ e1.printStackTrace();
+ }
+
+ this.root.put("fields", jsonString);
+ this.root.put("key", this.key);
+ this.root.put("featureURL", this.featureURL);
+
+ }
+
+ /**
+ * Gets the template.
+ *
+ * @param name the name
+ * @return the template
+ */
+ private Template getTemplate(String name) {
+ Template template = null;
+ try {
+ template = cfg.getTemplate(templatePath + name);
+ } catch (IOException e) {
+ System.out.println("Template not found: " + e.getMessage());
+ }
+ return template;
+ }
+
+ /**
+ * Process data model.
+ *
+ * @param tempFileName the temp file name
+ * @param outFileName the out file name
+ * @param dir the dir
+ */
+ public void processDataModel(String tempFileName, String outFileName, File dir){
+ Template template = this.getTemplate(tempFileName);
+ try {
+ Writer file = new FileWriter (new File(dir.getPath()+"/"+outFileName));
+ template.process(this.root, file);
+ file.flush();
+ } catch (IOException | TemplateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Creates the output files.
+ */
+ public void createOutputFiles(){
+ File dir = new File(this.dirPath+"/"+this.className);
+ dir.mkdir();
+ processDataModel("content_txt.ftl", "content.txt", dir);
+ processDataModel("test_properties_xml.ftl", "properties.xml", dir);
+ }
+
+ /**
+ * Json marshal.
+ *
+ * @param o the o
+ * @return the string
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ private String jsonMarshal(Object o) throws IOException {
+ CustomJacksonJaxBJsonProvider provider = new CustomJacksonJaxBJsonProvider();
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+
+ provider.writeTo(o, o.getClass(), null, null, MediaType.APPLICATION_JSON_TYPE, null, os);
+
+ String output = new String(os.toByteArray(), "UTF-8");
+
+ ObjectMapper mapper = provider.getMapper();
+
+ Object json = mapper.readValue(output, o.getClass());
+
+ output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
+ return output;
+ }
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FitNesseJUnitWriter.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FitNesseJUnitWriter.java
new file mode 100644
index 0000000..01b0784
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/FitNesseJUnitWriter.java
@@ -0,0 +1,141 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openecomp.aai.introspection.Version;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+public class FitNesseJUnitWriter {
+
+ private Configuration cfg = new Configuration();
+ private String templatePath = "src/main/java/org/openecomp/aai/freemarker/";
+ private String outputPath = "";
+
+
+ /**
+ * Instantiates a new fit nesse J unit writer.
+ *
+ * @param outputPath the output path
+ */
+ public FitNesseJUnitWriter(String outputPath) {
+
+ this.outputPath = outputPath;
+ }
+
+ /**
+ * Instantiates a new fit nesse J unit writer.
+ */
+ @SuppressWarnings("unused")
+ private FitNesseJUnitWriter() {
+
+ }
+
+ /**
+ * Creates the J unit class.
+ *
+ * @param packageName the package name
+ * @param apiVersion the api version
+ * @param fullSuitePath the full suite path
+ */
+ public void createJUnitClass(String packageName, Version apiVersion, String fullSuitePath) {
+ Map<String, Object> map = new HashMap<>();
+
+ packageName = packageName + "." + apiVersion;
+ String suiteName = this.getFitNesseRoot(fullSuitePath);
+ String[] parts = suiteName.split("\\.");
+ String className = parts[parts.length-1] + "IT";
+ map.put("packageName", packageName);
+ map.put("className", className);
+ map.put("suiteName", suiteName);
+ File dir = new File(this.outputPath + "/" + packageName.replaceAll("\\.", "/") + "/");
+ dir.mkdirs();
+ this.processDataModel("junit_class_java.ftl", className + ".java", dir, map);
+
+ }
+
+ /**
+ * Gets the template.
+ *
+ * @param name the name
+ * @return the template
+ */
+ private Template getTemplate(String name) {
+ Template template = null;
+ try {
+ template = cfg.getTemplate(templatePath + name);
+ } catch (IOException e) {
+ System.out.println("Template not found: " + e.getMessage());
+ }
+ return template;
+ }
+
+ /**
+ * Process data model.
+ *
+ * @param tempFileName the temp file name
+ * @param outFileName the out file name
+ * @param dir the dir
+ * @param map the map
+ */
+ public void processDataModel(String tempFileName, String outFileName, File dir, Map<?,?> map){
+ Template template = this.getTemplate(tempFileName);
+ try {
+ Writer file = new FileWriter (new File(dir.getPath()+"/"+outFileName));
+ template.process(map, file);
+ file.flush();
+ } catch (IOException | TemplateException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ }
+
+ /**
+ * Gets the fit nesse root.
+ *
+ * @param fullPath the full path
+ * @return the fit nesse root
+ */
+ private String getFitNesseRoot(String fullPath) {
+ String result = fullPath;
+ Pattern p = Pattern.compile("FitNesseRoot(?:/|\\\\)(.*)");
+ Matcher m = p.matcher(fullPath);
+
+ if (m.find()) {
+ result = m.group(1);
+ }
+
+ return result.replaceAll("/|\\\\", ".");
+
+ }
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/RelationshipWriter.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/RelationshipWriter.java
new file mode 100644
index 0000000..cfc2a62
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/RelationshipWriter.java
@@ -0,0 +1,405 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.JAXBException;
+
+import org.eclipse.persistence.exceptions.DynamicException;
+import org.json.JSONException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.IntrospectorFactory;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.logging.LogLineBuilder;
+import org.openecomp.aai.testing.LocateEndPoints;
+import org.openecomp.aai.testsuitegeneration.TestSuite.TestSuiteBuilder;
+
+import com.att.aft.dme2.internal.google.common.base.CaseFormat;
+
+public class RelationshipWriter extends AbstractWriter {
+
+ protected final String RELATIONSHIP_CONTENT = "relationship_content_txt.ftl";
+ protected final String RELATIONSHIP_SINGLE_CONTENT = "relationship_single_content_txt.ftl";
+ protected final String RELATIONSHIP_SINGLE_CONTENT_REVERSED = "relationship_single_reversed_content_txt.ftl";
+ protected final LogLineBuilder llBuilder = new LogLineBuilder();
+
+ // Hash map used for storing parent objects for re-use
+ //HashMap<String, Introspector> parentMap = new HashMap<>();
+ Loader loader = null;
+
+ /**
+ * Instantiates a new relationship writer.
+ *
+ * @param file the file
+ * @param builder the builder
+ * @param loader the loader
+ */
+ // Constructor
+ public RelationshipWriter(File file, TestSuiteBuilder builder, Loader loader) {
+
+ // Just call the super constructor
+ super(file, builder);
+
+ this.loader = loader;
+
+ }
+
+
+ /**
+ * Generate relationship test.
+ *
+ * @param objA the obj A
+ * @param objB the obj B
+ * @param lep the lep
+ * @param edgeMapProperties the edge map properties
+ * @param minListSize the min list size
+ * @param maxListSize the max list size
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws SecurityException the security exception
+ * @throws Exception the exception
+ */
+ public void generateRelationshipTest(Introspector objA, Introspector objB, LocateEndPoints lep, String edgeMapProperties, int minListSize, int maxListSize) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, Exception {
+ if(objA.getDbName().equals("ipaddress") || objB.getDbName().equals("ipaddress")) return;
+
+ // Get the unpopulated feature URls
+ String featureUrlA = this.getUnpopulatedFeatureUrl(objA, lep);
+ String featureUrlB = this.getUnpopulatedFeatureUrl(objB, lep);
+ String inputA = objA.getDbName();
+ String inputB = objB.getDbName();
+ String classA = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, inputA);
+ String classB = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, inputB);
+ // Prepare variable map
+ Map<String, Object> variableMap = new HashMap<>();
+ variableMap.put("type", "test");
+
+
+
+ ////////////////////////////////
+ // Process object A //
+ ////////////////////////////////
+ cleanUpPage = ".AAI.Tests.GenericTests.CleanUp";
+ if(hasDependency(featureUrlA)) {
+ objA = createParentObject(featureUrlA, lep);
+
+ // Get the parent name lower-hyphen format
+ String hyphenatedParentName = this.getHyphenatedParentName(featureUrlA);
+ Introspector parentObj =loader.introspectorFromName(hyphenatedParentName);
+ String topFeatureUrl = this.getUnpopulatedFeatureUrl(parentObj, lep);
+ String populatedUrl = replaceUsernamePlaceholders((String)lep.populatePath(objA, topFeatureUrl).get(0));
+ variableMap.put("topFeatureUrlA", populatedUrl);
+
+ boolean hasChildren = this.hasChildren(parentObj);
+
+ if(hasChildren && DeleteScope.get(hyphenatedParentName).contains("THIS_NODE_ONLY")) {
+ try {
+ cleanUpPage = generateRecursiveCleanUp(populatedUrl, outputPath, objA, lep, classA + "To" + classB + "A", "${topFeatureURL_A}");
+
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+
+ } else {
+ objA = lep.createChildFromClassName(objA.getName(), 1, 1, true);
+ String populatedUrl = replaceUsernamePlaceholders((String)lep.populatePath(objA, featureUrlA).get(0));
+ variableMap.put("topFeatureUrlA", populatedUrl);
+ boolean hasChildren = this.hasChildren(objA);
+
+ if(hasChildren && DeleteScope.get(objA.getDbName()).contains("THIS_NODE_ONLY")) {
+ try {
+ cleanUpPage = generateRecursiveCleanUp(populatedUrl, outputPath, objA, lep, classA + "To" + classB + "A", "${topFeatureURL_A}");
+
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ // Create the relationship object
+ Introspector relationshipA = lep.populateRelationship(objA, inputA, featureUrlA);
+ relationshipA.setValue("related-link", "-!${address}${relationshipURLA}!-/");
+ // Put the values to the map
+ List<Object> rubbishTuple = lep.populatePath(objA, featureUrlA);
+ String populatedPathA = (String)rubbishTuple.get(0);
+ Introspector childA = (Introspector)rubbishTuple.get(1);
+ variableMap.put("deletePageA", cleanUpPage);
+ variableMap.put("objectBodyA", replaceUsernamePlaceholders(objA.marshal(true)));
+ variableMap.put("featureUrlA", replaceUsernamePlaceholders(populatedPathA));
+ variableMap.put("relationshipURLA", replaceUsernamePlaceholders(populatedPathA));
+ variableMap.put("objectRelationshipA", replaceUsernamePlaceholders(relationshipA.marshal(true)));
+
+
+
+ ////////////////////////////////
+ // Process object B //
+ ////////////////////////////////
+ cleanUpPage = ".AAI.Tests.GenericTests.CleanUp";
+ if(hasDependency(featureUrlB)) {
+ objB = createParentObject(featureUrlB, lep);
+
+ // Get the parent name lower-hyphen format
+ String hyphenatedParentName = this.getHyphenatedParentName(featureUrlB);
+ Introspector parentObj = IntrospectorFactory.newInstance(objB.getModelType(), loader.objectFromName(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, hyphenatedParentName)), llBuilder);
+ String topFeatureUrl = this.getUnpopulatedFeatureUrl(parentObj, lep);
+ String populatedUrl = replaceUsernamePlaceholders((String)lep.populatePath(objB, topFeatureUrl).get(0));
+
+ variableMap.put("topFeatureUrlB", populatedUrl);
+ boolean hasChildren = this.hasChildren(parentObj);
+
+ if(hasChildren && DeleteScope.get(hyphenatedParentName).contains("THIS_NODE_ONLY")) {
+ try {
+ cleanUpPage = generateRecursiveCleanUp(populatedUrl, outputPath, objB, lep, classA + "To" + classB + "B", "${topFeatureURL_B}");
+
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ e.printStackTrace();
+ }
+ }
+
+ } else {
+ objB = lep.createChildFromClassName(objB.getName(), 1, 1, true);
+ String populatedUrl = replaceUsernamePlaceholders((String)lep.populatePath(objB, featureUrlB).get(0));
+ variableMap.put("topFeatureUrlB", populatedUrl);
+ boolean hasChildren = this.hasChildren(objB);
+
+ if(hasChildren && DeleteScope.get(objB.getDbName()).contains("THIS_NODE_ONLY")) {
+ try {
+ cleanUpPage = generateRecursiveCleanUp(populatedUrl, outputPath, objB, lep, classA + "To" + classB + "B", "${topFeatureURL_B}");
+
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ e.printStackTrace();
+ } }
+ }
+
+ // Create the relationship object
+ Introspector relationshipB = lep.populateRelationship(objB, inputB, featureUrlB);
+ relationshipB.setValue("related-link", "-!${address}${relationshipURLB}!-/");
+
+ if(hasDelTarget(edgeMapProperties)) {
+ cleanUpPage = ".AAI.Tests.GenericTests.VerifyDeletion";
+ }
+ rubbishTuple = lep.populatePath(objB, featureUrlB);
+ String populatedPathB = (String)rubbishTuple.get(0);
+ Introspector childB = (Introspector)rubbishTuple.get(1);
+ variableMap.put("deletePageB", cleanUpPage);
+ variableMap.put("objectBodyB", replaceUsernamePlaceholders(objB.marshal(true)));
+ variableMap.put("featureUrlB", replaceUsernamePlaceholders(populatedPathB));
+ variableMap.put("relationshipURLB", replaceUsernamePlaceholders(populatedPathB));
+ variableMap.put("objectRelationshipB", replaceUsernamePlaceholders(relationshipB.marshal(true)));
+
+
+ // Now, we have all the objects we need and need to generate the files
+ File dir = new File(outputPath + "/" + classA + "To" + classB + "RelationshipTest");
+ dir.mkdir();
+
+
+ //////////////////////////////////
+ // Special processing //
+ //////////////////////////////////
+ Object relationshipList = null;
+ relationshipList = this.loader.objectFromName("relationship-list");
+ childA.setValue("relationship-list", relationshipList);
+ relationshipList = this.loader.objectFromName("relationship-list");
+ childB.setValue("relationship-list", relationshipList);
+
+ ((List)IntrospectorFactory.newInstance(childA.getModelType(), childA.getValue("relationship-list"), llBuilder).getValue("relationship")).add(relationshipB.getUnderlyingObject());
+ ((List)IntrospectorFactory.newInstance(childB.getModelType(), childB.getValue("relationship-list"), llBuilder).getValue("relationship")).add(relationshipA.getUnderlyingObject());
+
+ variableMap.put("expectedResultA", replaceUsernamePlaceholders(childA.marshal(true)));
+ variableMap.put("expectedResultB", replaceUsernamePlaceholders(childB.marshal(true)));
+
+ processDataModel(RELATIONSHIP_CONTENT, "content.txt", dir, variableMap);
+ processDataModel(PROPERTIES_XML, "properties.xml", dir, variableMap);
+
+ }
+
+ /**
+ * Transform relationship UR is for vserver.
+ *
+ * @param variableMap the variable map
+ */
+ private void transformRelationshipURIsForVserver(Map<String, Object> variableMap) {
+ String aURL = (String)variableMap.get("relationshipURLA");
+ String bURL = (String)variableMap.get("relationshipURLB");
+
+ variableMap.put("relationshipURLA", this.replaceWithLegacyURI(aURL));
+ variableMap.put("relationshipURLB", this.replaceWithLegacyURI(bURL));
+
+ }
+
+ /**
+ * Replace with legacy URI.
+ *
+ * @param s the s
+ * @return the string
+ */
+ private String replaceWithLegacyURI(String s) {
+ String substring = "/aai/(v\\d)/cloud-infrastructure/tenants/tenant/(.*?)/vservers/vserver/([^/]*?$)";
+ String replacement = "/aai/servers/$1/$2/vservers/$3";
+ if (s.matches(substring)) {
+ s = s.replaceFirst(substring, replacement);
+ }
+
+ return s;
+ }
+
+
+ /**
+ * Gets the unpopulated feature url.
+ *
+ * @param hyphenatedClassName the hyphenated class name
+ * @param key the key
+ * @param lep the lep
+ * @return the unpopulated feature url
+ * @throws Exception the exception
+ */
+ private String getUnpopulatedFeatureUrl(String hyphenatedClassName, String key, LocateEndPoints lep) throws Exception {
+
+ // Each path ends with the endpoint suffix
+ String endpointSuffix = "{" + hyphenatedClassName + "-" + key + "}";
+
+ // Special case feature urls
+ switch(hyphenatedClassName) {
+ case "ctag-pool":
+ // Note that these have dual keys and dependencies are not working properly (availabilityZoneName is null)
+ endpointSuffix = "{ctag-pool-target-pe}/{ctag-pool-availability-zone-name}";
+ break;
+
+ case "service-capability":
+ // Note that these have dual keys and dependencies are not working properly (vnfType is null)
+ endpointSuffix = "{service-capability-service-type}/{service-capability-vnf-type}";
+ break;
+ case "cloud-region":
+ endpointSuffix = "{cloud-region-cloud-owner}/{cloud-region-cloud-region-id}";
+ break;
+ }
+
+ // Search the endpoints for the class endpoint
+ for(String path : lep.getAllPaths()) {
+ if(path.endsWith(endpointSuffix)) {
+ return path;
+ }
+ }
+
+ // The path was not found
+ throw new IllegalArgumentException("The endpoint URL for " + hyphenatedClassName + " was not found!");
+ }
+
+ /**
+ * Gets the unpopulated feature url.
+ *
+ * @param obj the obj
+ * @param lep the lep
+ * @return the unpopulated feature url
+ * @throws Exception the exception
+ */
+ private String getUnpopulatedFeatureUrl(Introspector obj, LocateEndPoints lep) throws Exception {
+ return this.getUnpopulatedFeatureUrl(obj.getDbName(), obj.getKeys().get(0), lep);
+ }
+
+ /**
+ * Determines if a class has a parent via the url.
+ *
+ * @param featureUrl The URL
+ * @return true, if successful
+ */
+ private boolean hasDependency(String featureUrl) {
+ return featureUrl.split("/").length > 7;
+ }
+
+ /**
+ * Creates the top-level parent object for a given feature URL.
+ *
+ * @param featureUrl the feature url
+ * @param lep the lep
+ * @return the introspector
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws InstantiationException the instantiation exception
+ * @throws JSONException the JSON exception
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws JAXBException the JAXB exception
+ */
+ private Introspector createParentObject(String featureUrl, LocateEndPoints lep) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, JSONException, IOException, JAXBException {
+
+ String topLevelClass = getHyphenatedParentName(featureUrl);
+
+ return lep.createChildFromClassName(topLevelClass, 1, 1, true);
+ }
+
+ /**
+ * Checks for del target.
+ *
+ * @param properties the properties
+ * @return true, if successful
+ */
+ private boolean hasDelTarget(String properties) {
+ String[] arr = properties.split(",");
+
+ if (arr.length > 5) {
+ return arr[5].equals("true");
+ }
+
+ return false;
+ }
+
+ /**
+ * Determines if the specified object contains a relationship list.
+ *
+ * @param obj the obj
+ * @return true, if successful
+ * @throws ClassNotFoundException the class not found exception
+ * @throws SecurityException the security exception
+ */
+ private boolean hasRelationshipList(Introspector obj) throws ClassNotFoundException, SecurityException {
+
+ return obj.hasProperty("relationship-list");
+ }
+
+ /**
+ * Gets the hyphenated parent name from the given feature URL.
+ *
+ * @param featureUrl the feature url
+ * @return the hyphenated parent name
+ */
+ private String getHyphenatedParentName(String featureUrl) {
+ return featureUrl.split("/")[5];
+ }
+
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuite.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuite.java
new file mode 100644
index 0000000..68ee508
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuite.java
@@ -0,0 +1,441 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+
+import javax.xml.bind.JAXBException;
+
+import org.json.JSONException;
+import org.openecomp.aai.db.AAIProperties;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.introspection.IntrospectorFactory;
+import org.openecomp.aai.introspection.Loader;
+import org.openecomp.aai.introspection.LoaderFactory;
+import org.openecomp.aai.introspection.ModelType;
+import org.openecomp.aai.introspection.Version;
+import org.openecomp.aai.logging.LogLineBuilder;
+import org.openecomp.aai.testing.LocateEndPoints;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.Multimap;
+
+public class TestSuite {
+
+
+ private final int minListSize;
+ private final int maxListSize;
+ private final Version apiVersion;
+ private TestSuiteBuilder builder = null;
+ protected final LogLineBuilder llBuilder = new LogLineBuilder();
+
+ /**
+ * Instantiates a new test suite.
+ *
+ * @param builder the builder
+ */
+ private TestSuite(TestSuiteBuilder builder) {
+
+ this.maxListSize = builder.maxListSize;
+ this.minListSize = builder.minListSize;
+ this.apiVersion = builder.apiVersion;
+
+ this.builder = builder;
+
+ }
+
+ /**
+ * Creates the.
+ *
+ * @param endpoints the endpoints
+ * @param relationships the relationships
+ * @throws JSONException the JSON exception
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws SecurityException the security exception
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws ClassNotFoundException the class not found exception
+ * @throws NoSuchFieldException the no such field exception
+ * @throws InstantiationException the instantiation exception
+ * @throws JAXBException the JAXB exception
+ */
+ public void create(File endpoints, File relationships) throws JSONException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, IOException, ClassNotFoundException, NoSuchFieldException, InstantiationException, JAXBException {
+
+ // Load all endpoints in the system
+ LocateEndPoints lep = new LocateEndPoints(this.apiVersion);
+
+ // Create the endpoints and relationship test folders in case they don't exist
+ //createRequiredDirectories(testCaseDirPath);
+
+ // Create the test suite and JUnit test writers
+ TestSuiteWriter endpointWriter = new TestSuiteWriter(endpoints, builder);
+ //FitNesseJUnitWriter jUnitWriter = new FitNesseJUnitWriter(jUnitDirPath);
+
+ // Iterate through all the parent paths
+ for (String parentPath : lep.getParentPaths()) {
+
+ // Create a parent object
+ Introspector parentObject = lep.createChildForPath(parentPath, minListSize, maxListSize);
+
+ // Write the parent test suites
+ String endpointSuitePath = endpointWriter.createParentSuite(parentPath, parentObject, lep, null);
+ //String relationshipSuitePath = relationshipWriter.createTestSuite(parentPath, parentObject, lep, null);
+ //jUnitWriter.createJUnitClass("aai.fitnesse.suites", apiVersion, endpointSuitePath);
+
+ // Iterate through all the children paths
+ for (String childPath : lep.getChildPaths()) {
+ String genericPath = childPath;
+ if (childPath.contains(parentPath)) {
+
+ // Create a child object
+ Introspector obj = lep.createChildForPath(childPath, minListSize, maxListSize);
+ String path = lep.populateChildPath(parentObject, obj, childPath);
+ endpointWriter.addTestCase(endpointSuitePath, path, obj, genericPath, lep);
+
+ }
+ }
+ }
+
+
+ // Generate all relationship tests
+ RelationshipWriter relationshipWriter = new RelationshipWriter(relationships, builder, LoaderFactory.createLoaderForVersion(ModelType.MOXY, apiVersion, llBuilder));
+
+ // Iterate through all the relationships
+ for(String key : builder.getEdgeMap().keys()) {
+
+ String edgeMapProperties = builder.getEdgeMap().get(key).iterator().next();
+
+ // Checking to see if this is a parent-child relationship, if so then skip
+ if(edgeMapProperties.split(",")[3].equals("true")) {
+ continue;
+ }
+
+ // Extract the class names
+ String classNameA = key.substring(0, key.indexOf('|'));
+ String classNameB = key.substring(key.indexOf('|') + 1);
+
+ // Check if we need to skip this test
+ if(!builder.apiVersion.equals(builder.currentApiVersion)) {
+ if(classNameA.equals("site-pair-set") || classNameB.equals("site-pair-set")) {
+ continue;
+ }
+ }
+
+ // Prepare full class path
+
+ Loader loader = LoaderFactory.createLoaderForVersion(ModelType.MOXY, apiVersion, llBuilder);
+
+ // Create the objects
+
+ // Generate the relationship test
+ try {
+ relationshipWriter.generateRelationshipTest(loader.introspectorFromName(classNameA), loader.introspectorFromName(classNameB), lep, edgeMapProperties, minListSize, maxListSize);
+ } catch (Exception e) {
+ System.out.println("Failed to generate relationship test for " + classNameA + "-" + classNameB + ".");
+ e.printStackTrace();
+ }
+
+ }
+ }
+
+ /**
+ * Creates the required directories.
+ *
+ * @param root the root
+ */
+ // Creates all the required directories in the system in case they don't already exist.
+ private void createRequiredDirectories(String root) {
+ File dir = new File(root + "/Endpoints");
+ dir.mkdir();
+ dir = new File(root + "/Relationships");
+ dir.mkdir();
+ dir = new File(root + "/Endpoints/" + apiVersion);
+ dir.mkdir();
+ dir = new File(root + "/Relationships/" + apiVersion);
+ dir.mkdir();
+ // TODO Generate suite content files for the root folders
+ }
+
+ /**
+ * Class exists.
+ *
+ * @param className the class name
+ * @return true, if successful
+ */
+ private boolean classExists(String className) {
+ try {
+ Class.forName(className);
+ return true;
+ } catch (ClassNotFoundException e) {
+ return false;
+ }
+ }
+
+ public static class TestSuiteBuilder {
+
+ private String pojoPackage = "";
+ private String restPackage = "";
+ private String dbmodelPackage = "";
+ private int minListSize = 1;
+ private int maxListSize = 2;
+ private String topLevelPath = "";
+ private List<String> children = null;
+ private Version apiVersion = null;
+ private Version currentApiVersion = AAIProperties.LATEST;
+
+ private Multimap<String, String> DeleteScope;
+ private Multimap<String, String> EdgeMap;
+
+
+ /**
+ * Instantiates a new test suite builder.
+ */
+ public TestSuiteBuilder() {
+
+ }
+
+ /**
+ * Gets the top level path.
+ *
+ * @return the top level path
+ */
+ public String getTopLevelPath() {
+ return topLevelPath;
+ }
+
+ /**
+ * Sets the top level path.
+ *
+ * @param topLevelPath the top level path
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setTopLevelPath(String topLevelPath) {
+ this.topLevelPath = topLevelPath;
+ return this;
+ }
+
+ /**
+ * Gets the children.
+ *
+ * @return the children
+ */
+ public List<String> getChildren() {
+ return children;
+ }
+
+ /**
+ * Sets the children.
+ *
+ * @param children the children
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setChildren(List<String> children) {
+ this.children = children;
+ return this;
+ }
+
+ /**
+ * Gets the pojo package.
+ *
+ * @return the pojo package
+ */
+ public String getPojoPackage() {
+ return pojoPackage;
+ }
+
+ /**
+ * Gets the db model package.
+ *
+ * @return the db model package
+ */
+ public String getDbModelPackage() {
+ return dbmodelPackage;
+ }
+
+ /**
+ * Sets the pojo package.
+ *
+ * @param pojoPackage the pojo package
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setPojoPackage(String pojoPackage) {
+ this.pojoPackage = pojoPackage;
+ return this;
+ }
+
+ /**
+ * Gets the min list size.
+ *
+ * @return the min list size
+ */
+ public int getMinListSize() {
+ return minListSize;
+ }
+
+ /**
+ * Sets the min list size.
+ *
+ * @param minListSize the min list size
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setMinListSize(int minListSize) {
+ this.minListSize = minListSize;
+ return this;
+ }
+
+ /**
+ * Gets the max list size.
+ *
+ * @return the max list size
+ */
+ public int getMaxListSize() {
+ return maxListSize;
+ }
+
+ /**
+ * Sets the max list size.
+ *
+ * @param maxListSize the max list size
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setMaxListSize(int maxListSize) {
+ this.maxListSize = maxListSize;
+ return this;
+ }
+
+ /**
+ * Gets the rest package.
+ *
+ * @return the rest package
+ */
+ public String getRestPackage() {
+ return restPackage;
+ }
+
+ /**
+ * Sets the rest package.
+ *
+ * @param restPackage the rest package
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setRestPackage(String restPackage) {
+ this.restPackage = restPackage;
+ return this;
+ }
+
+ /**
+ * Gets the api version.
+ *
+ * @return the api version
+ */
+ public Version getApiVersion() {
+ return apiVersion;
+ }
+
+ /**
+ * Sets the api version.
+ *
+ * @param apiVersion the api version
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setApiVersion(Version apiVersion) {
+ this.apiVersion = apiVersion;
+ return this;
+ }
+
+ /**
+ * Sets the db model package.
+ *
+ * @param dbmodelPackage the dbmodel package
+ * @return the test suite builder
+ */
+ public TestSuiteBuilder setDbModelPackage(String dbmodelPackage) {
+ this.dbmodelPackage = dbmodelPackage;
+ return this;
+ }
+
+ /**
+ * Gets the current api version.
+ *
+ * @return the current api version
+ */
+ public Version getCurrentApiVersion() {
+ return currentApiVersion;
+ }
+
+ /**
+ * Sets the current api version.
+ *
+ * @param currentApiVersion the new current api version
+ */
+ public void setCurrentApiVersion(Version currentApiVersion) {
+ this.currentApiVersion = currentApiVersion;
+ }
+
+
+ /**
+ * Gets the delete scope.
+ *
+ * @return the delete scope
+ */
+ public Multimap<String, String> getDeleteScope() {
+ return DeleteScope;
+ }
+
+ /**
+ * Gets the edge map.
+ *
+ * @return the edge map
+ */
+ public Multimap<String, String> getEdgeMap() {
+ return EdgeMap;
+ }
+
+
+ /**
+ * Builds the.
+ *
+ * @return the test suite
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws IllegalAccessException the illegal access exception
+ * @throws NoSuchFieldException the no such field exception
+ * @throws SecurityException the security exception
+ * @throws ClassNotFoundException the class not found exception
+ */
+ @SuppressWarnings("unchecked")
+ public TestSuite build() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, ClassNotFoundException {
+ Class<?> dbEdgeRules = Class.forName(dbmodelPackage + ".DbEdgeRules");
+
+ DeleteScope = (Multimap<String, String>)dbEdgeRules.getDeclaredField("DefaultDeleteScope").get(null);
+ EdgeMap = (Multimap<String, String>)dbEdgeRules.getDeclaredField("EdgeRules").get(null);
+
+ return new TestSuite(this);
+
+ }
+
+ }
+
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuiteWriter.java b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuiteWriter.java
new file mode 100644
index 0000000..9b35aa0
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/TestSuiteWriter.java
@@ -0,0 +1,375 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.aai.testsuitegeneration;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.ws.rs.core.Response.Status;
+import javax.xml.bind.JAXBException;
+
+import org.json.JSONException;
+import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Introspector;
+import org.openecomp.aai.rest.ueb.NotificationEvent;
+import org.openecomp.aai.rest.ueb.UEBNotification;
+import org.openecomp.aai.serialization.db.EdgeRule;
+import org.openecomp.aai.serialization.db.MultiplicityRule;
+import org.openecomp.aai.testing.InjectResourceVersion;
+import org.openecomp.aai.testing.LocateEndPoints;
+import org.openecomp.aai.testing.UpdateObject;
+import org.openecomp.aai.testsuitegeneration.TestSuite.TestSuiteBuilder;
+import org.springframework.web.util.UriUtils;
+
+import com.google.common.base.CaseFormat;
+import com.google.common.base.Joiner;
+
+import edu.emory.mathcs.backport.java.util.Arrays;
+
+public class TestSuiteWriter extends AbstractWriter {
+
+ protected final String END_POINT_SUITE_CONTENT = "end_point_suite_content_txt.ftl";
+ protected final String CHILD_TEST_CONTENT = "child_test_content_txt.ftl";
+
+ protected final String[] TOP_ENTITY_EXCEPTIONS = new String[] { "tenant", "volume-group", "dvs-switch", "image", "flavor", "oam-network", "availability-zone"};
+ protected final Set<String> EXCEPTION_SET = new HashSet<String>(Arrays.asList(TOP_ENTITY_EXCEPTIONS));
+
+ /**
+ * Instantiates a new test suite writer.
+ *
+ * @param file the file
+ * @param builder the builder
+ */
+ public TestSuiteWriter(File file, TestSuiteBuilder builder) {
+
+ // Just call the super constructor
+ super(file, builder);
+
+ }
+
+ /**
+ * Creates a suite for the parent object creation/teardown.
+ *
+ * @param path the path
+ * @param parentObject the parent object
+ * @param lep the lep
+ * @param genericPath the generic path
+ * @return the string
+ * @throws IOException Signals that an I/O exception has occurred.
+ * @throws IllegalAccessException the illegal access exception
+ * @throws IllegalArgumentException the illegal argument exception
+ * @throws InvocationTargetException the invocation target exception
+ * @throws NoSuchMethodException the no such method exception
+ * @throws SecurityException the security exception
+ */
+ protected String createParentSuite(String path, Introspector parentObject, LocateEndPoints lep, String genericPath) throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
+ if(genericPath == null) genericPath = path;
+
+ // Extract the object name to create the suite path
+ String name = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, parentObject.getDbName());
+ String suitePath = outputPath + "/" + name + "Suite";
+
+ // Create the suite directory
+ File suiteDir = new File(suitePath);
+ suiteDir.mkdir();
+
+ // Randomly generate field values to update the parent object
+ InjectResourceVersion inject = new InjectResourceVersion();
+ Introspector injectedObject = inject.addResourceVersionDeep(parentObject);
+ Introspector updatedParentObject = (new UpdateObject()).randomlyUpdateFieldValues(injectedObject);
+
+ String populatedPath = (String)lep.populatePath(parentObject, path).get(0);
+ //check the child map
+ String lowerHyphenName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, name);
+ Pattern p = Pattern.compile("^[\\w\\-]+?,,");
+ Matcher m = null;
+ boolean hasChildren = this.hasChildren(parentObject);
+
+ // Create the variable mapping for the suite
+ Map<String, Object> suiteMap = new HashMap<>();
+
+ if (hasChildren && DeleteScope.get(lowerHyphenName).contains("THIS_NODE_ONLY")) {
+
+ try {
+ tearDownPath = generateRecursiveCleanUp(populatedPath, suitePath, updatedParentObject, lep, "", "${topLevelFeatureURL}");
+ //tearDownPathChildren = generateRecursiveCleanUp(path, additionalPath, parentObject, lep, "OfParent");
+
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ e.printStackTrace();
+ }
+ parentCleanUpPage = this.tearDownPath;
+
+ } else {
+ parentCleanUpPage = ".AAI.Tests.GenericTests.SimpleParentCleanUp";
+ }
+ String encodedPath = this.encodeUsernamePlaceholders(populatedPath);
+ encodedPath = encodedPath.replaceFirst("/aai/v\\d+/", "");
+ UEBNotification notification = new UEBNotification(loader);
+ Introspector uebObj = null;
+ Introspector uebUpdatedObj = null;
+ String uebLink = "";
+ try {
+ notification.createNotificationEvent("test-generation", Status.CREATED, new URI(encodedPath), parentObject, new HashMap<String, Introspector>());
+ notification.createNotificationEvent("test-generation", Status.OK, new URI(encodedPath), updatedParentObject, new HashMap<String, Introspector>());
+ List<NotificationEvent> events = notification.getEvents();
+ uebObj = events.get(0).getObj();
+ uebUpdatedObj = events.get(1).getObj();
+ AddNamedPropWildcard addWildCard = new AddNamedPropWildcard(loader);
+ addWildCard.process(uebObj);
+ addWildCard.process(uebUpdatedObj);
+ uebLink = "-!${address}!-"+new URI((String)events.get(0).getEventHeader().getValue("entity-link")).getPath();
+ uebLink = this.decodeUserNamePlaceholders(uebLink);
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (AAIException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ String entity = this.getHyphenatedClassName(name);
+ String topEntity = this.computeTopEntity(entity);
+ suiteMap.put("topLevelBody", replaceUsernamePlaceholders(parentObject.marshal(true)));
+ suiteMap.put("topLevelUpdatedBody", replaceUsernamePlaceholders(updatedParentObject.marshal(true)));
+ suiteMap.put("topUebBody", replaceUsernamePlaceholders(uebObj.marshal(true)));
+ suiteMap.put("topUebUpdatedBody", replaceUsernamePlaceholders(uebUpdatedObj.marshal(true)));
+ suiteMap.put("topUebLink", replaceUsernamePlaceholders(uebLink));
+ suiteMap.put("topLevelFeatureURL", replaceUsernamePlaceholders(populatedPath));
+ suiteMap.put("type", "suite");
+ suiteMap.put("entity", entity);
+ suiteMap.put("topEntity", topEntity);
+ suiteMap.put("topLevelCleanUpPage", parentCleanUpPage);
+
+ Map<String, String> symLinks = new HashMap<>();
+ symLinks.put("SuiteSetUp", ".AAI.Tests.GenericTests.SuiteSetUpTemplate");
+ symLinks.put("SuiteTearDown", ".AAI.Tests.GenericTests.SuiteTearDownTemplate");
+ suiteMap.put("symLinks", symLinks);
+ // Process the freemarker files
+ processDataModel(END_POINT_SUITE_CONTENT, "content.txt", suiteDir, suiteMap);
+ processDataModel(PROPERTIES_XML, "properties.xml", suiteDir, suiteMap);
+
+ // Create a placeholder page for the parent test
+ String parentTest = suitePath + "/" + name + "Test";
+ suiteDir = new File(parentTest);
+ suiteDir.mkdir();
+ suiteMap = new HashMap<>();
+ suiteMap.put("type", "test");
+ processDataModel("empty_context_txt.ftl", "content.txt", suiteDir, suiteMap);
+ processDataModel(PROPERTIES_XML, "properties.xml", suiteDir, suiteMap);
+
+ return suitePath;
+ }
+
+ /**
+ * Format test name.
+ *
+ * @param genericPath the generic path
+ * @return the string
+ */
+ protected String formatTestName(String genericPath) {
+ String dropSuiteName = genericPath.substring(genericPath.indexOf("}")+1);
+ String removeVariables = dropSuiteName.replaceAll("\\/\\{.*?\\}", "");
+ String[] split = removeVariables.split("/");
+ List<String> result = new ArrayList<>();
+ for (int i = 0; i < split.length; i++) {
+
+ if (!this.isPlural(split[i])) {
+ result.add(CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, split[i]));
+ }
+ }
+ String addHyphens = Joiner.on("-").join(result).replaceFirst("-", "");
+
+ return addHyphens;
+ }
+
+ /**
+ * Adds the test case.
+ *
+ * @param suitePath the suite path
+ * @param path the path
+ * @param obj the obj
+ * @param genericPath the generic path
+ * @param lep the lep
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ public void addTestCase(String suitePath, String path, Introspector obj, String genericPath, LocateEndPoints lep) throws IOException {
+ if (genericPath == null){
+ genericPath = suitePath;
+ }
+ supplimentalMap.put("tearDownPath", this.tearDownPathChildren);
+
+ this.addTestCase(suitePath, path, obj, supplimentalMap, CHILD_TEST_CONTENT, genericPath, lep);
+ }
+
+ /**
+ * Adds the test case.
+ *
+ * @param parentPath the parent path
+ * @param path the path
+ * @param obj the obj
+ * @param supplimentalMap the supplimental map
+ * @param templateName the template name
+ * @param genericPath the generic path
+ * @param lep the lep
+ * @throws IOException Signals that an I/O exception has occurred.
+ */
+ protected void addTestCase(String parentPath, String path, Introspector obj, Map<String, Object> supplimentalMap,
+ String templateName, String genericPath, LocateEndPoints lep) throws IOException {
+
+ if (genericPath == null){
+ genericPath = parentPath;
+ }
+
+ InjectResourceVersion inject = new InjectResourceVersion();
+ Introspector injectedResource = inject.addResourceVersionDeep(obj);
+ Introspector updatedObj = (new UpdateObject()).randomlyUpdateFieldValues(injectedResource);
+
+ String name = CaseFormat.LOWER_HYPHEN.to(CaseFormat.UPPER_CAMEL, obj.getDbName());
+ String entityName = this.getHyphenatedClassName(name);
+ String nameWithDepth = this.formatTestName(genericPath);
+
+ if (!nameWithDepth.equals("")) {
+ name = nameWithDepth;
+ }
+ String testPath = parentPath + "/" + name + "Test";
+
+ File dir = new File(testPath);
+
+ dir.mkdir();
+
+ Map<String, Object> testMap = new HashMap<>();
+
+ boolean hasChildren = this.hasChildren(obj);
+
+ if (hasChildren && DeleteScope.get(obj.getDbName()).contains("THIS_NODE_ONLY")) {
+
+ try {
+ tearDownPath = generateRecursiveCleanUp(path, parentPath, updatedObj, lep, "", "${featureURL}");
+ //tearDownPathChildren = generateRecursiveCleanUp(path, additionalPath, parentObject, lep, "OfParent");
+
+ } catch (IllegalAccessException | IllegalArgumentException
+ | InvocationTargetException | NoSuchMethodException
+ | SecurityException e) {
+ e.printStackTrace();
+ }
+ this.deletePage = this.tearDownPath;
+ } else {
+ this.deletePage = ".AAI.Tests.GenericTests.DeleteTop";
+ }
+ String testPagePath = ".AAI.Tests.GenericTests.GenericTest";
+ try {
+ Introspector parent = null;
+ if (!genericPath.equals(obj.getFullGenericURI())) {
+ String parentObjectPath = genericPath.replace(obj.getFullGenericURI(), "");
+ parent = lep.createChildForPath(parentObjectPath, 1, 1);
+ EdgeRule rule = org.openecomp.aai.serialization.db.EdgeRules.getInstance().getEdgeRule(parent.getDbName(), obj.getDbName());
+
+ if (rule.getMultiplicityRule().equals(MultiplicityRule.ONE2ONE)) {
+ testPagePath = ".AAI.Tests.GenericTests.PlaceholderTest";
+ }
+ }
+ } catch (IllegalArgumentException | AAIException | IllegalAccessException | InvocationTargetException | InstantiationException | JSONException | JAXBException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+ String featureUrl = replaceUsernamePlaceholders(path);
+ String encodedPath = this.encodeUsernamePlaceholders(path);
+ encodedPath = encodedPath.replaceFirst("/aai/v\\d+/", "");
+
+ UEBNotification notification = new UEBNotification(loader);
+ Introspector uebObj = null;
+ Introspector uebUpdatedObj = null;
+ String uebLink = "";
+ try {
+ notification.createNotificationEvent("test-generation", Status.CREATED, new URI(encodedPath), obj, new HashMap<String, Introspector>());
+ notification.createNotificationEvent("test-generation", Status.OK, new URI(encodedPath), updatedObj, new HashMap<String, Introspector>());
+ List<NotificationEvent> events = notification.getEvents();
+ uebObj = events.get(0).getObj();
+ uebUpdatedObj = events.get(1).getObj();
+ AddNamedPropWildcard addWildCard = new AddNamedPropWildcard(loader);
+ addWildCard.process(uebObj);
+ addWildCard.process(uebUpdatedObj);
+ uebLink = "-!${address}!-"+new URI((String)events.get(0).getEventHeader().getValue("entity-link")).getPath();
+ uebLink = this.decodeUserNamePlaceholders(uebLink);
+ } catch (IllegalArgumentException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (AAIException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ } catch (URISyntaxException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+
+
+
+ testMap.put("body", replaceUsernamePlaceholders(obj.marshal(true)));
+ testMap.put("updatedBody", replaceUsernamePlaceholders(updatedObj.marshal(true)));
+ testMap.put("uebBody", replaceUsernamePlaceholders(uebObj.marshal(true)));
+ testMap.put("uebUpdatedBody", replaceUsernamePlaceholders(uebUpdatedObj.marshal(true)));
+ testMap.put("uebLink", replaceUsernamePlaceholders(uebLink));
+ testMap.put("featureURL", featureUrl);
+ testMap.put("type", "test");
+ testMap.put("testPath", testPagePath);
+ testMap.put("deletePage", this.deletePage);
+ testMap.put("putPage", ".AAI.Tests.GenericTests.StandardPut");
+ testMap.put("entity", entityName);
+ testMap.putAll(supplimentalMap);
+
+ this.processDataModel(templateName, "content.txt", dir, testMap);
+ this.processDataModel(PROPERTIES_XML, "properties.xml", dir, testMap);
+ }
+
+ /**
+ * Compute top entity.
+ *
+ * @param entity the entity
+ * @return the string
+ */
+ private String computeTopEntity(String entity) {
+ String result = entity;
+ if (!this.apiVersion.equals("v7")) {
+ if (EXCEPTION_SET.contains(entity)) {
+ result = "cloud-region";
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/child_test_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/child_test_content_txt.ftl
new file mode 100644
index 0000000..e051471
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/child_test_content_txt.ftl
@@ -0,0 +1,33 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!contents -R2 -g -p -f -h
+!*> Test Variables
+!define entity {${entity}}
+!define body {!-${body}-!}
+!define updatedBody {!-${updatedBody}-!}
+!define uebBody {!-${uebBody}-!}
+!define uebUpdatedBody {!-${uebUpdatedBody}-!}
+!define uebLink {!-${uebLink}-!}
+!define featureURL {!-${featureURL}-!}
+!define putPage {!include -c ${putPage}}
+!define deletePage {!include ${deletePage}}
+*!
+!include -setup ${testPath}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/empty_context_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/empty_context_txt.ftl
new file mode 100644
index 0000000..2118995
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/empty_context_txt.ftl
@@ -0,0 +1,21 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!include .AAI.Tests.GenericTests.PlaceholderTest
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/end_point_suite_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/end_point_suite_content_txt.ftl
new file mode 100644
index 0000000..271c6d6
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/end_point_suite_content_txt.ftl
@@ -0,0 +1,32 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!contents -R2 -g -p -f -h
+!*> Suite Variables
+!define entity {${entity}}
+!define topEntity {${topEntity}}
+!define topLevelBody {!-${topLevelBody}-!}
+!define topLevelUpdatedBody {!-${topLevelUpdatedBody}-!}
+!define topUebBody {!-${topUebBody}-!}
+!define topUebUpdatedBody {!-${topUebUpdatedBody}-!}
+!define topUebLink {!-${topUebLink}-!}
+!define topLevelFeatureURL {!-${topLevelFeatureURL}-!}
+!define topLevelCleanUpPage {!include ${topLevelCleanUpPage}}
+*!
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/junit_class_java.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/junit_class_java.ftl
new file mode 100644
index 0000000..7a882fb
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/junit_class_java.ftl
@@ -0,0 +1,33 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+package ${packageName};
+
+import org.junit.runner.RunWith;
+
+import fitnesse.junit.FitNesseRunner;
+
+@RunWith(FitNesseRunner.class)
+@FitNesseRunner.Suite("${suiteName}")
+@FitNesseRunner.FitnesseDir(".")
+@FitNesseRunner.OutputDir("./target/fitnesse-results")
+public class ${className} {
+
+}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/properties_xml.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/properties_xml.ftl
new file mode 100644
index 0000000..36e2059
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/properties_xml.ftl
@@ -0,0 +1,48 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<properties>
+<Edit/>
+<Files/>
+<Properties/>
+<#if skip??>
+ <Prune/><#lt>
+</#if>
+<RecentChanges/>
+<Refactor/>
+<Search/>
+<#if type == "test">
+ <Test/><#lt>
+<#elseif type == "suite">
+ <Suite/><#lt>
+<#elseif type == "static">
+ <Static/><#lt>
+</#if>
+<#if symLinks??>
+ <SymbolicLinks><#lt>
+ <#list symLinks?keys as link><#lt>
+ <${link}>${symLinks[link]}</${link}><#lt>
+ </#list><#lt>
+ </SymbolicLinks><#lt>
+</#if>
+<Versions/>
+<WhereUsed/>
+</properties>
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/recursive_teardown_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/recursive_teardown_content_txt.ftl
new file mode 100644
index 0000000..5573795
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/recursive_teardown_content_txt.ftl
@@ -0,0 +1,29 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!include .AAI.Tests.GenericTests.RestFixtureSetup
+
+!define deleteURL {${urlVariableName}}
+!include ${errorCheckPage}
+<#list pages as page>
+ !include ${page}<#lt>
+</#list>
+!define deleteURL {${urlVariableName}}
+!include ${parentCleanUpPage}
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_content_txt.ftl
new file mode 100644
index 0000000..69b731e
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_content_txt.ftl
@@ -0,0 +1,37 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!*> User-defined Variables
+!define topFeatureURL_A {!-${topFeatureUrlA}-!}
+!define topFeatureURL_B {!-${topFeatureUrlB}-!}
+!define featureURL_A {!-${featureUrlA}-!}
+!define featureURL_B {!-${featureUrlB}-!}
+!define relationshipURLA {!-${relationshipURLA}-!}
+!define relationshipURLB {!-${relationshipURLB}-!}
+!define body_A {!-${objectBodyA}-!}
+!define body_B {!-${objectBodyB}-!}
+!define body_RA {!-${objectRelationshipA}-!}
+!define body_RB {!-${objectRelationshipB}-!}
+!define deletePageA {!include ${deletePageA}}
+!define deletePageB {!include ${deletePageB}}
+!define expectedResultA {!-${expectedResultA}-!}
+!define expectedResultB {!-${expectedResultB}-!}
+*!
+!include -setup .AAI.Tests.GenericTests.GenericRelationshipTest
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_content_txt.ftl
new file mode 100644
index 0000000..55d4177
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_content_txt.ftl
@@ -0,0 +1,36 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!*> User-defined Variables
+!define topFeatureURL_A {!-${topFeatureUrlA}-!}
+!define topFeatureURL_B {!-${topFeatureUrlB}-!}
+!define featureURL_A {!-${featureUrlA}-!}
+!define featureURL_B {!-${featureUrlB}-!}
+!define relationshipURLA {!-${relationshipURLA}-!}
+!define relationshipURLB {!-${relationshipURLB}-!}
+!define body_A {!-${objectBodyA}-!}
+!define body_B {!-${objectBodyB}-!}
+!define body_RA {!-${objectRelationshipA}-!}
+!define body_RB {!-${objectRelationshipB}-!}
+!define deletePageA {!include ${deletePageA}}
+!define deletePageB {!include ${deletePageB}}
+!define expectedResultA {!-${expectedResultA}-!}
+*!
+!include -setup .AAI.Tests.GenericTests.GenericSingleRelationshipTest
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_reversed_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_reversed_content_txt.ftl
new file mode 100644
index 0000000..b9f4a0d
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/relationship_single_reversed_content_txt.ftl
@@ -0,0 +1,36 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!*> User-defined Variables
+!define topFeatureURL_A {!-${topFeatureUrlA}-!}
+!define topFeatureURL_B {!-${topFeatureUrlB}-!}
+!define featureURL_A {!-${featureUrlA}-!}
+!define featureURL_B {!-${featureUrlB}-!}
+!define relationshipURLA {!-${relationshipURLA}-!}
+!define relationshipURLB {!-${relationshipURLB}-!}
+!define body_A {!-${objectBodyA}-!}
+!define body_B {!-${objectBodyB}-!}
+!define body_RA {!-${objectRelationshipA}-!}
+!define body_RB {!-${objectRelationshipB}-!}
+!define deletePageA {!include ${deletePageA}}
+!define deletePageB {!include ${deletePageB}}
+!define expectedResultB {!-${expectedResultB}-!}
+*!
+!include -setup .AAI.Tests.GenericTests.GenericSingleRelationshipReversedTest
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/remove_children_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/remove_children_content_txt.ftl
new file mode 100644
index 0000000..660bdf4
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/remove_children_content_txt.ftl
@@ -0,0 +1,25 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+<#list urls as url>
+ !define deleteURL {!-${url}-!}<#lt>
+ !include ${deleteChildren}<#lt>
+
+</#list>
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/static_page_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/static_page_content_txt.ftl
new file mode 100644
index 0000000..a6736d3
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/static_page_content_txt.ftl
@@ -0,0 +1,21 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!contents -R2 -g -p -f -h
diff --git a/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/version_suite_content_txt.ftl b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/version_suite_content_txt.ftl
new file mode 100644
index 0000000..ebfa08d
--- /dev/null
+++ b/ajsc-aai/src/main/java/org/openecomp/aai/testsuitegeneration/version_suite_content_txt.ftl
@@ -0,0 +1,31 @@
+<#--
+ ============LICENSE_START=======================================================
+ org.openecomp.aai
+ ================================================================================
+ Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ ================================================================================
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ ============LICENSE_END=========================================================
+-->
+
+!1 Test suite ${version}
+!contents -R2 -g -p -f -h!contents -R2 -g -p -f -h
+!*> Suite Variables
+!define slim.port {${slimPort?c}}
+!define defns {http://org.openecomp.aai.inventory/${version}}
+!define createStatus {${createStatus}}
+!define version {${version}}
+!define currentApiVersion {${currentVersion}}
+#disable ueb tests
+!define uebTest {}
+*!