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