CLAMP Model policy creation support
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / components / CreateNewMicroServiceModel.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pap.xacml.rest.components;
23
24 import com.google.gson.Gson;
25 import java.io.BufferedInputStream;
26 import java.io.BufferedOutputStream;
27 import java.io.File;
28 import java.io.FileOutputStream;
29 import java.io.IOException;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Enumeration;
33 import java.util.HashMap;
34 import java.util.LinkedHashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.zip.ZipEntry;
38 import java.util.zip.ZipFile;
39 import org.apache.commons.io.FileUtils;
40 import org.apache.commons.lang.StringUtils;
41 import org.onap.policy.common.logging.eelf.MessageCodes;
42 import org.onap.policy.common.logging.eelf.PolicyLogger;
43 import org.onap.policy.common.logging.flexlogger.FlexLogger;
44 import org.onap.policy.common.logging.flexlogger.Logger;
45 import org.onap.policy.pap.xacml.rest.XACMLPapServlet;
46 import org.onap.policy.pap.xacml.rest.daoimpl.CommonClassDaoImpl;
47 import org.onap.policy.rest.jpa.MicroServiceModels;
48 import org.onap.policy.rest.jpa.UserInfo;
49 import org.onap.policy.rest.util.MSAttributeObject;
50 import org.onap.policy.rest.util.MSModelUtils;
51 import org.onap.policy.rest.util.MSModelUtils.MODEL_TYPE;
52
53 public class CreateNewMicroServiceModel {
54     private static final Logger logger = FlexLogger.getLogger(CreateNewMicroServiceModel.class);
55     private MicroServiceModels newModel = null;
56     private HashMap<String, MSAttributeObject> classMap = new HashMap<>();
57
58
59     private MSModelUtils utils = new MSModelUtils(XACMLPapServlet.getMsOnapName(), XACMLPapServlet.getMsPolicyName());
60
61     public CreateNewMicroServiceModel(String fileName, String serviceName, String string, String version) {
62         super();
63     }
64
65     /**
66      * Instantiates a new creates the new micro service model.
67      *
68      * @param importFile the import file
69      * @param modelName the model name
70      * @param description the description
71      * @param version the version
72      * @param randomID the random ID
73      */
74     public CreateNewMicroServiceModel(String importFile, String modelName, String description, String version,
75             String randomID) {
76
77         this.newModel = new MicroServiceModels();
78         this.newModel.setVersion(version);
79         this.newModel.setModelName(modelName);
80         UserInfo userInfo = new UserInfo();
81         userInfo.setUserLoginId("API");
82         this.newModel.setUserCreatedBy(userInfo);
83         String cleanUpFile = null;
84
85         Map<String, MSAttributeObject> tempMap = new HashMap<>();
86         // Need to delete the file
87         if (importFile.contains(".zip")) {
88             extractFolder(randomID + ".zip");
89             File directory = new File("ExtractDir" + File.separator + randomID);
90             List<File> fileList = listModelFiles(directory.toString());
91             // get all the files from a director
92             processFiles(modelName, fileList);
93             doCleanUpFiles(randomID);
94         } else {
95             if (importFile.contains(".yml")) {
96
97                 processYmlModel("ExtractDir" + File.separator + randomID + ".yml", modelName);
98                 cleanUpFile = "ExtractDir" + File.separator + randomID + ".yml";
99
100             } else {
101                 tempMap = utils.processEpackage("ExtractDir" + File.separator + randomID + ".xmi", MODEL_TYPE.XMI);
102                 classMap.putAll(tempMap);
103                 cleanUpFile = "ExtractDir" + File.separator + randomID + ".xmi";
104             }
105
106             File deleteFile = new File(cleanUpFile);
107             deleteFile.delete();
108         }
109     }
110
111     private void processFiles(String modelName, List<File> fileList) {
112         Map<String, MSAttributeObject> tempMap;
113         for (File file : fileList) {
114             if (file.isFile()) {
115                 int indx = file.getName().lastIndexOf('.');
116                 String type = file.getName().substring(indx + 1);
117
118                 if ("yml".equalsIgnoreCase(type)) {
119
120                     processYmlModel(file.toString(), modelName);
121
122                 } else {
123
124                     tempMap = utils.processEpackage(file.getAbsolutePath(), MODEL_TYPE.XMI);
125                     classMap.putAll(tempMap);
126                 }
127             }
128         }
129     }
130
131     private void doCleanUpFiles(String randomID) {
132         String cleanUpFile;
133         cleanUpFile = "ExtractDir" + File.separator + randomID + ".zip";
134         try {
135             FileUtils.deleteDirectory(new File("ExtractDir" + File.separator + randomID));
136             FileUtils.deleteDirectory(new File(randomID));
137             File deleteFile = new File(cleanUpFile);
138             FileUtils.forceDelete(deleteFile);
139         } catch (IOException e) {
140             logger.error("Failed to unzip model file " + randomID, e);
141         }
142     }
143
144     private void processYmlModel(String fileName, String modelName) {
145
146         try {
147
148
149             utils.parseTosca(fileName);
150
151             MSAttributeObject msAttributes = new MSAttributeObject();
152             msAttributes.setClassName(modelName);
153
154             LinkedHashMap<String, String> returnAttributeList = new LinkedHashMap<>();
155             returnAttributeList.put(modelName, utils.getAttributeString());
156             msAttributes.setAttribute(returnAttributeList);
157
158             msAttributes.setSubClass(utils.getRetmap());
159
160             msAttributes.setMatchingSet(utils.getMatchableValues());
161
162             LinkedHashMap<String, String> returnReferenceList = new LinkedHashMap<>();
163
164             returnReferenceList.put(modelName, utils.getReferenceAttributes());
165             msAttributes.setRefAttribute(returnReferenceList);
166
167             if (!PolicyDBDao.isNullOrEmpty(utils.getListConstraints())) {
168                 LinkedHashMap<String, String> enumList = new LinkedHashMap<>();
169                 String[] listArray = utils.getListConstraints().split("#");
170                 for (String str : listArray) {
171                     String[] strArr = str.split("=");
172                     if (strArr.length > 1) {
173                         enumList.put(strArr[0], strArr[1]);
174                     }
175                 }
176                 msAttributes.setEnumType(enumList);
177             }
178             if (utils.getJsonRuleFormation() != null) {
179                 msAttributes.setRuleFormation(utils.getJsonRuleFormation());
180             }
181
182             if (utils.getDataOrderInfo() != null) {
183                 msAttributes.setDataOrderInfo(utils.getDataOrderInfo());
184             }
185
186             classMap = new LinkedHashMap<>();
187             classMap.put(modelName, msAttributes);
188
189         } catch (Exception e) {
190             logger.error("Failed to process yml model" + e);
191         }
192
193     }
194
195     private List<File> listModelFiles(String directoryName) {
196         File directory = new File(directoryName);
197         List<File> resultList = new ArrayList<>();
198         File[] fList = directory.listFiles();
199         for (File file : fList) {
200             if (file.isFile()) {
201                 resultList.add(file);
202             } else if (file.isDirectory()) {
203                 resultList.addAll(listModelFiles(file.getAbsolutePath()));
204             }
205         }
206         return resultList;
207     }
208
209     @SuppressWarnings("rawtypes")
210     private void extractFolder(String zipFile) {
211         int BUFFER = 2048;
212         File file = new File(zipFile);
213
214         try (ZipFile zip = new ZipFile("ExtractDir" + File.separator + file)) {
215
216             String newPath = zipFile.substring(0, zipFile.length() - 4);
217             new File(newPath).mkdir();
218             Enumeration zipFileEntries = zip.entries();
219
220             // Process each entry
221             while (zipFileEntries.hasMoreElements()) {
222                 // grab a zip file entry
223                 ZipEntry entry = (ZipEntry) zipFileEntries.nextElement();
224                 String currentEntry = entry.getName();
225                 File destFile = new File("ExtractDir" + File.separator + newPath + File.separator + currentEntry);
226                 File destinationParent = destFile.getParentFile();
227
228                 destinationParent.mkdirs();
229
230                 if (!entry.isDirectory()) {
231                     BufferedInputStream is = new BufferedInputStream(zip.getInputStream(entry));
232                     int currentByte;
233
234                     byte data[] = new byte[BUFFER];
235                     try (FileOutputStream fos = new FileOutputStream(destFile);
236                             BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER)) {
237
238                         while ((currentByte = is.read(data, 0, BUFFER)) != -1) {
239                             dest.write(data, 0, currentByte);
240                         }
241                         dest.flush();
242                     }
243                     is.close();
244                 }
245
246                 if (currentEntry.endsWith(".zip")) {
247                     extractFolder(destFile.getAbsolutePath());
248                 }
249             }
250         } catch (IOException e) {
251             logger.error("Failed to unzip model file " + zipFile + e);
252         }
253     }
254
255     public Map<String, String> addValuesToNewModel(String type) {
256
257         Map<String, String> successMap = new HashMap<>();
258         MSAttributeObject mainClass = null;
259         List<String> dependency = null;
260         String subAttribute = null;
261
262         if (!classMap.containsKey(this.newModel.getModelName())) {
263             logger.error(
264                     "Model Provided does not contain the service name provided in request. Unable to import new model");
265             PolicyLogger.error(MessageCodes.ERROR_DATA_ISSUE, "AddValuesToNewModel",
266                     "Unable to pull out required values, file missing service name provided in request");
267             successMap.put("error", "MISSING");
268             return successMap;
269         }
270         mainClass = classMap.get(this.newModel.getModelName());
271
272
273         if (".yml".equalsIgnoreCase(type)) {
274
275             newModel.setDependency("[]");
276             if (mainClass.getSubClass() != null) {
277                 String value = new Gson().toJson(mainClass.getSubClass());
278                 newModel.setSub_attributes(value);
279             }
280
281             if (mainClass.getAttribute() != null) {
282                 String attributes = mainClass.getAttribute().toString().replace("{", "").replace("}", "");
283                 int equalsIndexForAttributes = attributes.indexOf("=");
284                 String atttributesAfterFirstEquals = attributes.substring(equalsIndexForAttributes + 1);
285                 this.newModel.setAttributes(atttributesAfterFirstEquals);
286             }
287
288             if (mainClass.getRefAttribute() != null) {
289                 String refAttributes = mainClass.getRefAttribute().toString().replace("{", "").replace("}", "");
290                 int equalsIndex = refAttributes.indexOf("=");
291                 String refAttributesAfterFirstEquals = refAttributes.substring(equalsIndex + 1);
292                 this.newModel.setRef_attributes(refAttributesAfterFirstEquals);
293             }
294
295             if (mainClass.getEnumType() != null) {
296                 this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
297             }
298
299             if (mainClass.getMatchingSet() != null) {
300                 this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
301             }
302             if (mainClass.getRuleFormation() != null) {
303                 this.newModel.setRuleFormation(mainClass.getRuleFormation());
304             }
305
306             if (mainClass.getDataOrderInfo() != null) {
307                 this.newModel.setDataOrderInfo(mainClass.getDataOrderInfo());
308             }
309
310         } else {
311
312             String dependTemp = StringUtils.replaceEach(mainClass.getDependency(), new String[] {"[", "]", " "},
313                     new String[] {"", "", ""});
314             this.newModel.setDependency(dependTemp);
315             if (this.newModel.getDependency() != null && !this.newModel.getDependency().isEmpty()) {
316                 dependency = new ArrayList<String>(Arrays.asList(dependTemp.split(",")));
317                 dependency = utils.getFullDependencyList(dependency, classMap);
318                 if (!dependency.isEmpty()) {
319                     for (String element : dependency) {
320                         MSAttributeObject temp = new MSAttributeObject();
321                         if (classMap.containsKey(element)) {
322                             temp = classMap.get(element);
323                             mainClass.addAllRefAttribute(temp.getRefAttribute());
324                             mainClass.addAllAttribute(temp.getAttribute());
325                         }
326                     }
327                 }
328             }
329             subAttribute = utils.createSubAttributes(dependency, classMap, this.newModel.getModelName());
330
331             this.newModel.setSub_attributes(subAttribute);
332             if (mainClass.getAttribute() != null && !mainClass.getAttribute().isEmpty()) {
333                 this.newModel.setAttributes(mainClass.getAttribute().toString().replace("{", "").replace("}", ""));
334             }
335
336             if (mainClass.getRefAttribute() != null && !mainClass.getRefAttribute().isEmpty()) {
337                 this.newModel
338                         .setRef_attributes(mainClass.getRefAttribute().toString().replace("{", "").replace("}", ""));
339             }
340
341             if (mainClass.getEnumType() != null && !mainClass.getEnumType().isEmpty()) {
342                 this.newModel.setEnumValues(mainClass.getEnumType().toString().replace("{", "").replace("}", ""));
343             }
344
345             if (mainClass.getMatchingSet() != null && !mainClass.getMatchingSet().isEmpty()) {
346                 this.newModel.setAnnotation(mainClass.getMatchingSet().toString().replace("{", "").replace("}", ""));
347             }
348         }
349         successMap.put("success", "success");
350         return successMap;
351
352     }
353
354     public Map<String, String> saveImportService() {
355         String modelName = this.newModel.getModelName();
356         String imported_by = "API";
357         String version = this.newModel.getVersion();
358         Map<String, String> successMap = new HashMap<>();
359         CommonClassDaoImpl dbConnection = new CommonClassDaoImpl();
360         List<Object> result =
361                 dbConnection.getDataById(MicroServiceModels.class, "modelName:version", modelName + ":" + version);
362         if (result == null || result.isEmpty()) {
363             MicroServiceModels model = new MicroServiceModels();
364             model.setModelName(modelName);
365             model.setVersion(version);
366             model.setAttributes(this.newModel.getAttributes());
367             model.setAnnotation(this.newModel.getAnnotation());
368             model.setDependency(this.newModel.getDependency());
369             model.setDescription(this.newModel.getDescription());
370             model.setEnumValues(this.newModel.getEnumValues());
371             model.setRef_attributes(this.newModel.getRef_attributes());
372             model.setSub_attributes(this.newModel.getSub_attributes());
373             model.setDataOrderInfo(this.newModel.getDataOrderInfo());
374             model.setDecisionModel(this.newModel.isDecisionModel());
375             model.setRuleFormation(this.newModel.getRuleFormation());
376             UserInfo userInfo = new UserInfo();
377             userInfo.setUserLoginId(imported_by);
378             userInfo.setUserName(imported_by);
379             model.setUserCreatedBy(userInfo);
380             dbConnection.save(model);
381             successMap.put("success", "success");
382         } else {
383             successMap.put("DBError", "EXISTS");
384             logger.error("Import new service failed.  Service already exists");
385         }
386         return successMap;
387     }
388 }