Fix operation history DB properties for Junits
[policy/drools-applications.git] / controlloop / common / guard / src / main / java / org / onap / policy / guard / PIPEngineGetHistory.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * guard
4  * ================================================================================
5  * Copyright (C) 2017 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 java.io.IOException;
24 import java.io.InputStream;
25 import java.math.BigInteger;
26 import java.sql.Timestamp;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.Date;
30 import java.util.HashSet;
31 import java.util.Iterator;
32 import java.util.Properties;
33 import java.util.Set;
34
35 import javax.persistence.EntityManager;
36 import javax.persistence.NoResultException;
37 import javax.persistence.NonUniqueResultException;
38 import javax.persistence.Persistence;
39 import javax.persistence.Query;
40
41 import org.onap.policy.drools.system.PolicyEngine;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 import com.att.research.xacml.api.Attribute;
46 import com.att.research.xacml.api.AttributeValue;
47 import com.att.research.xacml.api.Identifier;
48 import com.att.research.xacml.api.pip.PIPException;
49 import com.att.research.xacml.api.pip.PIPFinder;
50 import com.att.research.xacml.api.pip.PIPRequest;
51 import com.att.research.xacml.api.pip.PIPResponse;
52 import com.att.research.xacml.std.IdentifierImpl;
53 import com.att.research.xacml.std.StdMutableAttribute;
54 import com.att.research.xacml.std.datatypes.DataTypes;
55 import com.att.research.xacml.std.pip.StdMutablePIPResponse;
56 import com.att.research.xacml.std.pip.StdPIPRequest;
57 import com.att.research.xacml.std.pip.StdPIPResponse;
58 import com.att.research.xacml.std.pip.engines.StdConfigurableEngine;
59
60
61
62 public class PIPEngineGetHistory extends StdConfigurableEngine{
63         
64         private interface DateUtil{
65                 public class DateUtilException extends Exception {
66                         private static final long serialVersionUID = 2612662650481443076L;
67
68                         public DateUtilException(String message) {
69                                 super(message);
70                         }
71                         
72                 }
73                 
74         public long getMs();
75         public DateUtil init(String sqlValUnit) throws DateUtilException;
76     }
77
78         private static final Logger logger = LoggerFactory.getLogger(PIPEngineGetHistory.class);
79
80         public static final String DEFAULT_DESCRIPTION  = "PIP for retrieving Operations History from DB";
81         
82         
83
84         //
85         // Base issuer string. The issuer in the policy will also contain time window information
86         // E.g., "com:att:research:xacml:guard:historydb:tw:10:min"
87         //
88         public static final String DEFAULT_ISSUER                       = "com:att:research:xacml:guard:historydb";
89
90
91         private static final PIPRequest PIP_REQUEST_ACTOR       = new StdPIPRequest(
92                                         new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"),
93                                         new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:actor:actor-id"),
94                                         new IdentifierImpl("http://www.w3.org/2001/XMLSchema#string"));
95
96         private static final PIPRequest PIP_REQUEST_RECIPE              = new StdPIPRequest(
97                                         new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:action"),
98                                         new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:operation:operation-id"),
99                                         new IdentifierImpl("http://www.w3.org/2001/XMLSchema#string"));
100
101         private static final PIPRequest PIP_REQUEST_TARGET              = new StdPIPRequest(
102                         new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"),
103                         new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:target:target-id"),
104                         new IdentifierImpl("http://www.w3.org/2001/XMLSchema#string"));
105
106
107         private void addIntegerAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, int value, PIPRequest pipRequest) {
108                 AttributeValue<BigInteger> attributeValue       = null;
109                 try {
110                         attributeValue  = DataTypes.DT_INTEGER.createAttributeValue(value);
111                 } catch (Exception ex) {
112                         logger.error("Failed to convert {} to an AttributeValue<Boolean>",value, ex);
113                 }
114                 if (attributeValue != null) {
115                         stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, pipRequest.getIssuer()/*this.getIssuer()*/, false));
116                 }
117         }
118
119
120
121         public PIPEngineGetHistory() {
122                 super();
123                 // TODO Auto-generated constructor stub
124         }
125
126
127
128         @Override
129         public Collection<PIPRequest> attributesRequired() {
130                 // TODO Auto-generated method stub
131             return Collections.emptySet();
132         }
133
134         @Override
135         public Collection<PIPRequest> attributesProvided() {
136                 // TODO Auto-generated method stub
137             return Collections.emptySet();
138         }
139
140         @Override
141         public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException {
142                 // TODO Auto-generated method stub
143                 logger.debug("Entering FeqLimiter PIP");
144
145                 /*
146                  * First check to see if the issuer is set and then match it
147                  */
148                 String string;
149                 if ((string = pipRequest.getIssuer()) == null) {
150
151                         logger.debug("No issuer in the request...");
152                         logger.debug("FeqLimiter PIP - No issuer in the request!");
153                         return StdPIPResponse.PIP_RESPONSE_EMPTY;
154                 }
155                 else{
156                         //Notice, we are checking here for the base issuer prefix.
157                         if (!string.contains(this.getIssuer())) {
158                                 logger.debug("Requested issuer '{}' does not match {}", string, getIssuer());
159                                 logger.debug("FeqLimiter PIP - Issuer {}  does not match with: ", string, this.getIssuer());
160                                 return StdPIPResponse.PIP_RESPONSE_EMPTY;
161                         }
162                 }
163
164                 String[] s1 = string.split("tw:");
165                 String[] s2 = s1[1].split(":");
166                 String timeWindowVal = s2[0];// number [of minutes, hours, days...]
167                 String timeWindowScale = s2[1];//e.g., minute, hour, day, week, month, year
168
169                 String actor = getActor(pipFinder).iterator().next();
170                 String operation = getRecipe(pipFinder).iterator().next();
171                 String target = getTarget(pipFinder).iterator().next();
172
173                 String timeWindow = timeWindowVal + " " + timeWindowScale;
174
175                 logger.debug("Going to query DB about: {} {} {} {}", actor, operation, target, timeWindow);
176                 int countFromDB = getCountFromDB(actor, operation, target, timeWindow);
177
178                 StdMutablePIPResponse stdPIPResponse    = new StdMutablePIPResponse();
179
180                 this.addIntegerAttribute(stdPIPResponse,
181                                 new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"),
182                                 new IdentifierImpl("com:att:research:xacml:test:sql:resource:operations:count"),
183                                 countFromDB,
184                                 pipRequest);
185
186                 return new StdPIPResponse(stdPIPResponse);
187         }
188
189
190         @Override
191         public void configure(String id, Properties properties) throws PIPException {
192                 super.configure(id, properties);
193
194                 if (this.getDescription() == null) {
195                         this.setDescription(DEFAULT_DESCRIPTION);
196                 }
197                 if (this.getIssuer() == null) {
198                         this.setIssuer(DEFAULT_ISSUER);
199                 }
200         }
201
202
203
204         private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) {
205                 PIPResponse pipResponse = null;
206
207                 try {
208                         pipResponse     = pipFinder.getMatchingAttributes(pipRequest, this);
209                 } catch (PIPException ex) {
210                         logger.error("getAttribute threw:", ex);
211                         return null;
212                 }
213                 if (pipResponse == null) {
214                         return null;
215                 }
216                 if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) {
217                         logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus().toString());
218                         return null;
219                 }
220                 if (pipResponse.getAttributes() != null && pipResponse.getAttributes().isEmpty()) {
221                         logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus().toString());
222                         logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus());
223                         return null;
224                 }
225                 if (pipResponse.getAttributes() != null && pipResponse.getAttributes().isEmpty()) {
226                         logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus());
227                         return null;
228                 }
229                 return pipResponse;
230         }
231
232
233         private Set<String> getActor(PIPFinder pipFinder) {
234                 /*
235                  * Get the AT&T UID from either the subject id or the attuid property
236                  */
237                 PIPResponse pipResponseATTUID   = this.getAttribute(PIP_REQUEST_ACTOR, pipFinder);
238                 if (pipResponseATTUID == null) {
239                         return null;
240                 }
241
242                 /*
243                  * Iterate over all of the returned results and do the LDAP requests
244                  */
245                 Collection<Attribute> listATTUIDs       = pipResponseATTUID.getAttributes();
246                 Set<String> setATTUIDs                  = new HashSet<String>();
247                 for (Attribute attributeATTUID: listATTUIDs) {
248                         Iterator<AttributeValue<String>> iterAttributeValues    = attributeATTUID.findValues(DataTypes.DT_STRING);
249                         if (iterAttributeValues != null) {
250                                 while (iterAttributeValues.hasNext()) {
251                                         String attuid   = iterAttributeValues.next().getValue();
252                                         if (attuid != null) {
253                                                 setATTUIDs.add(attuid);
254                                         }
255                                 }
256                         }
257                 }
258
259                 return setATTUIDs;
260         }
261
262         private Set<String> getRecipe(PIPFinder pipFinder) {
263                 /*
264                  * Get the AT&T UID from either the subject id or the attuid property
265                  */
266                 PIPResponse pipResponseATTUID   = this.getAttribute(PIP_REQUEST_RECIPE, pipFinder);
267                 if (pipResponseATTUID == null) {
268                         return null;
269                 }
270
271                 /*
272                  * Iterate over all of the returned results and do the LDAP requests
273                  */
274                 Collection<Attribute> listATTUIDs       = pipResponseATTUID.getAttributes();
275                 Set<String> setATTUIDs                  = new HashSet<String>();
276                 for (Attribute attributeATTUID: listATTUIDs) {
277                         Iterator<AttributeValue<String>> iterAttributeValues    = attributeATTUID.findValues(DataTypes.DT_STRING);
278                         if (iterAttributeValues != null) {
279                                 while (iterAttributeValues.hasNext()) {
280                                         String attuid   = iterAttributeValues.next().getValue();
281                                         if (attuid != null) {
282                                                 setATTUIDs.add(attuid);
283                                         }
284                                 }
285                         }
286                 }
287
288                 return setATTUIDs;
289         }
290
291
292         private Set<String> getTarget(PIPFinder pipFinder) {
293                 /*
294                  * Get the AT&T UID from either the subject id or the attuid property
295                  */
296                 PIPResponse pipResponseATTUID   = this.getAttribute(PIP_REQUEST_TARGET, pipFinder);
297                 if (pipResponseATTUID == null) {
298                         return null;
299                 }
300
301                 /*
302                  * Iterate over all of the returned results and do the LDAP requests
303                  */
304                 Collection<Attribute> listATTUIDs       = pipResponseATTUID.getAttributes();
305                 Set<String> setATTUIDs                  = new HashSet<String>();
306                 for (Attribute attributeATTUID: listATTUIDs) {
307                         Iterator<AttributeValue<String>> iterAttributeValues    = attributeATTUID.findValues(DataTypes.DT_STRING);
308                         if (iterAttributeValues != null) {
309                                 while (iterAttributeValues.hasNext()) {
310                                         String attuid   = iterAttributeValues.next().getValue();
311                                         if (attuid != null) {
312                                                 setATTUIDs.add(attuid);
313                                         }
314                                 }
315                         }
316                 }
317
318                 return setATTUIDs;
319         }
320
321         private static int getCountFromDB(String actor, String operation, String target, String timeWindow){
322
323                 // DB Properties
324                 Properties props = new Properties();
325                 props.put(Util.ECLIPSE_LINK_KEY_URL, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL));
326                 props.put(Util.ECLIPSE_LINK_KEY_USER, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER));
327                 props.put(Util.ECLIPSE_LINK_KEY_PASS, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS));
328                 
329
330                 EntityManager em = null;
331                 String OpsHistPU = System.getProperty("OperationsHistoryPU");
332                 if(OpsHistPU == null || !OpsHistPU.equals("TestOperationsHistoryPU")){
333                         OpsHistPU = "OperationsHistoryPU";
334                 }
335                 else{
336                         props.clear();
337                 }
338                 try{
339                         em = Persistence.createEntityManagerFactory(OpsHistPU, props).createEntityManager();
340                 }catch(Exception ex){
341                         logger.error("PIP thread got Exception. Can't connect to Operations History DB -- {}", OpsHistPU);
342                         logger.error("getCountFromDB threw: ", ex);
343                         return 0;
344                 }
345
346                 DateUtil dateUtil = new DateUtil(){
347                         private long ms = 0;
348                         private double multiplier = 0;
349
350                         @Override
351                         public DateUtil init(String sqlValUnit) throws DateUtilException{
352                                 String[] split = sqlValUnit.split(" ");
353                                 if(split.length != 2){
354                                         throw new DateUtilException("Invalid Value Unit pair for SQL");
355                                 }
356
357                                 ms = Long.parseLong(split[0]);
358
359                                 if("SECOND".compareToIgnoreCase(split[1]) == 0){
360                                         multiplier = 1000;
361                                 }
362                                 else if("MINUTE".compareToIgnoreCase(split[1]) == 0){
363                                         multiplier = 60000;
364                                 }
365                                 else if("HOUR".compareToIgnoreCase(split[1]) == 0){
366                                         multiplier = 3.6e+6;
367                                 }
368                                 else if("DAY".compareToIgnoreCase(split[1]) == 0){
369                                         multiplier = 8.64e+7;
370                                 }
371                                 else if("WEEK".compareToIgnoreCase(split[1]) == 0){
372                                         multiplier = 6.048e+8;
373                                 }
374                                 else if("MONTH".compareToIgnoreCase(split[1]) == 0){
375                                         multiplier = 2.628e+9;
376                                 }
377                                 else if("QUARTER".compareToIgnoreCase(split[1]) == 0){
378                                         multiplier = 2.628e+9 * 3;
379                                 }
380                                 else if("YEAR".compareToIgnoreCase(split[1]) == 0){
381                                         multiplier = 3.154e+10;
382                                 }
383                                 else{
384                                         logger.error("{} not supported", split[1]);
385                                 }
386
387                                 ms *= multiplier;
388                                 return this;
389                         }
390                         public long getMs(){
391                                 return ms;
392                         }
393                 };
394
395                 long now = new Date().getTime();
396                 long diff;
397                 try {
398                         diff = now - dateUtil.init(timeWindow).getMs();
399                 } catch (Exception ex) {
400                         logger.error("PIP thread got Exception " + ex);
401                         return -1;
402                 }
403
404                 String sql = "select count(*) as count from operationshistory10 where outcome<>'Failure_Guard'"
405                                 + " and actor= ?"
406                                 + " and operation= ?"
407                                 + " and target= ?"
408                                 + " and endtime between '" + new Timestamp(diff) + "' and '" + new Timestamp(now) + "'";
409
410                 Query nq = em.createNativeQuery(sql);
411                 nq.setParameter(0, actor);
412                 nq.setParameter(1, operation);
413                 nq.setParameter(2, target);
414
415                 int ret = -1;
416                 try{
417                         ret = ((Number)nq.getSingleResult()).intValue();
418                 }
419                 catch(NoResultException | NonUniqueResultException ex){
420                         logger.error("getCountFromDB threw: ", ex);
421                         return -1;
422                 }
423
424                 em.close();
425
426                 return ret;
427
428         }
429
430
431 }