7abf38620c47841b6d7f7baf4c0eff8cd8a4297f
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  * guard
4  * ================================================================================
5  * Copyright (C) 2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.guard;
22
23 import com.att.research.xacml.api.DataTypeException;
24 import com.att.research.xacml.std.annotations.RequestParser;
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.UUID;
28 import java.util.function.Supplier;
29 import org.drools.core.WorkingMemory;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 public class CallGuardTaskEmbedded implements Runnable {
34
35     private static final Logger logger = LoggerFactory.getLogger(CallGuardTaskEmbedded.class);
36
37     /**
38      * Actor/recipe pairs whose guard requests need a VF Module count. Each element is of
39      * the form "<actor>:<recipe>".
40      */
41     private static final Set<String> NEEDS_VF_COUNT = new HashSet<>();
42
43     /**
44      * Actor/recipe pairs whose guard requests need the VF Module count to be incremented
45      * (i.e., because a module is being added). Each element is of the form
46      * "&lt;actor&gt;:&lt;recipe&gt;".
47      */
48     private static final Set<String> INCR_VF_COUNT = new HashSet<>();
49
50     static {
51         INCR_VF_COUNT.add("SO:VF Module Create");
52         NEEDS_VF_COUNT.addAll(INCR_VF_COUNT);
53     }
54
55     private WorkingMemory workingMemory;
56     private String clname;
57     private String actor;
58     private String recipe;
59     private String target;
60     private String requestId;
61     private Integer vfCount;
62
63     /**
64      * Populated once the response has been determined, which may happen during the
65      * constructor or later, during {@link #run()}.
66      */
67     private PolicyGuardResponse guardResponse;
68
69     /**
70      * Guard url is grabbed from PolicyEngine.manager properties
71      */
72     public CallGuardTaskEmbedded(WorkingMemory wm, String cl, String act, String rec, 
73             String tar, String reqId, Supplier<Integer> vfcnt) {
74         workingMemory = wm;
75         clname = cl;
76         actor = act;
77         recipe = rec;
78         requestId = reqId;
79         target = tar;
80
81         vfCount = null;
82
83         String key = act + ":" + rec;
84
85         if (NEEDS_VF_COUNT.contains(key)) {
86             // this actor/recipe needs the count - get it
87             if ((vfCount = vfcnt.get()) == null) {
88                 /*
89                  * The count is missing - create an artificial Deny, which will be
90                  * inserted into working memory when "run()" is called.
91                  */
92                 guardResponse = new PolicyGuardResponse(Util.DENY, UUID.fromString(requestId), recipe);
93                 logger.error("CallEmbeddedGuardTask.run missing VF Module count; requestId={}", requestId);
94                 return;
95             }
96
97             if (INCR_VF_COUNT.contains(key)) {
98                 // this actor/recipe needs the count to be incremented
99                 ++vfCount;
100             }
101         }
102     }
103
104     @Override
105     public void run() {
106         if (guardResponse != null) {
107             // already have a response - just insert it
108             workingMemory.insert(guardResponse);
109             return;
110         }
111         
112         final long startTime = System.nanoTime();
113         com.att.research.xacml.api.Request request = null;
114
115         PolicyGuardXacmlRequestAttributes xacmlReq =
116                         new PolicyGuardXacmlRequestAttributes(clname, actor, recipe, target, requestId, vfCount);
117
118         try {
119             request = RequestParser.parseRequest(xacmlReq);
120         } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) {
121             logger.error("CallEmbeddedGuardTask.run threw: {}", e);
122         }
123
124
125         logger.debug("\n********** XACML REQUEST START ********");
126         logger.debug("{}", request);
127         logger.debug("********** XACML REQUEST END ********\n");
128
129         String guardDecision = null;
130
131         //
132         // Make guard request
133         //
134         guardDecision = new PolicyGuardXacmlHelperEmbedded().callPdp(xacmlReq);
135
136         logger.debug("\n********** XACML RESPONSE START ********");
137         logger.debug("{}", guardDecision);
138         logger.debug("********** XACML RESPONSE END ********\n");
139
140         //
141         // Check if the restful call was unsuccessful or property doesn't exist
142         //
143         if (guardDecision == null) {
144             logger.error("********** XACML FAILED TO CONNECT ********");
145             guardDecision = Util.INDETERMINATE;
146         }
147
148         guardResponse = new PolicyGuardResponse(guardDecision, UUID.fromString(this.requestId), this.recipe);
149
150
151         //
152         // Create an artificial Guard response in case we didn't get a clear Permit or Deny
153         //
154         if (guardResponse.getResult().equals("Indeterminate")) {
155             guardResponse.setOperation(recipe);
156             guardResponse.setRequestID(UUID.fromString(requestId));
157         }
158
159         long estimatedTime = System.nanoTime() - startTime;
160         logger.debug("\n\n============ Guard inserted with decision {} !!! =========== time took: {} mili sec \n\n",
161                 guardResponse.getResult(), (double) estimatedTime / 1000 / 1000);
162         workingMemory.insert(guardResponse);
163
164     }
165
166 }