X-Git-Url: https://gerrit.onap.org/r/gitweb?p=policy%2Fengine.git;a=blobdiff_plain;f=ONAP-XACML%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Fpolicy%2Fxacml%2Fstd%2Fpip%2Fengines%2FOperationHistoryEngine.java;h=bb7421e94788a1bb55a95708cd044d6a50ad9d2b;hp=355a6f644bc658548c0bf0bfb2d38e4fc914c457;hb=d089848fdb0beef8446bdcf60cdb14e4655a93e5;hpb=7bb6ef9ad8a483bdac3ff1544cd0910ecebe5a98 diff --git a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java index 355a6f644..bb7421e94 100644 --- a/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java +++ b/ONAP-XACML/src/main/java/org/onap/policy/xacml/std/pip/engines/OperationHistoryEngine.java @@ -2,14 +2,14 @@ * ============LICENSE_START======================================================= * ONAP-XACML * ================================================================================ - * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,22 +20,6 @@ package org.onap.policy.xacml.std.pip.engines; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Properties; -import java.util.Set; - -import javax.persistence.EntityManager; -import javax.persistence.Persistence; -import javax.persistence.Query; - -import org.eclipse.persistence.config.PersistenceUnitProperties; -import org.onap.policy.common.logging.flexlogger.FlexLogger; -import org.onap.policy.common.logging.flexlogger.Logger; - import com.att.research.xacml.api.Attribute; import com.att.research.xacml.api.AttributeValue; import com.att.research.xacml.api.Identifier; @@ -54,244 +38,210 @@ import com.att.research.xacml.std.pip.StdPIPResponse; import com.att.research.xacml.std.pip.engines.StdConfigurableEngine; import com.att.research.xacml.util.XACMLProperties; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Properties; +import java.util.Set; + +import javax.persistence.EntityManager; +import javax.persistence.Persistence; +import javax.persistence.Query; + +import org.eclipse.persistence.config.PersistenceUnitProperties; +import org.onap.policy.common.logging.flexlogger.FlexLogger; +import org.onap.policy.common.logging.flexlogger.Logger; + /** * PIP Engine for Implementing {@link com.att.research.xacml.std.pip.engines.ConfigurableEngine} interface to provide - * attribute retrieval from Operation History Table. - * + * attribute retrieval from Operation History Table. + * * @version $Revision$ */ -public class OperationHistoryEngine extends StdConfigurableEngine{ - public static final String DEFAULT_DESCRIPTION = "PIP for retrieving Operations History from DB"; - public static final String DEFAULT_ISSUER = "org:onap:xacml:guard:historydb"; - - private static final Logger LOGGER= FlexLogger.getLogger(OperationHistoryEngine.class); - - private static final PIPRequest PIP_REQUEST_ACTOR = new StdPIPRequest( - XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, - new IdentifierImpl("actor"), - XACML.ID_DATATYPE_STRING); - - private static final PIPRequest PIP_REQUEST_RECIPE = new StdPIPRequest( - XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, - new IdentifierImpl("recipe"), - XACML.ID_DATATYPE_STRING); - - private static final PIPRequest PIP_REQUEST_TARGET = new StdPIPRequest( - XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, - new IdentifierImpl("target"), - XACML.ID_DATATYPE_STRING); - - public OperationHistoryEngine() { - super(); - } - - private void addIntegerAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, int value, PIPRequest pipRequest) { - AttributeValue attributeValue = null; - try { - attributeValue = DataTypes.DT_INTEGER.createAttributeValue(value); - } catch (Exception ex) { - LOGGER.error("Failed to convert " + value + " to an AttributeValue", ex); - } - if (attributeValue != null) { - stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, pipRequest.getIssuer()/*this.getIssuer()*/, false)); - } - } - - @Override - public Collection attributesRequired() { - return new ArrayList<>(); - } - - @Override - public Collection attributesProvided() { - return new ArrayList<>(); - } - - @Override - public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException { - LOGGER.info("Entering FeqLimiter PIP"); - /* - * First check to see if the issuer is set and then match it - */ - String string; - if ((string = pipRequest.getIssuer()) == null) { - LOGGER.info("FeqLimiter PIP - No issuer in the request!"); - return StdPIPResponse.PIP_RESPONSE_EMPTY; - } - else{ - //Notice, we are checking here for the base issuer prefix. - if (!string.contains(this.getIssuer())) { - LOGGER.debug("Requested issuer '" + string + "' does not match " + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'")); - LOGGER.info("FeqLimiter PIP - Issuer "+ string +" does not match with: "+this.getIssuer()); - return StdPIPResponse.PIP_RESPONSE_EMPTY; - } - } - String[] s1 = string.split("tw:"); - String[] s2 = s1[1].split(":"); - int timeWindowVal = Integer.parseInt(s2[0]);// number [of minutes, hours, days...] - String timeWindowScale = s2[1];//e.g., minute, hour, day, week, month, year - String actor = getActor(pipFinder).iterator().next(); - String operation = getRecipe(pipFinder).iterator().next(); - String target = getTarget(pipFinder).iterator().next(); - String timeWindow = timeWindowVal + " " + timeWindowScale; - LOGGER.info("Going to query DB about: "+actor + " " + operation + " " + target + " " + timeWindow); - int countFromDB = getCountFromDB(actor, operation, target, timeWindowVal, timeWindowScale); - StdMutablePIPResponse stdPIPResponse = new StdMutablePIPResponse(); - this.addIntegerAttribute(stdPIPResponse, - XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, - new IdentifierImpl("count"), - countFromDB, - pipRequest); - return new StdPIPResponse(stdPIPResponse); - } - - @Override - public void configure(String id, Properties properties) throws PIPException { - super.configure(id, properties); - if (this.getDescription() == null) { - this.setDescription(DEFAULT_DESCRIPTION); - } - if (this.getIssuer() == null) { - this.setIssuer(DEFAULT_ISSUER); - } - } - - private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) { - PIPResponse pipResponse = null; - try { - pipResponse = pipFinder.getMatchingAttributes(pipRequest, this); - if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) { - LOGGER.info("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": " + pipResponse.getStatus().toString()); - pipResponse = null; - } - if (pipResponse!=null && pipResponse.getAttributes().isEmpty()) { - LOGGER.info("No value for " + pipRequest.getAttributeId().stringValue()); - pipResponse = null; - } - } catch (PIPException ex) { - LOGGER.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex); - } - return pipResponse; - } - - - private Set getActor(PIPFinder pipFinder) { - /* - * Get the AT&T UID from either the subject id or the attuid property - */ - PIPResponse pipResponseATTUID = this.getAttribute(PIP_REQUEST_ACTOR, pipFinder); - if (pipResponseATTUID == null) { - return new HashSet<>(); - } - /* - * Iterate over all of the returned results and do the LDAP requests - */ - Collection listATTUIDs = pipResponseATTUID.getAttributes(); - Set setATTUIDs = new HashSet<>(); - for (Attribute attributeATTUID: listATTUIDs) { - Iterator> iterAttributeValues = attributeATTUID.findValues(DataTypes.DT_STRING); - if (iterAttributeValues != null) { - while (iterAttributeValues.hasNext()) { - String attuid = iterAttributeValues.next().getValue(); - if (attuid != null) { - setATTUIDs.add(attuid); - } - } - } - } - return setATTUIDs; - } - - private Set getRecipe(PIPFinder pipFinder) { - /* - * Get the AT&T UID from either the subject id or the attuid property - */ - PIPResponse pipResponseATTUID = this.getAttribute(PIP_REQUEST_RECIPE, pipFinder); - if (pipResponseATTUID == null) { - return new HashSet<>(); - } - /* - * Iterate over all of the returned results and do the LDAP requests - */ - Collection listATTUIDs = pipResponseATTUID.getAttributes(); - Set setATTUIDs = new HashSet<>(); - for (Attribute attributeATTUID: listATTUIDs) { - Iterator> iterAttributeValues = attributeATTUID.findValues(DataTypes.DT_STRING); - if (iterAttributeValues != null) { - while (iterAttributeValues.hasNext()) { - String attuid = iterAttributeValues.next().getValue(); - if (attuid != null) { - setATTUIDs.add(attuid); - } - } - } - } - return setATTUIDs; - } - - - private Set getTarget(PIPFinder pipFinder) { - /* - * Get the AT&T UID from either the subject id or the attuid property - */ - PIPResponse pipResponseATTUID = this.getAttribute(PIP_REQUEST_TARGET, pipFinder); - if (pipResponseATTUID == null) { - return new HashSet<>(); - } - /* - * Iterate over all of the returned results and do the LDAP requests - */ - Collection listATTUIDs = pipResponseATTUID.getAttributes(); - Set setATTUIDs = new HashSet<>(); - for (Attribute attributeATTUID: listATTUIDs) { - Iterator> iterAttributeValues = attributeATTUID.findValues(DataTypes.DT_STRING); - if (iterAttributeValues != null) { - while (iterAttributeValues.hasNext()) { - String attuid = iterAttributeValues.next().getValue(); - if (attuid != null) { - setATTUIDs.add(attuid); - } - } - } - } - return setATTUIDs; - } - - private static int getCountFromDB(String actor, String operation, String target, int timeWindow, String timeUnits){ - EntityManager em; - try{ - Properties properties = XACMLProperties.getProperties(); - properties.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, "META-INF/operationHistoryPU.xml"); - em = Persistence.createEntityManagerFactory("OperationsHistoryPU",properties).createEntityManager(); - }catch(Exception e){ - LOGGER.error("Test thread got Exception " + e.getLocalizedMessage() + " Can't connect to Operations History DB.", e); - return -1; - } - // Preventing SQL injection - if(!validTimeUnits(timeUnits)){ - LOGGER.error("given PIP timeUnits is not valid. " + timeUnits); - em.close(); - return -1; - } - String sql = "select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=?" - + " and operation=?" - + " and target=?" - + " and endtime between date_sub(now(),interval ? "+timeUnits+") and now()"; - Query nq = em.createNativeQuery(sql); - nq.setParameter(1, actor); - nq.setParameter(2, operation); - nq.setParameter(3, target); - nq.setParameter(4, timeWindow); - int ret = ((Number)nq.getSingleResult()).intValue(); - LOGGER.info("###########************** History count: " + ret); - em.close(); - return ret; - } - - // Validating Time Units to prevent SQL Injection. - private static boolean validTimeUnits(String timeUnits) { - return ("minute".equalsIgnoreCase(timeUnits) || "hour".equalsIgnoreCase(timeUnits) || "day".equalsIgnoreCase(timeUnits) - || "week".equalsIgnoreCase(timeUnits) || "month".equalsIgnoreCase(timeUnits)|| "year".equalsIgnoreCase(timeUnits))? - true: false; - } +public class OperationHistoryEngine extends StdConfigurableEngine { + public static final String DEFAULT_DESCRIPTION = "PIP for retrieving Operations History from DB"; + public static final String DEFAULT_ISSUER = "org:onap:xacml:guard:historydb"; + + private static final Logger LOGGER = FlexLogger.getLogger(OperationHistoryEngine.class); + + private static final PIPRequest PIP_REQUEST_ACTOR = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + new IdentifierImpl("actor"), XACML.ID_DATATYPE_STRING); + + private static final PIPRequest PIP_REQUEST_RECIPE = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + new IdentifierImpl("recipe"), XACML.ID_DATATYPE_STRING); + + private static final PIPRequest PIP_REQUEST_TARGET = new StdPIPRequest(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, + new IdentifierImpl("target"), XACML.ID_DATATYPE_STRING); + + public OperationHistoryEngine() { + super(); + } + + private void addIntegerAttribute(StdMutablePIPResponse stdPipResponse, Identifier category, Identifier attributeId, + int value, PIPRequest pipRequest) { + AttributeValue attributeValue = null; + try { + attributeValue = DataTypes.DT_INTEGER.createAttributeValue(value); + } catch (Exception ex) { + LOGGER.error("Failed to convert " + value + " to an AttributeValue", ex); + } + if (attributeValue != null) { + stdPipResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, + pipRequest.getIssuer()/* this.getIssuer() */, false)); + } + } + + @Override + public Collection attributesRequired() { + return new ArrayList<>(); + } + + @Override + public Collection attributesProvided() { + return new ArrayList<>(); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException { + LOGGER.info("Entering FeqLimiter PIP"); + /* + * First check to see if the issuer is set and then match it + */ + String string; + if ((string = pipRequest.getIssuer()) == null) { + LOGGER.info("FeqLimiter PIP - No issuer in the request!"); + return StdPIPResponse.PIP_RESPONSE_EMPTY; + } else { + // Notice, we are checking here for the base issuer prefix. + if (!string.contains(this.getIssuer())) { + LOGGER.debug("Requested issuer '" + string + "' does not match " + + (this.getIssuer() == null ? "null" : "'" + this.getIssuer() + "'")); + LOGGER.info("FeqLimiter PIP - Issuer " + string + " does not match with: " + this.getIssuer()); + return StdPIPResponse.PIP_RESPONSE_EMPTY; + } + } + String[] s1 = string.split("tw:"); + String[] s2 = s1[1].split(":"); + int timeWindowVal = Integer.parseInt(s2[0]);// number [of minutes, hours, days...] + String timeWindowScale = s2[1];// e.g., minute, hour, day, week, month, year + String actor = getActor(pipFinder).iterator().next(); + String operation = getRecipe(pipFinder).iterator().next(); + String target = getTarget(pipFinder).iterator().next(); + String timeWindow = timeWindowVal + " " + timeWindowScale; + LOGGER.info("Going to query DB about: " + actor + " " + operation + " " + target + " " + timeWindow); + int countFromDB = getCountFromDB(actor, operation, target, timeWindowVal, timeWindowScale); + StdMutablePIPResponse stdPipResponse = new StdMutablePIPResponse(); + this.addIntegerAttribute(stdPipResponse, XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, new IdentifierImpl("count"), + countFromDB, pipRequest); + return new StdPIPResponse(stdPipResponse); + } + + @Override + public void configure(String id, Properties properties) throws PIPException { + super.configure(id, properties); + if (this.getDescription() == null) { + this.setDescription(DEFAULT_DESCRIPTION); + } + if (this.getIssuer() == null) { + this.setIssuer(DEFAULT_ISSUER); + } + } + + private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) { + PIPResponse pipResponse = null; + try { + pipResponse = pipFinder.getMatchingAttributes(pipRequest, this); + if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) { + LOGGER.info("Error retrieving " + pipRequest.getAttributeId().stringValue() + ": " + + pipResponse.getStatus().toString()); + pipResponse = null; + } + if (pipResponse != null && pipResponse.getAttributes().isEmpty()) { + LOGGER.info("No value for " + pipRequest.getAttributeId().stringValue()); + pipResponse = null; + } + } catch (PIPException ex) { + LOGGER.error("PIPException getting subject-id attribute: " + ex.getMessage(), ex); + } + return pipResponse; + } + + private Set getActor(PIPFinder pipFinder) { + return getUuids(this.getAttribute(PIP_REQUEST_ACTOR, pipFinder)); + } + + private Set getRecipe(PIPFinder pipFinder) { + return getUuids(this.getAttribute(PIP_REQUEST_RECIPE, pipFinder)); + } + + private Set getTarget(PIPFinder pipFinder) { + return getUuids(this.getAttribute(PIP_REQUEST_TARGET, pipFinder)); + } + + private Set getUuids(PIPResponse pipResponseAttUid) { + /* + * Get the UID from either the subject id or the attuid property + */ + if (pipResponseAttUid == null) { + return new HashSet<>(); + } + /* + * Iterate over all of the returned results and do the LDAP requests + */ + Set setAttUids = new HashSet<>(); + for (Attribute attributeAttUid : pipResponseAttUid.getAttributes()) { + Iterator> iterAttributeValues = attributeAttUid.findValues(DataTypes.DT_STRING); + if (iterAttributeValues != null) { + while (iterAttributeValues.hasNext()) { + String attuid = iterAttributeValues.next().getValue(); + if (attuid != null) { + setAttUids.add(attuid); + } + } + } + } + return setAttUids; + } + + private static int getCountFromDB(String actor, String operation, String target, int timeWindow, String timeUnits) { + EntityManager em; + try { + Properties properties = XACMLProperties.getProperties(); + properties.setProperty(PersistenceUnitProperties.ECLIPSELINK_PERSISTENCE_XML, + "META-INF/operationHistoryPU.xml"); + em = Persistence.createEntityManagerFactory("OperationsHistoryPU", properties).createEntityManager(); + } catch (Exception e) { + LOGGER.error( + "Test thread got Exception " + e.getLocalizedMessage() + " Can't connect to Operations History DB.", + e); + return -1; + } + // Preventing SQL injection + if (!validTimeUnits(timeUnits)) { + LOGGER.error("given PIP timeUnits is not valid. " + timeUnits); + em.close(); + return -1; + } + String sql = "select count(*) as count from operationshistory10 where outcome<>'Failure_Guard' and actor=?" + + " and operation=?" + " and target=?" + " and endtime between date_sub(now(),interval ? " + timeUnits + + ") and now()"; + Query nq = em.createNativeQuery(sql); + nq.setParameter(1, actor); + nq.setParameter(2, operation); + nq.setParameter(3, target); + nq.setParameter(4, timeWindow); + int ret = ((Number) nq.getSingleResult()).intValue(); + LOGGER.info("###########************** History count: " + ret); + em.close(); + return ret; + } + + // Validating Time Units to prevent SQL Injection. + private static boolean validTimeUnits(String timeUnits) { + return ("minute".equalsIgnoreCase(timeUnits) || "hour".equalsIgnoreCase(timeUnits) + || "day".equalsIgnoreCase(timeUnits) || "week".equalsIgnoreCase(timeUnits) + || "month".equalsIgnoreCase(timeUnits) || "year".equalsIgnoreCase(timeUnits)) ? true : false; + } }