Fix the a log in Model Properties
[clamp.git] / src / main / java / org / onap / clamp / clds / model / prop / ModelProperties.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP CLAMP
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights
6  *                             reserved.
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  * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22  */
23
24 package org.onap.clamp.clds.model.prop;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28 import com.fasterxml.jackson.core.JsonProcessingException;
29 import com.fasterxml.jackson.databind.JsonNode;
30 import com.fasterxml.jackson.databind.ObjectMapper;
31
32 import java.io.IOException;
33 import java.lang.reflect.InvocationTargetException;
34 import java.util.HashSet;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Set;
38 import java.util.concurrent.ConcurrentHashMap;
39
40 import org.camunda.bpm.engine.delegate.DelegateExecution;
41 import org.onap.clamp.clds.model.CldsEvent;
42 import org.onap.clamp.clds.model.CldsModel;
43 import org.onap.clamp.clds.service.CldsService;
44
45 /**
46  * Parse model properties.
47  */
48 public class ModelProperties {
49     protected static final EELFLogger                                 logger              = EELFManager.getInstance()
50             .getLogger(CldsService.class);
51     protected static final EELFLogger                                 auditLogger         = EELFManager.getInstance()
52             .getAuditLogger();
53
54     private ModelBpmn                                                 modelBpmn;
55     private JsonNode                                                  modelJson;
56
57     private final String                                              modelName;
58     private final String                                              controlName;
59     private final String                                              actionCd;
60     // Flag indicate whether it is triggered by Validation Test button from UI
61     private final boolean                                             isTest;
62
63     private Global                                                    global;
64
65     private final Map<String, AbstractModelElement>                   modelElements       = new ConcurrentHashMap<>();
66
67     private String                                                    currentModelElementId;
68     private String                                                    policyUniqueId;
69
70     private static final Object                                       lock                = new Object();
71     private static Map<Class<? extends AbstractModelElement>, String> modelElementClasses = new ConcurrentHashMap<>();
72
73     static {
74         synchronized (lock) {
75             modelElementClasses.put(Policy.class, Policy.getType());
76             modelElementClasses.put(Tca.class, Tca.getType());
77             modelElementClasses.put(Holmes.class, Holmes.getType());
78         }
79     }
80
81     /**
82      * Retain data required to parse the ModelElement objects. (Rather than
83      * parse them all - parse them on demand if requested.)
84      *
85      * @param modelName
86      *            The model name coming form the UI
87      * @param controlName
88      *            The closed loop name coming from the UI
89      * @param actionCd
90      *            Type of operation PUT,UPDATE,DELETE
91      * @param isTest
92      *            The test flag coming from the UI (for validation only, no
93      *            query are physically executed)
94      * @param modelBpmnText
95      *            The BPMN flow in JSON from the UI
96      * @param modelPropText
97      *            The BPMN parameters for all boxes defined in modelBpmnTest
98      * @throws IOException
99      *             In case there is an issue with the JSON decoding
100      */
101     public ModelProperties(String modelName, String controlName, String actionCd, boolean isTest, String modelBpmnText,
102             String modelPropText) throws IOException {
103         this.modelName = modelName;
104         this.controlName = controlName;
105         this.actionCd = actionCd;
106         this.isTest = isTest;
107         modelBpmn = ModelBpmn.create(modelBpmnText);
108         modelJson = new ObjectMapper().readTree(modelPropText);
109
110         instantiateMissingModelElements();
111     }
112
113     /**
114      * This method is meant to ensure that one ModelElement instance exists for
115      * each ModelElement class.
116      *
117      * As new ModelElement classes could have been registered after
118      * instantiation of this ModelProperties, we need to build the missing
119      * ModelElement instances.
120      */
121     private final void instantiateMissingModelElements() {
122         if (modelElementClasses.size() != modelElements.size()) {
123             Set<String> missingTypes = new HashSet<>(modelElementClasses.values());
124             missingTypes.removeAll(modelElements.keySet());
125             // Parse the list of base Model Elements and build up the
126             // ModelElements
127             modelElementClasses.entrySet().stream().parallel()
128                     .filter(entry -> (AbstractModelElement.class.isAssignableFrom(entry.getKey())
129                             && missingTypes.contains(entry.getValue())))
130                     .forEach(entry -> {
131                         try {
132                             modelElements.put(entry.getValue(),
133                                     (entry.getKey()
134                                             .getConstructor(ModelProperties.class, ModelBpmn.class, JsonNode.class)
135                                             .newInstance(this, modelBpmn, modelJson)));
136                         } catch (InstantiationException | NoSuchMethodException | IllegalAccessException
137                                 | InvocationTargetException e) {
138                             logger.warn("Unable to instantiate a ModelElement, exception follows: ", e);
139                         }
140                     });
141         }
142     }
143
144     /**
145      * Get the VF for a model. If return null if there is no VF.
146      *
147      * @param model
148      * @return
149      */
150     public static String getVf(CldsModel model) {
151         List<String> vfs = null;
152         try {
153             ObjectMapper mapper = new ObjectMapper();
154             JsonNode modelJson = mapper.readTree(model.getPropText());
155             Global global = new Global(modelJson);
156             vfs = global.getResourceVf();
157         } catch (IOException e) {
158             logger.warn("no VF found", e);
159         }
160         String vf = null;
161         if (vfs != null && !vfs.isEmpty()) {
162             vf = vfs.get(0);
163         }
164         return vf;
165     }
166
167     /**
168      * Create ModelProperties for Camunda Delegate.
169      *
170      * @param execution
171      * @return
172      * @throws JsonProcessingException
173      * @throws IOException
174      */
175     public static ModelProperties create(DelegateExecution execution) throws IOException {
176         String modelProp = new String((byte[]) execution.getVariable("modelProp"));
177         String modelBpmnProp = (String) execution.getVariable("modelBpmnProp");
178         String modelName = (String) execution.getVariable("modelName");
179         String controlName = (String) execution.getVariable("controlName");
180         String actionCd = (String) execution.getVariable("actionCd");
181         boolean isTest = (boolean) execution.getVariable("isTest");
182
183         return new ModelProperties(modelName, controlName, actionCd, isTest, modelBpmnProp, modelProp);
184     }
185
186     /**
187      * return appropriate model element given the type
188      *
189      * @param type
190      * @return
191      */
192     public AbstractModelElement getModelElementByType(String type) {
193         AbstractModelElement modelElement = modelElements.get(type);
194         if (modelElement == null) {
195             throw new IllegalArgumentException("Invalid or not found ModelElement type: " + type);
196         }
197         return modelElement;
198     }
199
200     /**
201      * @return the modelName
202      */
203     public String getModelName() {
204         return modelName;
205     }
206
207     /**
208      * @return the controlName
209      */
210     public String getControlName() {
211         return controlName;
212     }
213
214     /**
215      * @return the controlNameAndPolicyUniqueId
216      */
217     public String getControlNameAndPolicyUniqueId() {
218         return controlName + "_" + policyUniqueId;
219     }
220
221     /**
222      * @return the currentPolicyName
223      */
224     private String getCurrentPolicyName() {
225         return normalizePolicyScopeName(controlName + "_" + currentModelElementId);
226     }
227
228     /**
229      * @return the currentPolicyScopeAndPolicyName
230      */
231     public String getCurrentPolicyScopeAndPolicyName() {
232         return normalizePolicyScopeName(modelName + "." + getCurrentPolicyName());
233     }
234
235     /**
236      * @return the policyScopeAndNameWithUniqueId
237      */
238     public String getPolicyScopeAndNameWithUniqueId() {
239         return normalizePolicyScopeName(modelName + "." + getCurrentPolicyName() + "_" + policyUniqueId);
240     }
241
242     /**
243      * @return the currentPolicyScopeAndFullPolicyName
244      */
245     public String getCurrentPolicyScopeAndFullPolicyName(String policyNamePrefix) {
246         return normalizePolicyScopeName(modelName + "." + policyNamePrefix + getCurrentPolicyName());
247     }
248
249     /**
250      * @return the currentPolicyScopeAndFullPolicyNameWithVersion
251      */
252     public String getCurrentPolicyScopeAndFullPolicyNameWithVersion(String policyNamePrefix, int version) {
253         return normalizePolicyScopeName(
254                 modelName + "." + policyNamePrefix + getCurrentPolicyName() + "." + version + ".xml");
255     }
256
257     /**
258      * Replace all '-' with '_' within policy scope and name.
259      *
260      * @param inName
261      * @return
262      */
263     private String normalizePolicyScopeName(String inName) {
264         return inName.replaceAll("-", "_");
265     }
266
267     /**
268      * @return the currentModelElementId
269      */
270     public String getCurrentModelElementId() {
271         return currentModelElementId;
272     }
273
274     /**
275      * When generating a policy request for a model element, must set the id of
276      * that model element using this method. Used to generate the policy name.
277      *
278      * @param currentModelElementId
279      *            the currentModelElementId to set
280      */
281     public void setCurrentModelElementId(String currentModelElementId) {
282         this.currentModelElementId = currentModelElementId;
283     }
284
285     /**
286      * @return the policyUniqueId
287      */
288     public String getPolicyUniqueId() {
289         return policyUniqueId;
290     }
291
292     /**
293      * When generating a policy request for a model element, must set the unique
294      * id of that policy using this method. Used to generate the policy name.
295      *
296      * @param policyUniqueId
297      *            the policyUniqueId to set
298      */
299     public void setPolicyUniqueId(String policyUniqueId) {
300         this.policyUniqueId = policyUniqueId;
301     }
302
303     /**
304      * @return the actionCd
305      */
306     public String getActionCd() {
307         return actionCd;
308     }
309
310     /**
311      * @return the isTest
312      */
313     public boolean isTest() {
314         return isTest;
315     }
316
317     /**
318      * @return the isCreateRequest
319      */
320     public boolean isCreateRequest() {
321         switch (actionCd) {
322             case CldsEvent.ACTION_SUBMIT:
323             case CldsEvent.ACTION_RESTART:
324                 return true;
325         }
326         return false;
327     }
328
329     public boolean isStopRequest() {
330         switch (actionCd) {
331             case CldsEvent.ACTION_STOP:
332                 return true;
333         }
334         return false;
335     }
336
337     /**
338      * @return the global
339      */
340     public Global getGlobal() {
341         if (global == null) {
342             global = new Global(modelJson);
343         }
344         return global;
345     }
346
347     public static final synchronized void registerModelElement(Class<? extends AbstractModelElement> modelElementClass,
348             String type) {
349         if (!modelElementClasses.containsKey(modelElementClass.getClass())) {
350             modelElementClasses.put(modelElementClass, type);
351         }
352     }
353
354     public <T extends AbstractModelElement> T getType(Class<T> clazz) {
355         instantiateMissingModelElements();
356         String type = modelElementClasses.get(clazz);
357         return (type != null ? (T) modelElements.get(type) : null);
358     }
359 }