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