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