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