Minor Improvement
[clamp.git] / src / main / java / org / onap / clamp / clds / client / req / policy / PolicyClient.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.client.req.policy;
25
26 import com.att.eelf.configuration.EELFLogger;
27 import com.att.eelf.configuration.EELFManager;
28
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Date;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.UUID;
36
37 import javax.ws.rs.BadRequestException;
38
39 import org.onap.clamp.clds.config.ClampProperties;
40 import org.onap.clamp.clds.config.PolicyConfiguration;
41 import org.onap.clamp.clds.exception.policy.PolicyClientException;
42 import org.onap.clamp.clds.model.properties.ModelProperties;
43 import org.onap.clamp.clds.util.LoggingUtils;
44 import org.onap.policy.api.AttributeType;
45 import org.onap.policy.api.ConfigRequestParameters;
46 import org.onap.policy.api.DeletePolicyCondition;
47 import org.onap.policy.api.DeletePolicyParameters;
48 import org.onap.policy.api.PolicyChangeResponse;
49 import org.onap.policy.api.PolicyConfig;
50 import org.onap.policy.api.PolicyConfigException;
51 import org.onap.policy.api.PolicyConfigType;
52 import org.onap.policy.api.PolicyEngine;
53 import org.onap.policy.api.PolicyEngineException;
54 import org.onap.policy.api.PolicyParameters;
55 import org.onap.policy.api.PolicyType;
56 import org.onap.policy.api.PushPolicyParameters;
57 import org.springframework.beans.factory.annotation.Autowired;
58 import org.springframework.context.ApplicationContext;
59 import org.springframework.context.annotation.Primary;
60 import org.springframework.stereotype.Component;
61
62 /**
63  * Policy utility methods - specifically, send the policy.
64  */
65 @Component
66 @Primary
67 public class PolicyClient {
68
69     protected PolicyEngine policyEngine;
70     protected static final String LOG_POLICY_PREFIX = "Response is ";
71     protected static final EELFLogger logger = EELFManager.getInstance().getLogger(PolicyClient.class);
72     protected static final EELFLogger metricsLogger = EELFManager.getInstance().getMetricsLogger();
73     public static final String POLICY_MSTYPE_PROPERTY_NAME = "policy.ms.type";
74     public static final String POLICY_ONAPNAME_PROPERTY_NAME = "policy.onap.name";
75     public static final String POLICY_BASENAME_PREFIX_PROPERTY_NAME = "policy.base.policyNamePrefix";
76     public static final String POLICY_OP_NAME_PREFIX_PROPERTY_NAME = "policy.op.policyNamePrefix";
77     public static final String POLICY_MS_NAME_PREFIX_PROPERTY_NAME = "policy.ms.policyNamePrefix";
78     public static final String POLICY_OP_TYPE_PROPERTY_NAME = "policy.op.type";
79     @Autowired
80     protected ApplicationContext appContext;
81     @Autowired
82     protected ClampProperties refProp;
83     @Autowired
84     private PolicyConfiguration policyConfiguration;
85
86     /**
87      * Perform BRMS policy type.
88      *
89      * @param attributes
90      *            A map of attributes
91      * @param prop
92      *            The ModelProperties
93      * @param policyRequestUuid
94      *            PolicyRequest UUID
95      * @return The response message of policy
96      */
97     public String sendBrmsPolicy(Map<AttributeType, Map<String, String>> attributes, ModelProperties prop,
98             String policyRequestUuid) {
99         PolicyParameters policyParameters = new PolicyParameters();
100         // Set Policy Type(Mandatory)
101         policyParameters.setPolicyConfigType(PolicyConfigType.BRMS_PARAM);
102         // Set Policy Name(Mandatory)
103         policyParameters.setPolicyName(prop.getPolicyScopeAndNameWithUniqueId());
104         // documentation says this is options, but when tested, got the
105         // following failure: java.lang.Exception: Policy send failed: PE300 -
106         // Data Issue: No policyDescription given.
107         policyParameters.setPolicyDescription(refProp.getStringValue("op.policyDescription"));
108         policyParameters.setAttributes(attributes);
109         // Set a random UUID(Mandatory)
110         policyParameters.setRequestID(UUID.fromString(policyRequestUuid));
111         String policyNamePrefix = refProp.getStringValue(POLICY_OP_NAME_PREFIX_PROPERTY_NAME);
112         String rtnMsg = send(policyParameters, prop, policyNamePrefix);
113         String policyType = refProp.getStringValue(POLICY_OP_TYPE_PROPERTY_NAME);
114         push(policyType, prop);
115         return rtnMsg;
116     }
117
118     /**
119      * Perform send of microservice policy in JSON.
120      *
121      * @param policyJson
122      *            The policy JSON
123      * @param prop
124      *            The ModelProperties
125      * @param policyRequestUuid
126      *            The policy Request UUID
127      * @return The response message of policy
128      */
129     public String sendMicroServiceInJson(String policyJson, ModelProperties prop, String policyRequestUuid) {
130         PolicyParameters policyParameters = new PolicyParameters();
131         // Set Policy Type
132         policyParameters.setPolicyConfigType(PolicyConfigType.MicroService);
133         policyParameters.setOnapName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME));
134         policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
135         policyParameters.setConfigBody(policyJson);
136         policyParameters.setConfigBodyType(PolicyType.JSON);
137         policyParameters.setRequestID(UUID.fromString(policyRequestUuid));
138         String policyNamePrefix = refProp.getStringValue(POLICY_MS_NAME_PREFIX_PROPERTY_NAME);
139         // Adding this line to clear the policy id from policy name while
140         // pushing to policy engine
141         prop.setPolicyUniqueId("");
142         String rtnMsg = send(policyParameters, prop, policyNamePrefix);
143         String policyType = refProp.getStringValue(POLICY_MSTYPE_PROPERTY_NAME);
144         push(policyType, prop);
145         return rtnMsg;
146     }
147
148     /**
149      * Perform send of base policy in OTHER type.
150      *
151      * @param configBody
152      *            The config policy string body
153      * @param configPolicyName
154      *            The config policy name of the component that has been
155      *            pre-deployed in DCAE
156      * @param prop
157      *            The ModelProperties
158      * @param policyRequestUuid
159      *            The policy request UUID
160      * @return The answer from policy call
161      */
162     public String sendBasePolicyInOther(String configBody, String configPolicyName, ModelProperties prop,
163             String policyRequestUuid) {
164         PolicyParameters policyParameters = new PolicyParameters();
165         // Set Policy Type
166         policyParameters.setPolicyConfigType(PolicyConfigType.Base);
167         policyParameters.setOnapName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME));
168         policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
169         policyParameters.setConfigBody(configBody);
170         policyParameters.setConfigBodyType(PolicyType.OTHER);
171         policyParameters.setConfigName("HolmesPolicy");
172         policyParameters.setPolicyName(configPolicyName);
173         policyParameters.setRequestID(UUID.fromString(policyRequestUuid));
174         // Adding this line to clear the policy id from policy name while
175         // pushing to policy engine
176         prop.setPolicyUniqueId("");
177         String rtnMsg = send(policyParameters, prop, refProp.getStringValue(POLICY_BASENAME_PREFIX_PROPERTY_NAME));
178         push(PolicyConfigType.Base.toString(), prop);
179         return rtnMsg;
180     }
181
182     /**
183      * Perform send of Microservice policy in OTHER type.
184      * 
185      * @param configBody
186      *            The config policy string body
187      * @param prop
188      *            The ModelProperties
189      * @return The answer from policy call
190      */
191     public String sendMicroServiceInOther(String configBody, ModelProperties prop) {
192         PolicyParameters policyParameters = new PolicyParameters();
193         // Set Policy Type
194         policyParameters.setPolicyConfigType(PolicyConfigType.MicroService);
195         policyParameters.setOnapName(refProp.getStringValue(POLICY_ONAPNAME_PROPERTY_NAME));
196         policyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
197         policyParameters.setConfigBody(configBody);
198         String policyNamePrefix = refProp.getStringValue(POLICY_MS_NAME_PREFIX_PROPERTY_NAME);
199         // Adding this line to clear the policy id from policy name while
200         // pushing to policy engine
201         prop.setPolicyUniqueId("");
202         String rtnMsg = send(policyParameters, prop, policyNamePrefix);
203         String policyType = refProp.getStringValue(POLICY_MSTYPE_PROPERTY_NAME);
204         push(policyType, prop);
205         return rtnMsg;
206     }
207
208     /**
209      * Perform send of policy.
210      *
211      * @param policyParameters
212      *            The PolicyParameters
213      * @param prop
214      *            The ModelProperties
215      * @return The response message of Policy
216      */
217     protected String send(PolicyParameters policyParameters, ModelProperties prop, String policyNamePrefix) {
218         // Verify whether it is triggered by Validation Test button from UI
219         if (prop.isTestOnly()) {
220             return "send not executed for test action";
221         }
222         // API method to create or update Policy.
223         PolicyChangeResponse response = null;
224         String responseMessage = "";
225         Date startTime = new Date();
226         try {
227             List<Integer> versions = getVersions(policyNamePrefix, prop);
228             if (versions.isEmpty()) {
229                 LoggingUtils.setTargetContext("Policy", "createPolicy");
230                 logger.info("Attempting to create policy for action=" + prop.getActionCd());
231                 response = getPolicyEngine().createPolicy(policyParameters);
232                 responseMessage = response.getResponseMessage();
233             } else {
234                 LoggingUtils.setTargetContext("Policy", "updatePolicy");
235                 logger.info("Attempting to update policy for action=" + prop.getActionCd());
236                 response = getPolicyEngine().updatePolicy(policyParameters);
237                 responseMessage = response.getResponseMessage();
238             }
239         } catch (Exception e) {
240             LoggingUtils.setResponseContext("900", "Policy send failed", this.getClass().getName());
241             LoggingUtils.setErrorContext("900", "Policy send error");
242             logger.error("Exception occurred during policy communication", e);
243             throw new PolicyClientException("Exception while communicating with Policy", e);
244         }
245         logger.info(LOG_POLICY_PREFIX + responseMessage);
246         LoggingUtils.setTimeContext(startTime, new Date());
247         if (response.getResponseCode() == 200) {
248             LoggingUtils.setResponseContext("0", "Policy send success", this.getClass().getName());
249             logger.info("Policy send successful");
250             metricsLogger.info("Policy send success");
251         } else {
252             LoggingUtils.setResponseContext("900", "Policy send failed", this.getClass().getName());
253             logger.warn("Policy send failed: " + responseMessage);
254             metricsLogger.info("Policy send failure");
255             throw new BadRequestException("Policy send failed: " + responseMessage);
256         }
257         return responseMessage;
258     }
259
260     /**
261      * Format and send push of policy.
262      *
263      * @param policyType
264      *            The policy Type
265      * @param prop
266      *            The ModelProperties
267      * @return The response message of policy
268      */
269     protected String push(String policyType, ModelProperties prop) {
270         // Verify whether it is triggered by Validation Test button from UI
271         if (prop.isTestOnly()) {
272             return "push not executed for test action";
273         }
274         PushPolicyParameters pushPolicyParameters = new PushPolicyParameters();
275         // Parameter arguments
276         if (prop.getPolicyUniqueId() != null && !prop.getPolicyUniqueId().isEmpty()) {
277             pushPolicyParameters.setPolicyName(prop.getPolicyScopeAndNameWithUniqueId());
278         } else {
279             pushPolicyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
280         }
281         logger.info("Policy Name in Push policy method - " + pushPolicyParameters.getPolicyName());
282         pushPolicyParameters.setPolicyType(policyType);
283         pushPolicyParameters.setPdpGroup(refProp.getStringValue("policy.pdp.group"));
284         pushPolicyParameters.setRequestID(null);
285         // API method to create or update Policy.
286         PolicyChangeResponse response;
287         String responseMessage = "";
288         try {
289             LoggingUtils.setTargetContext("Policy", "pushPolicy");
290             logger.info("Attempting to push policy...");
291             response = getPolicyEngine().pushPolicy(pushPolicyParameters);
292             if (response != null) {
293                 responseMessage = response.getResponseMessage();
294             }
295         } catch (Exception e) {
296             LoggingUtils.setResponseContext("900", "Policy push failed", this.getClass().getName());
297             LoggingUtils.setErrorContext("900", "Policy push error");
298             logger.error("Exception occurred during policy communication", e);
299             throw new PolicyClientException("Exception while communicating with Policy", e);
300         }
301         logger.info(LOG_POLICY_PREFIX + responseMessage);
302         if (response != null && (response.getResponseCode() == 200 || response.getResponseCode() == 204)) {
303             LoggingUtils.setResponseContext("0", "Policy push success", this.getClass().getName());
304             logger.info("Policy push successful");
305             metricsLogger.info("Policy push success");
306         } else {
307             LoggingUtils.setResponseContext("900", "Policy push failed", this.getClass().getName());
308             logger.warn("Policy push failed: " + responseMessage);
309             metricsLogger.info("Policy push failure");
310             throw new BadRequestException("Policy push failed: " + responseMessage);
311         }
312         return responseMessage;
313     }
314
315     /**
316      * Use Get Config Policy API to retrieve the versions for a policy. Return
317      * versions in sorted order. Return empty list if none found.
318      *
319      * @param policyNamePrefix
320      *            The Policy Name Prefix
321      * @param prop
322      *            The ModelProperties
323      * @return The response message from policy
324      * @throws PolicyConfigException
325      *             In case of issues with policy engine
326      */
327     protected List<Integer> getVersions(String policyNamePrefix, ModelProperties prop) throws PolicyConfigException {
328         ArrayList<Integer> versions = new ArrayList<>();
329         ConfigRequestParameters configRequestParameters = new ConfigRequestParameters();
330         String policyName = "";
331         if (prop.getPolicyUniqueId() != null && !prop.getPolicyUniqueId().isEmpty()) {
332             policyName = prop.getCurrentPolicyScopeAndFullPolicyName(policyNamePrefix) + "_" + prop.getPolicyUniqueId();
333         } else {
334             policyName = prop.getCurrentPolicyScopeAndFullPolicyName(policyNamePrefix);
335         }
336         logger.info("Search in Policy Engine for policyName=" + policyName);
337         configRequestParameters.setPolicyName(policyName);
338         try {
339             Collection<PolicyConfig> response = getPolicyEngine().getConfig(configRequestParameters);
340             for (PolicyConfig policyConfig : response) {
341                 if (policyConfig.getPolicyVersion() != null) {
342                     Integer version = Integer.valueOf(policyConfig.getPolicyVersion());
343                     versions.add(version);
344                 } else {
345                     logger.warn("Policy version was null, unable to convert it to Integer");
346                 }
347             }
348             Collections.sort(versions);
349             logger.info("Policy versions.size()=" + versions.size());
350         } catch (PolicyConfigException e) {
351             // just print warning - if no policy version found
352             logger.warn("policy not found...policy name - " + policyName, e);
353         }
354         return versions;
355     }
356
357     /**
358      * This method create a new policy engine.
359      * 
360      * @return A new policy engine
361      */
362     private synchronized PolicyEngine getPolicyEngine() {
363         try {
364             if (policyEngine == null) {
365                 policyEngine = new PolicyEngine(policyConfiguration.getProperties());
366             }
367         } catch (PolicyEngineException e) {
368             throw new PolicyClientException("Exception when creating a new policy engine", e);
369         }
370         return policyEngine;
371     }
372
373     /**
374      * Format and send delete Micro Service requests to Policy.
375      *
376      * @param prop
377      *            The ModelProperties
378      * @return The response message from Policy
379      */
380     public String deleteMicrosService(ModelProperties prop) {
381         String deletePolicyResponse = "";
382         try {
383             String policyNamePrefix = refProp.getStringValue(POLICY_MS_NAME_PREFIX_PROPERTY_NAME);
384             List<Integer> versions = getVersions(policyNamePrefix, prop);
385             if (!versions.isEmpty()) {
386                 String policyType = refProp.getStringValue(POLICY_MSTYPE_PROPERTY_NAME);
387                 deletePolicyResponse = deletePolicy(prop, policyType);
388             }
389         } catch (Exception e) {
390             logger.error("Exception occurred during policy communication", e);
391             throw new PolicyClientException("Exception while communicating with Policy", e);
392         }
393         return deletePolicyResponse;
394     }
395
396     /**
397      * This method delete the Base policy.
398      *
399      * @param prop
400      *            The model Properties
401      * @return A string with the answer from policy
402      */
403     public String deleteBasePolicy(ModelProperties prop) {
404         return deletePolicy(prop, PolicyConfigType.Base.toString());
405     }
406
407     /**
408      * Format and send delete BRMS requests to Policy.
409      *
410      * @param prop
411      *            The ModelProperties
412      * @return The response message from policy
413      */
414     public String deleteBrms(ModelProperties prop) {
415         String deletePolicyResponse = "";
416         try {
417             String policyNamePrefix = refProp.getStringValue(POLICY_OP_NAME_PREFIX_PROPERTY_NAME);
418             List<Integer> versions = getVersions(policyNamePrefix, prop);
419             if (!versions.isEmpty()) {
420                 String policyType = refProp.getStringValue(POLICY_OP_TYPE_PROPERTY_NAME);
421                 deletePolicyResponse = deletePolicy(prop, policyType);
422             }
423         } catch (Exception e) {
424             logger.error("Exception occurred during policy communication", e);
425             throw new PolicyClientException("Exception while communicating with Policy", e);
426         }
427         return deletePolicyResponse;
428     }
429
430     /**
431      * Format and send delete PAP and PDP requests to Policy.
432      *
433      * @param prop
434      *            The ModelProperties
435      * @return The response message from policy
436      */
437     protected String deletePolicy(ModelProperties prop, String policyType) {
438         DeletePolicyParameters deletePolicyParameters = new DeletePolicyParameters();
439         if (prop.getPolicyUniqueId() != null && !prop.getPolicyUniqueId().isEmpty()) {
440             deletePolicyParameters.setPolicyName(prop.getPolicyScopeAndNameWithUniqueId());
441         } else {
442             deletePolicyParameters.setPolicyName(prop.getCurrentPolicyScopeAndPolicyName());
443         }
444         logger.info("Policy Name in delete policy method - " + deletePolicyParameters.getPolicyName());
445         deletePolicyParameters.setPolicyComponent("PDP");
446         deletePolicyParameters.setDeleteCondition(DeletePolicyCondition.ALL);
447         deletePolicyParameters.setPdpGroup(refProp.getStringValue("policy.pdp.group"));
448         deletePolicyParameters.setPolicyType(policyType);
449         // send delete request
450         StringBuilder responseMessage = new StringBuilder(sendDeletePolicy(deletePolicyParameters, prop));
451         logger.info("Deleting policy from PAP...");
452         deletePolicyParameters.setPolicyComponent("PAP");
453         deletePolicyParameters.setDeleteCondition(DeletePolicyCondition.ALL);
454         // send delete request
455         responseMessage.append(sendDeletePolicy(deletePolicyParameters, prop));
456         return responseMessage.toString();
457     }
458
459     /**
460      * Send delete request to Policy.
461      *
462      * @param deletePolicyParameters
463      *            The DeletePolicyParameters
464      * @param prop
465      *            The ModelProperties
466      * @return The response message from policy
467      */
468     protected String sendDeletePolicy(DeletePolicyParameters deletePolicyParameters, ModelProperties prop) {
469         // Verify whether it is triggered by Validation Test button from UI
470         if (prop.isTestOnly()) {
471             return "delete not executed for test action";
472         }
473         // API method to create or update Policy.
474         PolicyChangeResponse response = null;
475         String responseMessage = "";
476         try {
477             logger.info("Attempting to delete policy...");
478             response = getPolicyEngine().deletePolicy(deletePolicyParameters);
479             responseMessage = response.getResponseMessage();
480         } catch (Exception e) {
481             logger.error("Exception occurred during policy communnication", e);
482         }
483         logger.info(LOG_POLICY_PREFIX + responseMessage);
484         if (response != null && response.getResponseCode() == 200) {
485             logger.info("Policy delete successful");
486         } else {
487             logger.warn("Policy delete failed: " + responseMessage);
488             throw new BadRequestException("Policy delete failed: " + responseMessage);
489         }
490         return responseMessage;
491     }
492 }