diff options
25 files changed, 1788 insertions, 762 deletions
diff --git a/controlloop/common/guard/pom.xml b/controlloop/common/guard/pom.xml index f41328438..94b337d9f 100644 --- a/controlloop/common/guard/pom.xml +++ b/controlloop/common/guard/pom.xml @@ -22,7 +22,7 @@ <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> - <scope>provided</scope> + <scope>test</scope> </dependency> <dependency> <groupId>commons-io</groupId> diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java index d81aaa40c..9e3116dd8 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/CallGuardTask.java @@ -23,16 +23,14 @@ package org.onap.policy.guard; import java.util.UUID; import org.drools.core.WorkingMemory; -import org.onap.policy.drools.system.PolicyEngine; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.att.research.xacml.api.DataTypeException; import com.att.research.xacml.std.annotations.RequestParser; - public class CallGuardTask implements Runnable { - + private static final Logger logger = LoggerFactory.getLogger(CallGuardTask.class); WorkingMemory workingMemory; String restfulPdpUrl; @@ -41,40 +39,39 @@ public class CallGuardTask implements Runnable { String recipe; String target; String requestId; - + /* * Guard url is grabbed from PolicyEngine.manager properties */ - public CallGuardTask(WorkingMemory wm, String cl, String act, String rec, String tar, String reqId) { - workingMemory = wm; - clname = cl; - actor = act; - recipe = rec; - requestId = reqId; - target = tar; - } - - @Override - public void run() { - long startTime = System.nanoTime(); - com.att.research.xacml.api.Request request = null; - - PolicyGuardXacmlRequestAttributes xacmlReq = new PolicyGuardXacmlRequestAttributes(clname, actor, recipe, target, requestId); - - try { - request = RequestParser.parseRequest(xacmlReq); + public CallGuardTask(WorkingMemory wm, String cl, String act, String rec, String tar, String reqId) { + workingMemory = wm; + clname = cl; + actor = act; + recipe = rec; + requestId = reqId; + target = tar; + } + + @Override + public void run() { + long startTime = System.nanoTime(); + com.att.research.xacml.api.Request request = null; + + PolicyGuardXacmlRequestAttributes xacmlReq = new PolicyGuardXacmlRequestAttributes(clname, actor, recipe, target, requestId); + + try { + request = RequestParser.parseRequest(xacmlReq); } catch (IllegalArgumentException | IllegalAccessException | DataTypeException e) { logger.error("CallGuardTask.run threw: {}", e); } - - - logger.debug("\n********** XACML REQUEST START ********"); + + + logger.debug("\n********** XACML REQUEST START ********"); logger.debug("{}", request); logger.debug("********** XACML REQUEST END ********\n"); - - String guardUrl = PolicyEngine.manager.getEnvironmentProperty(Util.PROP_GUARD_URL); + String guardDecision = null; - + // // Make guard request // @@ -94,20 +91,20 @@ public class CallGuardTask implements Runnable { PolicyGuardResponse guardResponse = new PolicyGuardResponse(guardDecision, UUID.fromString(this.requestId), this.recipe); - + // //Create an artificial Guard response in case we didn't get a clear Permit or Deny // - if(guardResponse.result.equals("Indeterminate")){ - guardResponse.operation = recipe; - guardResponse.requestID = UUID.fromString(requestId); + if(guardResponse.getResult().equals("Indeterminate")){ + guardResponse.setOperation(recipe); + guardResponse.setRequestID(UUID.fromString(requestId)); } - + long estimatedTime = System.nanoTime() - startTime; logger.debug("\n\n============ Guard inserted with decision {} !!! =========== time took: {} mili sec \n\n", - guardResponse.result, (double)estimatedTime/1000/1000); + guardResponse.getResult(), (double)estimatedTime/1000/1000); workingMemory.insert(guardResponse); - } + } } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/GuardResult.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/GuardResult.java index 4afd16dab..b2792858a 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/GuardResult.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/GuardResult.java @@ -24,5 +24,4 @@ public enum GuardResult { LOCK_DENIED, LOCK_EXCEPTION ; - } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PIPEngineGetHistory.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PIPEngineGetHistory.java index 6ba1a5a5f..bfdff4d7f 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PIPEngineGetHistory.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PIPEngineGetHistory.java @@ -55,89 +55,57 @@ import com.att.research.xacml.std.pip.StdPIPRequest; import com.att.research.xacml.std.pip.StdPIPResponse; import com.att.research.xacml.std.pip.engines.StdConfigurableEngine; - - public class PIPEngineGetHistory extends StdConfigurableEngine{ - - private interface DateUtil{ - public class DateUtilException extends Exception { - private static final long serialVersionUID = 2612662650481443076L; - - public DateUtilException(String message) { - super(message); - } - - } - - public long getMs(); - public DateUtil init(String sqlValUnit) throws DateUtilException; - } - private static final Logger logger = LoggerFactory.getLogger(PIPEngineGetHistory.class); - public static final String DEFAULT_DESCRIPTION = "PIP for retrieving Operations History from DB"; - - - // // Base issuer string. The issuer in the policy will also contain time window information // E.g., "com:att:research:xacml:guard:historydb:tw:10:min" // - public static final String DEFAULT_ISSUER = "com:att:research:xacml:guard:historydb"; + public static final String DEFAULT_ISSUER = "com:att:research:xacml:guard:historydb"; + public static final String DEFAULT_DESCRIPTION = "PIP for retrieving Operations History from DB"; + + private static final String XML_SCHEMA_STRING = "http://www.w3.org/2001/XMLSchema#string"; + private static final String XACML_SUBJECT_CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"; + private static final String XACML_ACTOR_ACTOR_ID = "urn:oasis:names:tc:xacml:1.0:actor:actor-id"; + private static final String XACML_ATTRIBUTE_CATEGORY_ACTION ="urn:oasis:names:tc:xacml:3.0:attribute-category:action"; + private static final String XACML_OPERATION_OPERATION_ID ="urn:oasis:names:tc:xacml:1.0:operation:operation-id"; + private static final String XACML_ATTRIBUTE_CATEGORY_RESOURCE ="urn:oasis:names:tc:xacml:3.0:attribute-category:resource"; + private static final String XACML_TARGET_TARGET_ID ="urn:oasis:names:tc:xacml:1.0:target:target-id"; + private static final String XACML_TEST_SQL_RESOURCE_OPERATIONS_COUNT = "com:att:research:xacml:test:sql:resource:operations:count"; private static final PIPRequest PIP_REQUEST_ACTOR = new StdPIPRequest( - new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:subject-category:access-subject"), - new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:actor:actor-id"), - new IdentifierImpl("http://www.w3.org/2001/XMLSchema#string")); + new IdentifierImpl(XACML_SUBJECT_CATEGORY_ACCESS_SUBJECT), + new IdentifierImpl(XACML_ACTOR_ACTOR_ID), + new IdentifierImpl(XML_SCHEMA_STRING)); private static final PIPRequest PIP_REQUEST_RECIPE = new StdPIPRequest( - new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:action"), - new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:operation:operation-id"), - new IdentifierImpl("http://www.w3.org/2001/XMLSchema#string")); + new IdentifierImpl(XACML_ATTRIBUTE_CATEGORY_ACTION), + new IdentifierImpl(XACML_OPERATION_OPERATION_ID), + new IdentifierImpl(XML_SCHEMA_STRING)); private static final PIPRequest PIP_REQUEST_TARGET = new StdPIPRequest( - new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"), - new IdentifierImpl("urn:oasis:names:tc:xacml:1.0:target:target-id"), - new IdentifierImpl("http://www.w3.org/2001/XMLSchema#string")); - - - private void addIntegerAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, int value, PIPRequest pipRequest) { - AttributeValue<BigInteger> attributeValue = null; - try { - attributeValue = DataTypes.DT_INTEGER.createAttributeValue(value); - } catch (Exception ex) { - logger.error("Failed to convert {} to an AttributeValue<Boolean>",value, ex); - } - if (attributeValue != null) { - stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, pipRequest.getIssuer()/*this.getIssuer()*/, false)); - } - } - - + new IdentifierImpl(XACML_ATTRIBUTE_CATEGORY_RESOURCE), + new IdentifierImpl(XACML_TARGET_TARGET_ID), + new IdentifierImpl(XML_SCHEMA_STRING)); public PIPEngineGetHistory() { super(); - // TODO Auto-generated constructor stub } - - @Override public Collection<PIPRequest> attributesRequired() { - // TODO Auto-generated method stub - return Collections.emptySet(); + return Collections.emptySet(); } @Override public Collection<PIPRequest> attributesProvided() { - // TODO Auto-generated method stub - return Collections.emptySet(); + return Collections.emptySet(); } @Override public PIPResponse getAttributes(PIPRequest pipRequest, PIPFinder pipFinder) throws PIPException { - // TODO Auto-generated method stub logger.debug("Entering FeqLimiter PIP"); /* @@ -164,9 +132,17 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ String timeWindowVal = 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 actor = null; + String operation = null; + String target = null; + try { + actor = getActor(pipFinder).iterator().next(); + operation = getRecipe(pipFinder).iterator().next(); + target = getTarget(pipFinder).iterator().next(); + } catch (Exception e) { + logger.debug("could not retrieve actor, operation, or target from PIP finder"); + return StdPIPResponse.PIP_RESPONSE_EMPTY; + } String timeWindow = timeWindowVal + " " + timeWindowScale; @@ -176,15 +152,14 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ StdMutablePIPResponse stdPIPResponse = new StdMutablePIPResponse(); this.addIntegerAttribute(stdPIPResponse, - new IdentifierImpl("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"), - new IdentifierImpl("com:att:research:xacml:test:sql:resource:operations:count"), + new IdentifierImpl(XACML_ATTRIBUTE_CATEGORY_RESOURCE), + new IdentifierImpl(XACML_TEST_SQL_RESOURCE_OPERATIONS_COUNT), countFromDB, pipRequest); return new StdPIPResponse(stdPIPResponse); } - @Override public void configure(String id, Properties properties) throws PIPException { super.configure(id, properties); @@ -197,8 +172,6 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ } } - - private PIPResponse getAttribute(PIPRequest pipRequest, PIPFinder pipFinder) { PIPResponse pipResponse = null; @@ -212,36 +185,34 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ return null; } if (pipResponse.getStatus() != null && !pipResponse.getStatus().isOk()) { - logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus().toString()); - return null; - } - if (pipResponse.getAttributes() != null && pipResponse.getAttributes().isEmpty()) { - logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus().toString()); - logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus()); + if (logger.isWarnEnabled()) { + logger.warn("PIP response error {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus().toString()); + } return null; } if (pipResponse.getAttributes() != null && pipResponse.getAttributes().isEmpty()) { - logger.warn("Error retrieving {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus()); + if (logger.isWarnEnabled()) { + logger.warn("No attributes in POP response {}: {}", pipRequest.getAttributeId().stringValue(), pipResponse.getStatus().toString()); + } return null; } return pipResponse; } - private Set<String> 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 null; + return new HashSet<>(); } /* * Iterate over all of the returned results and do the LDAP requests */ Collection<Attribute> listATTUIDs = pipResponseATTUID.getAttributes(); - Set<String> setATTUIDs = new HashSet<String>(); + Set<String> setATTUIDs = new HashSet<>(); for (Attribute attributeATTUID: listATTUIDs) { Iterator<AttributeValue<String>> iterAttributeValues = attributeATTUID.findValues(DataTypes.DT_STRING); if (iterAttributeValues != null) { @@ -261,16 +232,16 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ /* * Get the AT&T UID from either the subject id or the attuid property */ - PIPResponse pipResponseATTUID = this.getAttribute(PIP_REQUEST_RECIPE, pipFinder); + PIPResponse pipResponseATTUID = this.getAttribute(PIP_REQUEST_RECIPE, pipFinder); if (pipResponseATTUID == null) { - return null; + return new HashSet<>(); } /* * Iterate over all of the returned results and do the LDAP requests */ Collection<Attribute> listATTUIDs = pipResponseATTUID.getAttributes(); - Set<String> setATTUIDs = new HashSet<String>(); + Set<String> setATTUIDs = new HashSet<>(); for (Attribute attributeATTUID: listATTUIDs) { Iterator<AttributeValue<String>> iterAttributeValues = attributeATTUID.findValues(DataTypes.DT_STRING); if (iterAttributeValues != null) { @@ -286,6 +257,17 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ return setATTUIDs; } + private void addIntegerAttribute(StdMutablePIPResponse stdPIPResponse, Identifier category, Identifier attributeId, int value, PIPRequest pipRequest) { + AttributeValue<BigInteger> attributeValue = null; + try { + attributeValue = DataTypes.DT_INTEGER.createAttributeValue(value); + } catch (Exception ex) { + logger.error("Failed to convert {} to an AttributeValue<Boolean>",value, ex); + } + if (attributeValue != null) { + stdPIPResponse.addAttribute(new StdMutableAttribute(category, attributeId, attributeValue, pipRequest.getIssuer()/*this.getIssuer()*/, false)); + } + } private Set<String> getTarget(PIPFinder pipFinder) { /* @@ -293,14 +275,14 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ */ PIPResponse pipResponseATTUID = this.getAttribute(PIP_REQUEST_TARGET, pipFinder); if (pipResponseATTUID == null) { - return null; + return new HashSet<>(); } /* * Iterate over all of the returned results and do the LDAP requests */ Collection<Attribute> listATTUIDs = pipResponseATTUID.getAttributes(); - Set<String> setATTUIDs = new HashSet<String>(); + Set<String> setATTUIDs = new HashSet<>(); for (Attribute attributeATTUID: listATTUIDs) { Iterator<AttributeValue<String>> iterAttributeValues = attributeATTUID.findValues(DataTypes.DT_STRING); if (iterAttributeValues != null) { @@ -317,101 +299,57 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ } private static int getCountFromDB(String actor, String operation, String target, String timeWindow){ - // DB Properties Properties props = new Properties(); props.put(Util.ECLIPSE_LINK_KEY_URL, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_URL)); props.put(Util.ECLIPSE_LINK_KEY_USER, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_USER)); props.put(Util.ECLIPSE_LINK_KEY_PASS, PolicyEngine.manager.getEnvironmentProperty(Util.ONAP_KEY_PASS)); - + EntityManager em = null; - String OpsHistPU = System.getProperty("OperationsHistoryPU"); - if(OpsHistPU == null || !OpsHistPU.equals("TestOperationsHistoryPU")){ - OpsHistPU = "OperationsHistoryPU"; + String opsHistPU = System.getProperty("OperationsHistoryPU"); + if (opsHistPU == null || !opsHistPU.equals("TestOperationsHistoryPU")){ + opsHistPU = "OperationsHistoryPU"; } - else{ + else { props.clear(); } - try{ - em = Persistence.createEntityManagerFactory(OpsHistPU, props).createEntityManager(); - }catch(Exception ex){ - logger.error("PIP thread got Exception. Can't connect to Operations History DB -- {}", OpsHistPU); + + try { + em = Persistence.createEntityManagerFactory(opsHistPU, props).createEntityManager(); + } catch(Exception ex){ + logger.error("PIP thread got Exception. Can't connect to Operations History DB -- {}", opsHistPU); logger.error("getCountFromDB threw: ", ex); return -1; } - DateUtil dateUtil = new DateUtil(){ - private long ms = 0; - private double multiplier = 0; - - @Override - public DateUtil init(String sqlValUnit) throws DateUtilException{ - String[] split = sqlValUnit.split(" "); - if(split.length != 2){ - throw new DateUtilException("Invalid Value Unit pair for SQL"); - } - - ms = Long.parseLong(split[0]); - - if("SECOND".compareToIgnoreCase(split[1]) == 0){ - multiplier = 1000; - } - else if("MINUTE".compareToIgnoreCase(split[1]) == 0){ - multiplier = 60000; - } - else if("HOUR".compareToIgnoreCase(split[1]) == 0){ - multiplier = 3.6e+6; - } - else if("DAY".compareToIgnoreCase(split[1]) == 0){ - multiplier = 8.64e+7; - } - else if("WEEK".compareToIgnoreCase(split[1]) == 0){ - multiplier = 6.048e+8; - } - else if("MONTH".compareToIgnoreCase(split[1]) == 0){ - multiplier = 2.628e+9; - } - else if("QUARTER".compareToIgnoreCase(split[1]) == 0){ - multiplier = 2.628e+9 * 3; - } - else if("YEAR".compareToIgnoreCase(split[1]) == 0){ - multiplier = 3.154e+10; - } - else{ - logger.error("{} not supported", split[1]); - } - - ms *= multiplier; - return this; - } - public long getMs(){ - return ms; - } - }; - long now = new Date().getTime(); long diff; try { - diff = now - dateUtil.init(timeWindow).getMs(); + diff = now - getMSFromTimeWindow(timeWindow); } catch (Exception ex) { logger.error("PIP thread got Exception " + ex); return -1; } - String sql = "select count(*) as count from operationshistory10 where outcome<>'Failure_Guard'" - + " and actor= ?" - + " and operation= ?" - + " and target= ?" - + " and endtime between '" + new Timestamp(diff) + "' and '" + new Timestamp(now) + "'"; - - Query nq = em.createNativeQuery(sql); + StringBuilder sqlBuilder = new StringBuilder(); + sqlBuilder.append("select count(*) as count from operationshistory10 where outcome<>'Failure_Guard'"); + sqlBuilder.append(" and actor= ?"); + sqlBuilder.append(" and operation= ?"); + sqlBuilder.append(" and target= ?"); + sqlBuilder.append(" and endtime between '"); + sqlBuilder.append(new Timestamp(diff)); + sqlBuilder.append("' and '"); + sqlBuilder.append(new Timestamp(now)); + sqlBuilder.append('\''); + + Query nq = em.createNativeQuery(sqlBuilder.toString()); nq.setParameter(1, actor); nq.setParameter(2, operation); nq.setParameter(3, target); int ret = -1; - try{ + try { ret = ((Number)nq.getSingleResult()).intValue(); } catch(NoResultException | NonUniqueResultException ex){ @@ -422,8 +360,54 @@ public class PIPEngineGetHistory extends StdConfigurableEngine{ em.close(); return ret; - } + /** + * Get the Millisecond time from a time window string + * @param timeWindow the time window string to parse + * @return the millisecond time from the time window string + * @throws PIPException On invalid time window strings + */ + private static long getMSFromTimeWindow(String timeWindowString) throws PIPException { + long ms = 0; + double multiplier = 0; + + String[] split = timeWindowString.split(" "); + if (split.length != 2) { + throw new PIPException("Invalid Value Unit pair for SQL"); + } + + ms = Long.parseLong(split[0]); + + if("SECOND".compareToIgnoreCase(split[1]) == 0){ + multiplier = 1000; + } + else if("MINUTE".compareToIgnoreCase(split[1]) == 0){ + multiplier = 60000; + } + else if("HOUR".compareToIgnoreCase(split[1]) == 0){ + multiplier = 3.6e+6; + } + else if("DAY".compareToIgnoreCase(split[1]) == 0){ + multiplier = 8.64e+7; + } + else if("WEEK".compareToIgnoreCase(split[1]) == 0){ + multiplier = 6.048e+8; + } + else if("MONTH".compareToIgnoreCase(split[1]) == 0){ + multiplier = 2.628e+9; + } + else if("QUARTER".compareToIgnoreCase(split[1]) == 0){ + multiplier = 2.628e+9 * 3; + } + else if("YEAR".compareToIgnoreCase(split[1]) == 0){ + multiplier = 3.154e+10; + } + else{ + logger.error("{} not supported", split[1]); + } + ms *= multiplier; + return ms; + } } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java index b35ec5a9f..c23dc35cd 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuard.java @@ -31,15 +31,19 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PolicyGuard { - - private static Map<String, TargetLock> activeLocks = new HashMap<String, TargetLock>(); + private PolicyGuard() { + // Cannot instantiate this static class + } + + private static Map<String, TargetLock> activeLocks = new HashMap<>(); private static final Logger logger = LoggerFactory.getLogger(PolicyGuard.class); + public static class LockResult<A, B> { private A a; private B b; public static <A, B> LockResult<A, B> createLockResult(A a, B b) { - return new LockResult<A, B>(a, b); + return new LockResult<>(a, b); } public LockResult(A a, B b) { @@ -101,7 +105,7 @@ public class PolicyGuard { } } - public static boolean unlockTarget(TargetLock lock) { + public static boolean unlockTarget(TargetLock lock) { synchronized(activeLocks) { if (activeLocks.containsKey(lock.getTargetInstance())) { logger.debug("Unlocking {}", lock); @@ -111,7 +115,7 @@ public class PolicyGuard { } } - public static boolean isLocked(TargetType targetType, String targetInstance, UUID requestID) { + public static boolean isLocked(TargetType targetType, String targetInstance, UUID requestID) { synchronized(activeLocks) { if (activeLocks.containsKey(targetInstance)) { TargetLock lock = activeLocks.get(targetInstance); @@ -120,5 +124,4 @@ public class PolicyGuard { return false; } } - } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java index 04732dc36..20c9665ce 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardRequest.java @@ -22,8 +22,12 @@ package org.onap.policy.guard; import java.util.UUID; -public class PolicyGuardRequest{ - +public class PolicyGuardRequest { + private String actor; + private String target; + private UUID requestID; + private String operation; + public PolicyGuardRequest(String actor, String target, UUID requestID, String operation) { super(); this.actor = actor; @@ -31,16 +35,42 @@ public class PolicyGuardRequest{ this.requestID = requestID; this.operation = operation; } - public String actor; - public String target; - public UUID requestID; - public String operation; - @Override public String toString() { return "PolicyGuardRequest [actor=" + actor + ", target=" + target + ", requestID=" + requestID + ", operation=" + operation + "]"; } - + + public String getActor() { + return actor; + } + + public void setActor(String actor) { + this.actor = actor; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public UUID getRequestID() { + return requestID; + } + + public void setRequestID(UUID requestID) { + this.requestID = requestID; + } + + public String getOperation() { + return operation; + } + + public void setOperation(String operation) { + this.operation = operation; + } }
\ No newline at end of file diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java index 20bbc2eb6..110fbe0ab 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardResponse.java @@ -23,23 +23,21 @@ package org.onap.policy.guard; import java.util.UUID; public class PolicyGuardResponse{ - public PolicyGuardResponse(String string, UUID req, String op) { - this.result = string; + private UUID requestID; + private String operation; + private String result; + + public PolicyGuardResponse(String result, UUID req, String op) { + this.result = result; this.requestID = req; this.operation = op; } - public UUID requestID; - public String operation; - public String result; - - - - @Override public String toString() { return "PolicyGuardResponse [requestID=" + requestID + ", operation=" + operation + ", result=" + result + "]"; } + public UUID getRequestID() { return requestID; } @@ -52,5 +50,10 @@ public class PolicyGuardResponse{ public void setResult(String result) { this.result = result; } - + public String getOperation() { + return operation; + } + public void setOperation(String operation) { + this.operation = operation; + } }
\ No newline at end of file diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java index cbaa8edde..a81da89d7 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlHelper.java @@ -20,10 +20,9 @@ package org.onap.policy.guard; -import java.io.BufferedReader; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Serializable; import java.net.HttpURLConnection; @@ -48,12 +47,12 @@ import com.att.research.xacml.api.Result; public class PolicyGuardXacmlHelper { - - private static final Logger logger = LoggerFactory - .getLogger(PolicyGuardXacmlHelper.class); - + private static final Logger logger = LoggerFactory.getLogger(PolicyGuardXacmlHelper.class); private static final Logger netLogger = LoggerFactory.getLogger(org.onap.policy.drools.event.comm.Topic.NETWORK_LOGGER); + // Constant for the systme line separator + private static final String SYSTEM_LS = System.lineSeparator(); + public PolicyGuardXacmlHelper() { init(PolicyEngine.manager.getEnvironment()); } @@ -63,12 +62,14 @@ public class PolicyGuardXacmlHelper { // 'Authorization' header entry. 'restUrlIndex' indicates the next // entry to try -- after each failure, the index is advanced to the // next entry (wrapping to the beginning, if needed). - static private class URLEntry implements Serializable { + private static class URLEntry implements Serializable { + private static final long serialVersionUID = -8859237552195400518L; + URL restURL; String authorization = null; String clientAuth = null; String environment = null; - }; + } private URLEntry[] restUrls = null; private int restUrlIndex = 0; @@ -76,14 +77,6 @@ public class PolicyGuardXacmlHelper { // REST timeout, initialized from 'pdpx.timeout' property private int timeout = 20000; - - // initialized from 'guard.disabled', but may also be set to 'true' if - // there is an initialization error - private boolean disabled = false; - - // errors that forced 'disabled' to be set to 'true' - private String errorMessage = null; - public String callPDP(PolicyGuardXacmlRequestAttributes xacmlReq) { // // Send it to the PDP @@ -94,11 +87,11 @@ public class PolicyGuardXacmlHelper { // Build the json request // JSONObject attributes = new JSONObject(); - attributes.put("actor", xacmlReq.getActor_id()); - attributes.put("recipe", xacmlReq.getOperation_id()); - attributes.put("target", xacmlReq.getTarget_id()); - if (xacmlReq.getClname_id() != null) { - attributes.put("clname", xacmlReq.getClname_id()); + attributes.put("actor", xacmlReq.getActorID()); + attributes.put("recipe", xacmlReq.getOperationID()); + attributes.put("target", xacmlReq.getTargetID()); + if (xacmlReq.getClnameID() != null) { + attributes.put("clname", xacmlReq.getClnameID()); } JSONObject jsonReq = new JSONObject(); jsonReq.put("decisionAttributes", attributes); @@ -110,12 +103,13 @@ public class PolicyGuardXacmlHelper { // Call RESTful PDP // URLEntry urlEntry = restUrls[restUrlIndex]; - netLogger.info("[OUT|{}|{}|]{}{}", "GUARD", urlEntry.restURL, System.lineSeparator(), jsonReq.toString()); + String jsonRequestString = jsonReq.toString(); + netLogger.info("[OUT|{}|{}|]{}{}", "GUARD", urlEntry.restURL, SYSTEM_LS, jsonRequestString); response = callRESTfulPDP(new ByteArrayInputStream(jsonReq .toString().getBytes()), urlEntry.restURL, urlEntry.authorization, urlEntry.clientAuth, urlEntry.environment); - netLogger.info("[IN|{}|{}|]{}{}", "GUARD", urlEntry.restURL, System.lineSeparator(), response); + netLogger.info("[IN|{}|{}|]{}{}", "GUARD", urlEntry.restURL, SYSTEM_LS, response); } catch (Exception e) { logger.error("Error in sending RESTful request: ", e); } @@ -130,13 +124,10 @@ public class PolicyGuardXacmlHelper { * @param file * @return response from guard which contains "Permit" or "Deny" */ - private String callRESTfulPDP(InputStream is, URL restURL, - String authorization, String clientauth, String environment) { - String response = null; - String rawDecision = null; + private String callRESTfulPDP(InputStream is, URL restURL, String authorization, String clientauth, String environment) { HttpURLConnection connection = null; - try { + try { // // Open up the connection // @@ -175,85 +166,46 @@ public class PolicyGuardXacmlHelper { try (OutputStream os = connection.getOutputStream()) { IOUtils.copy(is, os); } + // // Do the connect // connection.connect(); - if (connection.getResponseCode() == 200) { - // - // Read the response - // - ContentType contentType = null; - try { - contentType = ContentType - .parse(connection.getContentType()); - - if (contentType.getMimeType().equalsIgnoreCase( - ContentType.APPLICATION_JSON.getMimeType())) { - InputStream iStream = connection.getInputStream(); - int contentLength = connection.getContentLength(); - - // if content length is -1, respose is chunked, and - // TCP connection will be dropped at the end - byte[] buf = new byte[contentLength < 0 ? 1024 - : contentLength]; - int offset = 0; - for (;;) { - if (offset == contentLength) { - // all expected bytes have been read - response = new String(buf); - break; - } - int size = iStream.read(buf, offset, buf.length - - offset); - if (size < 0) { - if (contentLength > 0) { - logger.error("partial input stream"); - } else { - // chunked response -- - // dropped connection is expected - response = new String(buf, 0, offset); - } - break; - } - offset += size; - } - } else { - logger.error("unknown content-type: " + contentType); - } - - } catch (Exception e) { - String message = "Parsing Content-Type: " - + connection.getContentType(); - logger.error(message, e); - } - } else { - logger.error(connection.getResponseCode() + " " - + connection.getResponseMessage()); + if (connection.getResponseCode() != 200) { + logger.error(connection.getResponseCode() + " " + connection.getResponseMessage()); + return Util.INDETERMINATE; } } catch (Exception e) { - logger.error( - "Exception in 'PolicyGuardXacmlHelper.callRESTfulPDP'", e); + logger.error("Exception in 'PolicyGuardXacmlHelper.callRESTfulPDP'", e); + return Util.INDETERMINATE; } - + // - // Connection may have failed or not been 200 OK, return Indeterminate + // Read the response // - if(response == null || response.isEmpty()){ + try { + ContentType contentType = ContentType.parse(connection.getContentType()); + + if (contentType.getMimeType().equalsIgnoreCase(ContentType.APPLICATION_JSON.getMimeType())) { + InputStream iStream = connection.getInputStream(); + int contentLength = connection.getContentLength(); + + return readResponseFromStream(iStream, contentLength); + } else { + logger.error("unknown content-type: {}", contentType); + return Util.INDETERMINATE; + } + + } catch (Exception e) { + String message = "Parsing Content-Type: " + connection.getContentType(); + logger.error(message, e); return Util.INDETERMINATE; } - - rawDecision = new JSONObject(response).getString("decision"); - - return rawDecision; } - public static PolicyGuardResponse ParseXacmlPdpResponse( - com.att.research.xacml.api.Response xacmlResponse) { - + public static PolicyGuardResponse parseXACMLPDPResponse(com.att.research.xacml.api.Response xacmlResponse) { if (xacmlResponse == null) { - // // In case the actual XACML response was null, create an empty // response object with decision "Indeterminate" @@ -261,40 +213,33 @@ public class PolicyGuardXacmlHelper { return new PolicyGuardResponse("Indeterminate", null, ""); } - Iterator<Result> it_res = xacmlResponse.getResults().iterator(); + Iterator<Result> itRes = xacmlResponse.getResults().iterator(); - Result res = it_res.next(); - String decision_from_xacml_response = res.getDecision().toString(); - Iterator<AttributeCategory> it_attr_cat = res.getAttributes() - .iterator(); - UUID req_id_from_xacml_response = null; - String operation_from_xacml_response = ""; + Result res = itRes.next(); + String decisionFromXACMLResponse = res.getDecision().toString(); + Iterator<AttributeCategory> itAttrCat = res.getAttributes().iterator(); + UUID reqIDFromXACMLResponse = null; + String operationFromXACMLResponse = ""; - while (it_attr_cat.hasNext()) { - Iterator<Attribute> it_attr = it_attr_cat.next().getAttributes() + while (itAttrCat.hasNext()) { + Iterator<Attribute> itAttr = itAttrCat.next().getAttributes() .iterator(); - while (it_attr.hasNext()) { - Attribute current_attr = it_attr.next(); - String s = current_attr.getAttributeId().stringValue(); + while (itAttr.hasNext()) { + Attribute currentAttr = itAttr.next(); + String s = currentAttr.getAttributeId().stringValue(); if ("urn:oasis:names:tc:xacml:1.0:request:request-id".equals(s)) { - Iterator<AttributeValue<?>> it_values = current_attr - .getValues().iterator(); - req_id_from_xacml_response = UUID.fromString(it_values - .next().getValue().toString()); + Iterator<AttributeValue<?>> itValues = currentAttr.getValues().iterator(); + reqIDFromXACMLResponse = UUID.fromString(itValues .next().getValue().toString()); } - if ("urn:oasis:names:tc:xacml:1.0:operation:operation-id" - .equals(s)) { - Iterator<AttributeValue<?>> it_values = current_attr - .getValues().iterator(); - operation_from_xacml_response = it_values.next().getValue() - .toString(); + if ("urn:oasis:names:tc:xacml:1.0:operation:operation-id" .equals(s)) { + Iterator<AttributeValue<?>> itValues = currentAttr.getValues().iterator(); + operationFromXACMLResponse = itValues.next().getValue().toString(); } - } } - return new PolicyGuardResponse(decision_from_xacml_response, - req_id_from_xacml_response, operation_from_xacml_response); + return new PolicyGuardResponse(decisionFromXACMLResponse, + reqIDFromXACMLResponse, operationFromXACMLResponse); } @@ -306,36 +251,45 @@ public class PolicyGuardXacmlHelper { String timeoutString = properties.getProperty("pdpx.timeout"); String disabledString = properties.getProperty("guard.disabled"); - if (disabledString != null) { - // decode optional 'guard.disabled' parameter - disabled = new Boolean(disabledString); - if (disabled) { - // skip everything else - return; + if (disabledString != null && Boolean.parseBoolean(disabledString)) { + return; + } + + ArrayList<URLEntry> entries = initEntries(properties, sb); + + if (entries.isEmpty()) { + sb.append("'pdpx.*' -- no URLs specified, "); + } else { + restUrls = entries.toArray(new URLEntry[0]); + } + + if (timeoutString != null) { + try { + // decode optional 'pdpx.timeout' parameter + timeout = Integer.valueOf(timeoutString); + } catch (NumberFormatException e) { + sb.append("'pdpx.timeout': " + e + ", "); + logger.trace(e.getLocalizedMessage()); } } - /* - * Decode 'pdpx.*' parameters - */ - - // first, the default parameters - String defaultUser = properties.getProperty("pdpx.username"); - String defaultPassword = properties - .getProperty("pdpx.password"); - String defaultClientUser = properties - .getProperty("pdpx.client.username"); - String defaultClientPassword = properties - .getProperty("pdpx.client.password"); - String defaultEnvironment = properties - .getProperty("pdpx.environment"); + // if there are any errors, update 'errorMessage' & disable guard + // queries + if (sb.length() != 0) { + // remove the terminating ", ", and extract resulting error message + sb.setLength(sb.length() - 2); + String errorMessage = sb.toString(); + logger.error("Initialization failure: {}", errorMessage); + } + } + + private ArrayList<URLEntry> initEntries(Properties properties, StringBuilder sb) { // now, see which numeric entries (1-9) exist ArrayList<URLEntry> entries = new ArrayList<>(); for (int index = 0; index < 10; index += 1) { String urlPrefix = "guard."; - String pdpxPrefix = "pdpx."; if (index != 0) { urlPrefix = urlPrefix + index + "."; } @@ -353,102 +307,83 @@ public class PolicyGuardXacmlHelper { // URL,user // URL,user,password for (String restURL : restURLlist.split("\\s*;\\s*")) { - String[] segments = restURL.split("\\s*,\\s*"); - String user = null; - String password = null; - - if (segments.length >= 2) { - // user id is provided - restURL = segments[0]; - user = segments[1]; - if (segments.length >= 3) { - // password is also provided - password = segments[2]; - } - } - - // URL does exist -- create the entry - URLEntry urlEntry = new URLEntry(); - try { - urlEntry.restURL = new URL(restURL); - } catch (java.net.MalformedURLException e) { - // if we don't have a URL, - // don't bother with the rest on this one - sb.append("'").append(urlPrefix).append("url' '") - .append(restURL).append("': ").append(e) - .append(","); - continue; - } - - if (nullOrEmpty(user)) { - // user id was not provided on '*.url' line -- - // extract it from a separate property - user = properties.getProperty(pdpxPrefix + "username", defaultUser); - } - if (nullOrEmpty(password)) { - // password was not provided on '*.url' line -- - // extract it from a separate property - password = properties.getProperty(pdpxPrefix + "password", - defaultPassword); - } - - // see if 'user' and 'password' entries both exist - if (!nullOrEmpty(user) && !nullOrEmpty(password)) { - urlEntry.authorization = "Basic " - + Base64.getEncoder().encodeToString( - (user + ":" + password).getBytes()); - } - - // see if 'client.user' and 'client.password' entries both exist - String clientUser = properties.getProperty(pdpxPrefix - + "client.username", defaultClientUser); - String clientPassword = properties.getProperty(pdpxPrefix - + "client.password", defaultClientPassword); - if (!nullOrEmpty(clientUser) && !nullOrEmpty(clientPassword)) { - urlEntry.clientAuth = "Basic " - + Base64.getEncoder().encodeToString( - (clientUser + ":" + clientPassword) - .getBytes()); + URLEntry entry = initRestURL(properties, sb, restURL); + // include this URLEntry in the list + if (entry != null) { + entries.add(entry); } + } + } - // see if there is an 'environment' entry - String environment = properties.getProperty(pdpxPrefix - + "environment", defaultEnvironment); - if (!nullOrEmpty(environment)) { - urlEntry.environment = environment; - } + return entries; + } - // include this URLEntry in the list - entries.add(urlEntry); + private URLEntry initRestURL(Properties properties, StringBuilder sb, String restURL) { + String urlPrefix = "guard."; + String pdpxPrefix = "pdpx."; + + String[] segments = restURL.split("\\s*,\\s*"); + String user = null; + String password = null; + + if (segments.length >= 2) { + // user id is provided + restURL = segments[0]; + user = segments[1]; + if (segments.length >= 3) { + // password is also provided + password = segments[2]; } } - if (entries.size() == 0) { - sb.append("'pdpx.*' -- no URLs specified, "); - } else { - restUrls = entries.toArray(new URLEntry[0]); + // URL does exist -- create the entry + URLEntry urlEntry = new URLEntry(); + try { + urlEntry.restURL = new URL(restURL); + } catch (java.net.MalformedURLException e) { + // if we don't have a URL, + // don't bother with the rest on this one + sb.append("'").append(urlPrefix).append("url' '") + .append(restURL).append("': ").append(e) + .append(","); + return null; } - if (timeoutString != null) { - try { - // decode optional 'pdpx.timeout' parameter - timeout = Integer.valueOf(timeoutString); - } catch (NumberFormatException e) { - sb.append("'pdpx.timeout': " + e + ", "); - logger.trace(e.getLocalizedMessage()); - } + if (nullOrEmpty(user)) { + // user id was not provided on '*.url' line -- + // extract it from a separate property + user = properties.getProperty(pdpxPrefix + "username", properties.getProperty("pdpx.username")); + } + if (nullOrEmpty(password)) { + // password was not provided on '*.url' line -- + // extract it from a separate property + password = properties.getProperty(pdpxPrefix + "password", properties.getProperty("pdpx.password")); } + // see if 'user' and 'password' entries both exist + if (!nullOrEmpty(user) && !nullOrEmpty(password)) { + urlEntry.authorization = "Basic " + + Base64.getEncoder().encodeToString( + (user + ":" + password).getBytes()); + } - // if there are any errors, update 'errorMessage' & disable guard - // queries - if (sb.length() != 0) { - // remove the terminating ", ", and extract resulting error message - sb.setLength(sb.length() - 2); - errorMessage = sb.toString(); - disabled = true; - logger.error("Initialization failure: " + errorMessage); + // see if 'client.user' and 'client.password' entries both exist + String clientUser = properties.getProperty(pdpxPrefix + "client.username", properties.getProperty("pdpx.client.username")); + String clientPassword = properties.getProperty(pdpxPrefix + "client.password", properties.getProperty("pdpx.client.password")); + if (!nullOrEmpty(clientUser) && !nullOrEmpty(clientPassword)) { + urlEntry.clientAuth = "Basic " + + Base64.getEncoder().encodeToString( + (clientUser + ":" + clientPassword) + .getBytes()); } + + // see if there is an 'environment' entry + String environment = properties.getProperty(pdpxPrefix + "environment", properties.getProperty("pdpx.environment")); + if (!nullOrEmpty(environment)) { + urlEntry.environment = environment; + } + + return urlEntry; } /** @@ -459,8 +394,37 @@ public class PolicyGuardXacmlHelper { * @return 'true' if the string is 'null' or has a length of 0, 'false' * otherwise */ - static private boolean nullOrEmpty(String value) { + private static boolean nullOrEmpty(String value) { return (value == null || value.isEmpty()); } + private static String readResponseFromStream(InputStream iStream, int contentLength) throws IOException { + // if content length is -1, response is chunked, and + // TCP connection will be dropped at the end + byte[] buf = new byte[contentLength < 0 ? 1024: contentLength]; + int offset = 0; + do { + int size = iStream.read(buf, offset, buf.length - offset); + if (size < 0) { + // In a chunked response a dropped connection is expected, but not if the response is not chunked + if (contentLength > 0) { + logger.error("partial input stream"); + } + break; + } + offset += size; + } while (offset != contentLength); + + String response = new String(buf, 0, offset); + + // + // Connection may have failed or not been 200 OK, return Indeterminate + // + if (response.isEmpty()) { + return Util.INDETERMINATE; + } + + return new JSONObject(response).getString("decision"); + + } } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java index 115108219..70291001a 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributes.java @@ -26,118 +26,76 @@ import com.att.research.xacml.std.annotations.XACMLRequest; import com.att.research.xacml.std.annotations.XACMLResource; import com.att.research.xacml.std.annotations.XACMLSubject; - - @XACMLRequest(ReturnPolicyIdList=true,CombinedDecision=true) public class PolicyGuardXacmlRequestAttributes { - - - - public PolicyGuardXacmlRequestAttributes(String clname_id, String actor_id, String operation_id, String target_id, - String request_id) { - super(); - this.clname_id = clname_id; - this.actor_id = actor_id; - this.operation_id = operation_id; - this.target_id = target_id; - this.request_id = request_id; - } - - - - @Override - public String toString() { - return "PolicyGuardXacmlRequestAttributes [actor_id=" + actor_id + ", operation_id=" + operation_id - + ", target_id=" + target_id + ", request_id=" + request_id + "]"; - } - - - - //@XACMLSubject(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id") - //String userID; - - //@XACMLAction() - //String action; - - @XACMLSubject(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:clname:clname-id") - String clname_id; - - @XACMLSubject(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id") - String actor_id; - - @XACMLAction(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id") - String operation_id; - - //@XACMLResource(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id123") - //String resource; - - @XACMLResource(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:target:target-id") - String target_id; - - @XACMLResource(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:request:request-id") - String request_id; - - public String getActor_id() { - return actor_id; - } - - - - public void setActor_id(String actor_id) { - this.actor_id = actor_id; - } - - - - public String getOperation_id() { - return operation_id; - } - - - - public void setOperation_id(String operation_id) { - this.operation_id = operation_id; - } - - - - public String getTarget_id() { - return target_id; - } + public PolicyGuardXacmlRequestAttributes(String clnameID, String actorID, String operationID, String targetID, String requestID) { + super(); + this.clnameID = clnameID; + this.actorID = actorID; + this.operationID = operationID; + this.targetID = targetID; + this.requestID = requestID; + } + @Override + public String toString() { + return "PolicyGuardXacmlRequestAttributes [actorID=" + actorID + ", operationID=" + operationID + + ", targetID=" + targetID + ", requestID=" + requestID + "]"; + } + @XACMLSubject(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:clname:clname-id") + String clnameID; - public void setTarget_id(String target_id) { - this.target_id = target_id; - } + @XACMLSubject(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id") + String actorID; + @XACMLAction(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id") + String operationID; + @XACMLResource(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:target:target-id") + String targetID; - public String getRequest_id() { - return request_id; - } + @XACMLResource(includeInResults=true, attributeId="urn:oasis:names:tc:xacml:1.0:request:request-id") + String requestID; + public String getActorID() { + return actorID; + } + public void setActorID(String actorID) { + this.actorID = actorID; + } - public void setRequest_id(String request_id) { - this.request_id = request_id; - } + public String getOperationID() { + return operationID; + } + public void setOperationID(String operationID) { + this.operationID = operationID; + } + public String getTargetID() { + return targetID; + } - public String getClname_id() { - return clname_id; - } + public void setTargetID(String targetID) { + this.targetID = targetID; + } + public String getRequestID() { + return requestID; + } + public void setRequestID(String requestID) { + this.requestID = requestID; + } - public void setClname_id(String clname_id) { - this.clname_id = clname_id; - } - - - - - }; + public String getClnameID() { + return clnameID; + } + public void setClnameID(String clnameID) { + this.clnameID = clnameID; + } +} diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java index aef86f320..bb6ae49c8 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/PolicyGuardYamlToXacml.java @@ -25,22 +25,23 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.onap.policy.controlloop.policy.guard.Constraint; import org.onap.policy.controlloop.policy.guard.ControlLoopGuard; +import org.onap.policy.controlloop.policy.guard.MatchParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; - - public class PolicyGuardYamlToXacml { - private static final Logger logger = LoggerFactory.getLogger(PolicyGuardYamlToXacml.class); - - public static void fromYamlToXacml(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput){ - + + private PolicyGuardYamlToXacml() { + // Construction of this static class is not allowed + } + + public static void fromYamlToXacml(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput) { ControlLoopGuard yamlGuardObject = Util.loadYamlGuard(yamlFile); logger.debug("clname: {}", yamlGuardObject.getGuards().getFirst().getMatch_parameters().getControlLoopName()); logger.debug("actor: {}", yamlGuardObject.getGuards().getFirst().getMatch_parameters().getActor()); @@ -48,212 +49,160 @@ public class PolicyGuardYamlToXacml { logger.debug("num: {}", yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getFreq_limit_per_target()); logger.debug("duration: {}", yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getTime_window()); logger.debug("time_in_range: {}", yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getActive_time_range()); - + Path xacmlTemplatePath = Paths.get(xacmlTemplate); - String xacmlTemplateContent; - - try { + String xacmlTemplateContent; + + try { xacmlTemplateContent = new String(Files.readAllBytes(xacmlTemplatePath)); - - String xacmlPolicyContent = generateXacmlGuard(xacmlTemplateContent, - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getControlLoopName(), - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getActor(), - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getRecipe(), - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getTargets(), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getFreq_limit_per_target(), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getTime_window(), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getActive_time_range().get("start"), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getActive_time_range().get("end") - ); - - - Files.write(Paths.get(xacmlPolicyOutput), xacmlPolicyContent.getBytes()); - + + String xacmlPolicyContent = generateXACMLGuard(xacmlTemplateContent, + yamlGuardObject.getGuards().getFirst().getMatch_parameters(), + yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst() + ); + + Files.write(Paths.get(xacmlPolicyOutput), xacmlPolicyContent.getBytes()); + } catch (IOException e) { logger.error("fromYamlToXacml threw: ", e); } - } - - - - public static String generateXacmlGuard(String xacmlFileContent, - String clname, - String actor, - String recipe, - List<String> targets, - Integer limit, - Map<String,String> timeWindow, - String guardActiveStart, - String guardActiveEnd) { + private static String generateXACMLGuard(String xacmlTemplateContent, MatchParameters matchParameters, Constraint constraint) { Pattern p = Pattern.compile("\\$\\{clname\\}"); - Matcher m = p.matcher(xacmlFileContent); - if(isNullOrEmpty(clname)) clname = ".*"; - xacmlFileContent = m.replaceAll(clname); - + Matcher m = p.matcher(xacmlTemplateContent); + if (isNullOrEmpty(matchParameters.getControlLoopName())) matchParameters.setControlLoopName(".*"); + xacmlTemplateContent = m.replaceAll(matchParameters.getControlLoopName()); + p = Pattern.compile("\\$\\{actor\\}"); - m = p.matcher(xacmlFileContent); - if(isNullOrEmpty(actor)) actor = ".*"; - xacmlFileContent = m.replaceAll(actor); + m = p.matcher(xacmlTemplateContent); + if(isNullOrEmpty(matchParameters.getActor())) matchParameters.setActor(".*"); + xacmlTemplateContent = m.replaceAll(matchParameters.getActor()); p = Pattern.compile("\\$\\{recipe\\}"); - m = p.matcher(xacmlFileContent); - if(isNullOrEmpty(recipe)) recipe = ".*"; - xacmlFileContent = m.replaceAll(recipe); - + m = p.matcher(xacmlTemplateContent); + if(isNullOrEmpty(matchParameters.getRecipe())) matchParameters.setRecipe(".*"); + xacmlTemplateContent = m.replaceAll(matchParameters.getRecipe()); + p = Pattern.compile("\\$\\{targets\\}"); - m = p.matcher(xacmlFileContent); + m = p.matcher(xacmlTemplateContent); String targetsRegex = ""; - if(isNullOrEmptyList(targets)){ + if(isNullOrEmptyList(matchParameters.getTargets())) { targetsRegex = ".*"; } - else{ - for(String t : targets){ - targetsRegex += (t + "|"); - + else { + StringBuilder targetsRegexSB = new StringBuilder(); + boolean addBarChar = false; + for (String t : matchParameters.getTargets()){ + targetsRegexSB.append(t); + if (addBarChar) { + targetsRegexSB.append("|"); + } + else { + addBarChar = true; + } } - targetsRegex = targetsRegex.substring(0, targetsRegex.length()-1); + targetsRegex = targetsRegexSB.toString(); } - xacmlFileContent = m.replaceAll(targetsRegex); + xacmlTemplateContent = m.replaceAll(targetsRegex); p = Pattern.compile("\\$\\{limit\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(limit.toString()); - - - //p = Pattern.compile("\\$\\{timeWindow\\}"); - //m = p.matcher(xacmlFileContent); - //xacmlFileContent = m.replaceAll("tw"+timeWindow); - + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getFreq_limit_per_target().toString()); + p = Pattern.compile("\\$\\{twValue\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(timeWindow.get("value")); - + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getTime_window().get("value")); + p = Pattern.compile("\\$\\{twUnits\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(timeWindow.get("units")); - + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getTime_window().get("units")); + p = Pattern.compile("\\$\\{guardActiveStart\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(guardActiveStart); + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getActive_time_range().get("start")); p = Pattern.compile("\\$\\{guardActiveEnd\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(guardActiveEnd); - logger.debug(xacmlFileContent); + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getActive_time_range().get("end")); + logger.debug(xacmlTemplateContent); - return xacmlFileContent; + return xacmlTemplateContent; } - - public static boolean isNullOrEmpty(String s){ - - if(s == null){ - return true; - } - else if(s.equals("")){ - return true; - } - return false; - + + public static boolean isNullOrEmpty(String s) { + return s == null || s.trim().isEmpty(); } - + public static boolean isNullOrEmptyList(List<String> list){ - - if(list == null){ - return true; - } - else if(list.isEmpty()){ - return true; - } - return false; - + return list == null || list.isEmpty(); } - public static void fromYamlToXacmlBlacklist(String yamlFile, String xacmlTemplate, String xacmlPolicyOutput){ - ControlLoopGuard yamlGuardObject = Util.loadYamlGuard(yamlFile); logger.debug("actor: {}", yamlGuardObject.getGuards().getFirst().getMatch_parameters().getActor()); logger.debug("recipe: {}", yamlGuardObject.getGuards().getFirst().getMatch_parameters().getRecipe()); logger.debug("freq_limit_per_target: {}", yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getFreq_limit_per_target()); logger.debug("time_window: {}", yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getTime_window()); logger.debug("active_time_range: {}", yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getActive_time_range()); - + Path xacmlTemplatePath = Paths.get(xacmlTemplate); - String xacmlTemplateContent; - - try { + String xacmlTemplateContent; + + try { xacmlTemplateContent = new String(Files.readAllBytes(xacmlTemplatePath)); - - String xacmlPolicyContent = generateXacmlGuardBlacklist(xacmlTemplateContent, - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getControlLoopName(), - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getActor(), - yamlGuardObject.getGuards().getFirst().getMatch_parameters().getRecipe(), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getBlacklist(), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getActive_time_range().get("start"), - yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst().getActive_time_range().get("end") - ); - - - Files.write(Paths.get(xacmlPolicyOutput), xacmlPolicyContent.getBytes()); - + String xacmlPolicyContent = generateXacmlGuardBlacklist(xacmlTemplateContent, + yamlGuardObject.getGuards().getFirst().getMatch_parameters(), + yamlGuardObject.getGuards().getFirst().getLimit_constraints().getFirst() + ); + + Files.write(Paths.get(xacmlPolicyOutput), xacmlPolicyContent.getBytes()); + } catch (IOException e) { logger.error("fromYamlToXacmlBlacklist threw: ", e); } - } - - public static String generateXacmlGuardBlacklist(String xacmlFileContent, - String clname, - String actor, - String recipe, - List<String> blacklist, - String guardActiveStart, - String guardActiveEnd) { - - + + private static String generateXacmlGuardBlacklist(String xacmlTemplateContent, MatchParameters matchParameters, Constraint constraint) { Pattern p = Pattern.compile("\\$\\{clname\\}"); - Matcher m = p.matcher(xacmlFileContent); - if(isNullOrEmpty(clname)) clname = ".*"; - xacmlFileContent = m.replaceAll(clname); - + Matcher m = p.matcher(xacmlTemplateContent); + if(isNullOrEmpty(matchParameters.getControlLoopName())) matchParameters.setControlLoopName(".*"); + xacmlTemplateContent = m.replaceAll(matchParameters.getControlLoopName()); + p = Pattern.compile("\\$\\{actor\\}"); - m = p.matcher(xacmlFileContent); - if(isNullOrEmpty(actor)) actor = ".*"; - xacmlFileContent = m.replaceAll(actor); + m = p.matcher(xacmlTemplateContent); + if(isNullOrEmpty(matchParameters.getActor())) matchParameters.setActor(".*"); + xacmlTemplateContent = m.replaceAll(matchParameters.getActor()); p = Pattern.compile("\\$\\{recipe\\}"); - m = p.matcher(xacmlFileContent); - if(isNullOrEmpty(recipe)) recipe = ".*"; - xacmlFileContent = m.replaceAll(recipe); - + m = p.matcher(xacmlTemplateContent); + if(isNullOrEmpty(matchParameters.getRecipe())) matchParameters.setRecipe(".*"); + xacmlTemplateContent = m.replaceAll(matchParameters.getRecipe()); + p = Pattern.compile("\\$\\{guardActiveStart\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(guardActiveStart); + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getActive_time_range().get("start")); p = Pattern.compile("\\$\\{guardActiveEnd\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(guardActiveEnd); - logger.debug(xacmlFileContent); - - for(String target : blacklist){ + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(constraint.getActive_time_range().get("end")); + logger.debug(xacmlTemplateContent); + + for(String target : constraint.getBlacklist()){ p = Pattern.compile("\\$\\{blackListElement\\}"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll("<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">" - + target - + "</AttributeValue>" - + "\n\t\t\t\t\t\t\\$\\{blackListElement\\}\n"); + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll("<AttributeValue DataType=\"http://www.w3.org/2001/XMLSchema#string\">" + + target + + "</AttributeValue>" + + "\n\t\t\t\t\t\t\\$\\{blackListElement\\}\n"); } - + p = Pattern.compile("\t\t\t\t\t\t\\$\\{blackListElement\\}\n"); - m = p.matcher(xacmlFileContent); - xacmlFileContent = m.replaceAll(""); - - - return xacmlFileContent; + m = p.matcher(xacmlTemplateContent); + xacmlTemplateContent = m.replaceAll(""); + + + return xacmlTemplateContent; } - - } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/Util.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/Util.java index 93bdc0c37..53e7a5e50 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/Util.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/Util.java @@ -20,8 +20,6 @@ package org.onap.policy.guard; -import static org.junit.Assert.fail; - import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -38,6 +36,9 @@ import org.yaml.snakeyaml.Yaml; import org.yaml.snakeyaml.constructor.Constructor; public final class Util { + private Util() { + // This static class cannot be instantiated + } /* * Keys for guard properties @@ -75,6 +76,7 @@ public final class Util { protected static final String JUNITPU = "TestOperationsHistoryPU"; private static final Logger logger = LoggerFactory.getLogger(Util.class); + public static class Pair<A, B> { public final A a; public final B b; @@ -85,7 +87,7 @@ public final class Util { } } - public static Pair<ControlLoopPolicy, String> loadYaml(String testFile) { + public static Pair<ControlLoopPolicy, String> loadYaml(String testFile) { try (InputStream is = new FileInputStream(new File(testFile))) { String contents = IOUtils.toString(is, StandardCharsets.UTF_8); // @@ -96,15 +98,14 @@ public final class Util { logger.debug(contents); - return new Pair<ControlLoopPolicy, String>((ControlLoopPolicy) obj, contents); + return new Pair<>((ControlLoopPolicy) obj, contents); } catch (IOException e) { logger.error(e.getLocalizedMessage(), e); - fail(e.getLocalizedMessage()); } return null; } - public static ControlLoopGuard loadYamlGuard(String testFile) { + public static ControlLoopGuard loadYamlGuard(String testFile) { try (InputStream is = new FileInputStream(new File(testFile))) { String contents = IOUtils.toString(is, StandardCharsets.UTF_8); // @@ -115,7 +116,6 @@ public final class Util { return (ControlLoopGuard) obj; } catch (IOException e) { logger.error(e.getLocalizedMessage(), e); - fail(e.getLocalizedMessage()); } return null; } @@ -126,7 +126,7 @@ public final class Util { * @see /guard/src/test/java/org/onap/policy/guard/UtilTest.java * for setting test properties */ - public static void setGuardEnvProps(String url, String username, String password, String clientName, String clientPassword, String environment){ + public static void setGuardEnvProps(String url, String username, String password, String clientName, String clientPassword, String environment) { PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_URL, url); PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_USER, username); PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_PASS, password); @@ -134,11 +134,12 @@ public final class Util { PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_CLIENT_PASS, clientPassword); PolicyEngine.manager.setEnvironmentProperty(org.onap.policy.guard.Util.PROP_GUARD_ENV, environment); } + public static void setGuardEnvProp(String key, String value){ PolicyEngine.manager.setEnvironmentProperty(key, value); } + public static String getGuardProp(String propName){ return PolicyEngine.manager.getEnvironmentProperty(propName); } - } diff --git a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PNFTargetLock.java b/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PNFTargetLock.java index 62ddb0d71..d9335ea3d 100644 --- a/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PNFTargetLock.java +++ b/controlloop/common/guard/src/main/java/org/onap/policy/guard/impl/PNFTargetLock.java @@ -49,7 +49,7 @@ public class PNFTargetLock implements TargetLock, Serializable { } @Override - public UUID getLockID() { + public UUID getLockID() { return this.lockID; } diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/GuardResultTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/GuardResultTest.java new file mode 100644 index 000000000..b4d417e35 --- /dev/null +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/GuardResultTest.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2018 Ericsson. 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public class GuardResultTest { + + @Test + public void guardResultTest() { + assertEquals(3, GuardResult.values().length); + assertNotNull(GuardResult.LOCK_ACQUIRED); + assertNotNull(GuardResult.LOCK_DENIED); + assertNotNull(GuardResult.LOCK_EXCEPTION); + + assertEquals(GuardResult.LOCK_ACQUIRED, GuardResult.valueOf("LOCK_ACQUIRED")); + assertEquals(GuardResult.LOCK_DENIED, GuardResult.valueOf("LOCK_DENIED")); + assertEquals(GuardResult.LOCK_EXCEPTION, GuardResult.valueOf("LOCK_EXCEPTION")); + } +} diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/GuardUtilTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/GuardUtilTest.java new file mode 100644 index 000000000..9e1d1b29e --- /dev/null +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/GuardUtilTest.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2018 Ericsson. 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; +import org.onap.policy.controlloop.policy.ControlLoopPolicy; +import org.onap.policy.controlloop.policy.guard.ControlLoopGuard; +import org.onap.policy.guard.Util.Pair; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +import com.att.aft.dme2.internal.google.common.io.Files; + +public class GuardUtilTest { + @Test + public void testLoadYamlOK() throws IOException { + File tempYAMLFile = File.createTempFile("ONAPPF", "yaml"); + + ControlLoopPolicy clPolicy = new ControlLoopPolicy(); + + Yaml clYaml = new Yaml(new Constructor(ControlLoopPolicy.class)); + String clYamlString = clYaml.dump(clPolicy); + + TextFileUtils.putStringAsFile(clYamlString, tempYAMLFile); + + Pair<ControlLoopPolicy, String> result = Util.loadYaml(tempYAMLFile.getCanonicalPath()); + + assertEquals(clPolicy, result.a); + assertEquals(clYamlString, result.b); + + tempYAMLFile.delete(); + } + + @Test + public void testLoadYamlError() throws IOException { + File tempDir = Files.createTempDir(); + + // Read from a directory forces an IO exception + assertNull(Util.loadYaml(tempDir.getCanonicalPath())); + + tempDir.delete(); + } + + @Test + public void testLoadGuardYamlOK() throws IOException { + File tempYAMLFile = File.createTempFile("ONAPPF", "yaml"); + + ControlLoopGuard clGuardPolicy = new ControlLoopGuard(); + + Yaml clYaml = new Yaml(new Constructor(ControlLoopPolicy.class)); + String clYamlString = clYaml.dump(clGuardPolicy); + + TextFileUtils.putStringAsFile(clYamlString, tempYAMLFile); + + ControlLoopGuard result = Util.loadYamlGuard(tempYAMLFile.getCanonicalPath()); + + assertEquals(clGuardPolicy, result); + + tempYAMLFile.delete(); + } + + @Test + public void testLoadGuardYamlError() throws IOException { + File tempDir = Files.createTempDir(); + + // Read from a directory forces an IO exception + assertNull(Util.loadYamlGuard(tempDir.getCanonicalPath())); + + tempDir.delete(); + } + + @Test + public void testMisc() { + Util.setGuardEnvProp("Actor", "Judy Garland"); + assertEquals("Judy Garland", Util.getGuardProp("Actor")); + + Util.setGuardEnvProps("http://somewhere.over.the.rainbow", "Dorothy", "Toto", "Wizard", "Emerald", "Oz"); + + assertEquals("http://somewhere.over.the.rainbow", Util.getGuardProp(Util.PROP_GUARD_URL)); + assertEquals("Dorothy", Util.getGuardProp(Util.PROP_GUARD_USER)); + assertEquals("Toto", Util.getGuardProp(Util.PROP_GUARD_PASS)); + assertEquals("Wizard", Util.getGuardProp(Util.PROP_GUARD_CLIENT_USER)); + assertEquals("Emerald", Util.getGuardProp(Util.PROP_GUARD_CLIENT_PASS)); + assertEquals("Oz", Util.getGuardProp(Util.PROP_GUARD_ENV)); + } +} diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PIPEngineGetHistoryTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PIPEngineGetHistoryTest.java index 566cc7a93..0c34d62b1 100644 --- a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PIPEngineGetHistoryTest.java +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PIPEngineGetHistoryTest.java @@ -28,6 +28,13 @@ import static org.mockito.Mockito.when; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Properties; +import java.util.UUID; import javax.persistence.EntityManager; import javax.persistence.Persistence; @@ -37,9 +44,24 @@ import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.drools.system.PolicyEngine; +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.api.pip.PIPEngine; +import com.att.research.xacml.api.pip.PIPException; +import com.att.research.xacml.api.pip.PIPFinder; +import com.att.research.xacml.api.pip.PIPRequest; +import com.att.research.xacml.api.pip.PIPResponse; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdAttribute; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdStatus; +import com.att.research.xacml.std.StdStatusCode; import com.att.research.xacml.std.pip.StdPIPRequest; import com.att.research.xacml.std.pip.StdPIPResponse; import com.att.research.xacml.std.pip.finders.EngineFinder; +import com.att.research.xacml.util.FactoryException; public class PIPEngineGetHistoryTest { static PIPEngineGetHistory pegh; @@ -73,8 +95,7 @@ public class PIPEngineGetHistoryTest { // Test issuer null when(mockPIPRequest.getIssuer()).thenReturn(null); try { - assertEquals(pegh.getAttributes(mockPIPRequest, mockPIPFinder), - StdPIPResponse.PIP_RESPONSE_EMPTY); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pegh.getAttributes(mockPIPRequest, mockPIPFinder)); } catch (Exception e) { fail("getAttributes failed"); } @@ -83,8 +104,7 @@ public class PIPEngineGetHistoryTest { pegh.setIssuer(ISSUER); when(mockPIPRequest.getIssuer()).thenReturn("something else"); try { - assertEquals(pegh.getAttributes(mockPIPRequest, mockPIPFinder), - StdPIPResponse.PIP_RESPONSE_EMPTY); + assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pegh.getAttributes(mockPIPRequest, mockPIPFinder)); } catch (Exception e) { fail("getAttributes failed"); } @@ -165,4 +185,209 @@ public class PIPEngineGetHistoryTest { assertEquals(1, count); } + @Test + public void testConfigure() throws PIPException { + PIPEngineGetHistory pegh = new PIPEngineGetHistory(); + pegh.configure("Dorothy", new Properties()); + + pegh.setDescription(null); + pegh.setIssuer(null); + pegh.configure("Dorothy", new Properties()); + } + + @Test + public void getAttributesTest() throws URISyntaxException, PIPException, FactoryException { + PIPEngineGetHistory pegh = new PIPEngineGetHistory(); + pegh.setIssuer("Dorothy"); + + Identifier identifierCategory = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/category"));; + Identifier identifierAttribute = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/atrtribute"));; + Identifier identifierDataType = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/datatype"));; + PIPRequest pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:1000:SECOND"); + + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinderPipException())); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinderResponseStatusNOK())); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinderResponseEmptyAttrs())); + } + + @Test + public void timeWindowTest() throws URISyntaxException, PIPException, FactoryException { + PIPEngineGetHistory pegh = new PIPEngineGetHistory(); + pegh.setIssuer("Dorothy"); + + Identifier identifierCategory = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/category"));; + Identifier identifierAttribute = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/atrtribute"));; + Identifier identifierDataType = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/datatype"));; + + PIPRequest pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:SECOND"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:MINUTE"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:HOUR"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:DAY"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:WEEK"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:MONTH"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:QUARTER"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:YEAR"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:FORTNIGHT"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + pipRequest = new StdPIPRequest(identifierCategory , identifierAttribute, identifierDataType, "Dorothy,tw:100:FORT NIGHT"); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinder())); + + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinderPipException())); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinderResponseStatusNOK())); + assertNotNull(pegh.getAttributes(pipRequest, new DummyPipFinderResponseEmptyAttrs())); + } + + private class DummyPipFinder implements PIPFinder { + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + try { + List<Attribute> attributeList = new ArrayList<>(); + Identifier categoryIdIn = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/category")); + Identifier dataTypeIdIn = new IdentifierImpl(new URI("http://www.w3.org/2001/XMLSchema#string")); + + Identifier attributeIdIn0 = new IdentifierImpl(new URI(UUID.randomUUID().toString())); + AttributeValue<String> valueIn0 = new StdAttributeValue<String>(dataTypeIdIn, "ActorDorothy"); + Attribute attribute0 = new StdAttribute(categoryIdIn, attributeIdIn0, valueIn0); + attributeList.add(attribute0); + + Identifier attributeIdIn1 = new IdentifierImpl(new URI(UUID.randomUUID().toString())); + AttributeValue<String> valueIn1 = new StdAttributeValue<String>(dataTypeIdIn, "OperationHomeFromOZ"); + Attribute attribute1 = new StdAttribute(categoryIdIn, attributeIdIn1, valueIn1); + attributeList.add(attribute1); + + Identifier attributeIdIn2 = new IdentifierImpl(new URI(UUID.randomUUID().toString())); + AttributeValue<String> valueIn2 = new StdAttributeValue<String>(dataTypeIdIn, "TargetWickedWitch"); + Attribute attribute2 = new StdAttribute(categoryIdIn, attributeIdIn2, valueIn2); + attributeList.add(attribute2); + + return new StdPIPResponse(attributeList); + } + catch (Exception e) { + return null; + } + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public Collection<PIPEngine> getPIPEngines() { + return null; + } + } + + private class DummyPipFinderPipException implements PIPFinder { + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + throw new PIPException(); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public Collection<PIPEngine> getPIPEngines() { + return null; + } + } + + private class DummyPipFinderResponseStatusNOK implements PIPFinder { + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + Status status = new StdStatus(StdStatusCode.STATUS_CODE_PROCESSING_ERROR, "Processing Error"); + return new StdPIPResponse(status); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public Collection<PIPEngine> getPIPEngines() { + return null; + } + } + + private class DummyPipFinderResponseEmptyAttrs implements PIPFinder { + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude) throws PIPException { + List<Attribute> attributeList = new ArrayList<>(); + return new StdPIPResponse(attributeList); + } + + @Override + public PIPResponse getAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public PIPResponse getMatchingAttributes(PIPRequest pipRequest, PIPEngine exclude, PIPFinder pipFinderParent) throws PIPException { + return null; + } + + @Override + public Collection<PIPEngine> getPIPEngines() { + return null; + } + } } diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardRequestTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardRequestTest.java new file mode 100644 index 000000000..fa4acf7ec --- /dev/null +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardRequestTest.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2018 Ericsson. 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import static org.junit.Assert.*; + +import java.util.UUID; + +import org.junit.Test; + +public class PolicyGuardRequestTest { + + @Test + public void policyGuardRequestTest() { + UUID requestId = UUID.randomUUID(); + + assertNotNull(new PolicyGuardRequest(null, null, null, null)); + + PolicyGuardRequest request = new PolicyGuardRequest("Dorothy", "Kansas", requestId, "GetBackHome"); + + request.setRequestID(requestId); + assertEquals(requestId, request.getRequestID()); + + request.setActor("Dorothy"); + assertEquals("Dorothy", request.getActor()); + + request.setTarget("Kansas"); + assertEquals("Kansas", request.getTarget()); + + request.setOperation("GetBackHome"); + assertEquals("GetBackHome", request.getOperation()); + + assertEquals("PolicyGuardRequest [actor=Dorothy", request.toString().substring(0, 33)); + } +} diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardResponseTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardResponseTest.java new file mode 100644 index 000000000..fe0155541 --- /dev/null +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardResponseTest.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2018 Ericsson. 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import static org.junit.Assert.*; + +import java.util.UUID; + +import org.junit.Test; + +public class PolicyGuardResponseTest { + + @Test + public void policyGuardResponseTest() { + UUID requestId = UUID.randomUUID(); + + assertNotNull(new PolicyGuardResponse(null, null, null)); + + PolicyGuardResponse response = new PolicyGuardResponse("BackHome", requestId, "GetBackHome"); + + response.setRequestID(requestId); + assertEquals(requestId, response.getRequestID()); + + response.setResult("BackHome"); + assertEquals("BackHome", response.getResult()); + + response.setOperation("GetBackHome"); + assertEquals("GetBackHome", response.getOperation()); + + assertEquals("PolicyGuardResponse [requestID=", response.toString().substring(0, 31)); + } +} diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java index 17e115707..82656fa09 100644 --- a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardTest.java @@ -19,36 +19,42 @@ */ package org.onap.policy.guard; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.util.UUID; import org.junit.Test; import org.onap.policy.controlloop.policy.TargetType; +import org.onap.policy.guard.PolicyGuard.LockResult; +import org.onap.policy.guard.impl.PNFTargetLock; +import org.onap.policy.guard.impl.VMTargetLock; +import org.onap.policy.guard.impl.VNFTargetLock; public class PolicyGuardTest { - private class DummyLockCallback implements LockCallback{ + private static final String INSTANCENAME = "targetInstance"; + + private class DummyLockCallback implements LockCallback { @Override public boolean isActive() { - // TODO Auto-generated method stub return false; } @Override public boolean releaseLock() { - // TODO Auto-generated method stub return false; } } - private class DummyTargetLock implements TargetLock{ + + private class DummyTargetLock implements TargetLock { @Override public UUID getLockID() { - // TODO Auto-generated method stub return null; } @Override public TargetType getTargetType() { - // TODO Auto-generated method stub return null; } @Override @@ -57,26 +63,173 @@ public class PolicyGuardTest { } @Override public UUID getRequestID() { - // TODO Auto-generated method stub return null; } } - private static final String INSTANCENAME = "targetInstance"; + @Test + public void testLockVM() { + UUID uuid = UUID.randomUUID(); + TargetType type = TargetType.VM; + + // Test isLocked before and after lock added + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + DummyLockCallback dlcb = new DummyLockCallback(); + LockResult<GuardResult, TargetLock> result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); + assertEquals(VMTargetLock.class, result.getB().getClass()); + + VMTargetLock vtl = (VMTargetLock) result.getB(); + assertNotNull(vtl.getLockID()); + assertEquals(INSTANCENAME, vtl.getTargetInstance()); + assertEquals(TargetType.VM, vtl.getTargetType()); + assertNotNull(vtl.getRequestID()); + assertEquals(dlcb, vtl.getCallback()); + + // Test isLocked after lock removed + PolicyGuard.unlockTarget(new DummyTargetLock()); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + } + + @Test + public void testLockPNF() { + UUID uuid = UUID.randomUUID(); + TargetType type = TargetType.PNF; + + // Test isLocked before and after lock added + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + DummyLockCallback dlcb = new DummyLockCallback(); + LockResult<GuardResult, TargetLock> result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); + assertEquals(PNFTargetLock.class, result.getB().getClass()); + + PNFTargetLock ptl = (PNFTargetLock) result.getB(); + assertNotNull(ptl.getLockID()); + assertEquals(INSTANCENAME, ptl.getTargetInstance()); + assertEquals(TargetType.PNF, ptl.getTargetType()); + assertNotNull(ptl.getRequestID()); + assertEquals(dlcb, ptl.getCallback()); + + // Test isLocked after lock removed + PolicyGuard.unlockTarget(new DummyTargetLock()); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + } + + + @Test + public void testLockVNF() { + UUID uuid = UUID.randomUUID(); + TargetType type = TargetType.VNF; + + // Test isLocked before and after lock added + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + DummyLockCallback dlcb = new DummyLockCallback(); + LockResult<GuardResult, TargetLock> result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); + assertEquals(VNFTargetLock.class, result.getB().getClass()); + + VNFTargetLock vtl = (VNFTargetLock) result.getB(); + assertNotNull(vtl.getLockID()); + assertEquals(INSTANCENAME, vtl.getTargetInstance()); + assertEquals(TargetType.VNF, vtl.getTargetType()); + assertNotNull(vtl.getRequestID()); + assertEquals(dlcb, vtl.getCallback()); + + // Test isLocked after lock removed + PolicyGuard.unlockTarget(new DummyTargetLock()); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + } @Test - public void testAll() { + public void testLockVFC() { + UUID uuid = UUID.randomUUID(); + TargetType type = TargetType.VFC; + + // Test isLocked before and after lock added + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + DummyLockCallback dlcb = new DummyLockCallback(); + LockResult<GuardResult, TargetLock> result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_EXCEPTION, result.getA()); + assertNull(result.getB()); + + // Test isLocked after lock removed + PolicyGuard.unlockTarget(new DummyTargetLock()); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + } + + @Test + public void testUnLockNotLocked() { UUID uuid = UUID.randomUUID(); TargetType type = TargetType.VM; + // Test isLocked before and after lock added + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + DummyLockCallback dlcb = new DummyLockCallback(); + LockResult<GuardResult, TargetLock> result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); + assertEquals(VMTargetLock.class, result.getB().getClass()); + + result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_DENIED, result.getA()); + assertNull(result.getB()); + + // Test isLocked after lock removed + PolicyGuard.unlockTarget(new DummyTargetLock()); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + // Test unlock after lock removed + PolicyGuard.unlockTarget(new DummyTargetLock()); + assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + } + + @Test + public void testLockAlreadyLocked() { + UUID uuid = UUID.randomUUID(); + TargetType type = TargetType.VM; // Test isLocked before and after lock added assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); - PolicyGuard.lockTarget(type, INSTANCENAME, uuid , new DummyLockCallback()); + DummyLockCallback dlcb = new DummyLockCallback(); + LockResult<GuardResult, TargetLock> result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_ACQUIRED, result.getA()); + assertEquals(VMTargetLock.class, result.getB().getClass()); + + result = PolicyGuard.lockTarget(type, INSTANCENAME, uuid , dlcb); + assertTrue(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); + + assertEquals(GuardResult.LOCK_DENIED, result.getA()); + assertNull(result.getB()); // Test isLocked after lock removed PolicyGuard.unlockTarget(new DummyTargetLock()); assertFalse(PolicyGuard.isLocked(type, INSTANCENAME, uuid)); } + + @Test + public void testInnards() { + + DummyLockCallback dlcb = new DummyLockCallback(); + assertFalse(dlcb.isActive()); + assertFalse(dlcb.releaseLock()); + + DummyTargetLock dtl = new DummyTargetLock(); + assertNull(dtl.getLockID()); + assertNull(dtl.getRequestID()); + assertEquals(INSTANCENAME, dtl.getTargetInstance()); + assertNull(dtl.getTargetType()); + } } diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlHelperTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlHelperTest.java index 1d3ab02e4..10c6d7239 100644 --- a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlHelperTest.java +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlHelperTest.java @@ -19,17 +19,43 @@ */ package org.onap.policy.guard; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Properties; +import java.util.UUID; + import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import org.onap.policy.drools.http.server.HttpServletServer; +import org.onap.policy.drools.system.PolicyEngine; import org.onap.policy.drools.utils.LoggerUtil; - +import com.att.research.xacml.api.Advice; +import com.att.research.xacml.api.Attribute; +import com.att.research.xacml.api.AttributeCategory; +import com.att.research.xacml.api.AttributeValue; +import com.att.research.xacml.api.Decision; +import com.att.research.xacml.api.IdReference; +import com.att.research.xacml.api.Identifier; +import com.att.research.xacml.api.Obligation; +import com.att.research.xacml.api.Response; +import com.att.research.xacml.api.Result; +import com.att.research.xacml.api.Status; +import com.att.research.xacml.std.IdentifierImpl; +import com.att.research.xacml.std.StdAttribute; +import com.att.research.xacml.std.StdAttributeCategory; +import com.att.research.xacml.std.StdAttributeValue; +import com.att.research.xacml.std.StdResponse; +import com.att.research.xacml.std.StdResult; +import com.att.research.xacml.std.StdStatus; public class PolicyGuardXacmlHelperTest { @@ -65,7 +91,7 @@ public class PolicyGuardXacmlHelperTest { org.onap.policy.simulators.GuardSimulatorJaxRs.DENY_CLNAME, "actor", "recipe", "target", "requestId"); String rawDecision = new PolicyGuardXacmlHelper().callPDP(xacmlReq); assertNotNull(rawDecision); - assertTrue(0 == Util.INDETERMINATE.compareToIgnoreCase(rawDecision)); + assertEquals(0, Util.INDETERMINATE.compareToIgnoreCase(rawDecision)); } @Test @@ -93,9 +119,131 @@ public class PolicyGuardXacmlHelperTest { "clname", "actor", "recipe", "target", "requestId"); rawDecision = new PolicyGuardXacmlHelper().callPDP(xacmlReq); assertNotNull(rawDecision); - assertTrue(0 == Util.PERMIT.compareToIgnoreCase(rawDecision)); + assertEquals(0, Util.PERMIT.compareToIgnoreCase(rawDecision)); // Indeterminate case is in tearDown for efficiency } + + @Test + /** + * Tests PolicyGuardXacmlHelper.callPDP method to exercise all branches + */ + public void testCallPDPExtra() { + PolicyGuardXacmlRequestAttributes xacmlReq = new PolicyGuardXacmlRequestAttributes( + org.onap.policy.simulators.GuardSimulatorJaxRs.DENY_CLNAME, "actor", "recipe", "target", "requestId"); + + xacmlReq.setClnameID(null); + String rawDecision = new PolicyGuardXacmlHelper().callPDP(xacmlReq); + assertNotNull(rawDecision); + assertEquals(-5, Util.DENY.compareToIgnoreCase(rawDecision)); + + org.onap.policy.guard.Util.setGuardEnvProps("http://localhost:6669/pdp/api/getDecision", + "", + "", + "", + "", + ""); + + rawDecision = new PolicyGuardXacmlHelper().callPDP(xacmlReq); + assertNotNull(rawDecision); + + org.onap.policy.guard.Util.setGuardEnvProps("http://localhost:6669/pdp/api/getDecision", + "python", + "test", + "python", + "test", + "DEVL"); + + } + + @Test + public void testParseXACMLPDPResponse() throws URISyntaxException { + PolicyGuardResponse pgResponse = PolicyGuardXacmlHelper.parseXACMLPDPResponse(null); + assertEquals("Indeterminate", pgResponse.getResult()); + Decision decision = Decision.PERMIT; + Status status = new StdStatus(StdStatus.STATUS_OK); + Result result = new StdResult(decision, status); + Response xacmlResponse = new StdResponse(result); + pgResponse = PolicyGuardXacmlHelper.parseXACMLPDPResponse(xacmlResponse); + assertEquals("Permit", pgResponse.getResult()); + + + Collection<Obligation> obligationsIn = null; + Collection<Advice> adviceIn = null; + Collection<IdReference> policyIdentifiersIn = null; + Collection<IdReference> policySetIdentifiersIn = null; + + Collection<AttributeCategory> attributesIn = new ArrayList<>(); + Identifier identifierCategory = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow")); + Collection<Attribute> listAttributes = new ArrayList<>(); + Identifier categoryIdIn = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow/category")); + Identifier attributeIdIn0 = new IdentifierImpl(new URI("urn:oasis:names:tc:xacml:1.0:request:request-id")); + Identifier dataTypeIdIn = new IdentifierImpl(new URI("http://somewhere.over.the.rainbow.dataType")); + AttributeValue<String> valueIn = new StdAttributeValue<String>(dataTypeIdIn, UUID.randomUUID().toString()); + Attribute attribute0 = new StdAttribute(categoryIdIn, attributeIdIn0, valueIn); + listAttributes.add(attribute0); + + Identifier attributeIdIn1 = new IdentifierImpl(new URI("urn:oasis:names:tc:xacml:1.0:operation:operation-id")); + Attribute attribute1 = new StdAttribute(categoryIdIn, attributeIdIn1, valueIn); + listAttributes.add(attribute1); + attributesIn.add(new StdAttributeCategory(identifierCategory , listAttributes)); + + Identifier attributeIdIn2 = new IdentifierImpl(new URI("Http://somewhere.over.the.rainbow/attributeId")); + Attribute attribute2 = new StdAttribute(categoryIdIn, attributeIdIn2, valueIn); + listAttributes.add(attribute2); + attributesIn.add(new StdAttributeCategory(identifierCategory , listAttributes)); + + Result fullResult = new StdResult(Decision.DENY, obligationsIn, adviceIn, attributesIn, policyIdentifiersIn, policySetIdentifiersIn); + Response fullXacmlResponse = new StdResponse(fullResult); + PolicyGuardResponse fullPGResponse = PolicyGuardXacmlHelper.parseXACMLPDPResponse(fullXacmlResponse); + assertEquals("Deny", fullPGResponse.getResult()); + } + + @Test + public void testInit() { + Properties savedEnvironment = (Properties) PolicyEngine.manager.getEnvironment().clone(); + + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("guard.url", "http://localhost:6669/pdp/api/getDecision,Dorothy"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("guard.url", "http://localhost:6669/pdp/api/getDecision,Dorothy,Toto"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("guard.url", "http://localhost:6669/pdp/api/getDecision"); + + PolicyEngine.manager.getEnvironment().setProperty("pdpx.timeout", "thisIsNotANumber"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("pdpx.timeout", "1000"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().remove("pdpx.password"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("pdpx.username", "python"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().remove("pdpx.client.password"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().remove("pdpx.client.username"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("guard.url", "///"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("guard.disabled", ""); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().setProperty("guard.disabled", "true"); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.getEnvironment().clear(); + assertNotNull(new PolicyGuardXacmlHelper()); + + PolicyEngine.manager.setEnvironment(savedEnvironment); + } } diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributesTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributesTest.java new file mode 100644 index 000000000..d07a97a67 --- /dev/null +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardXacmlRequestAttributesTest.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2018 Ericsson. 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import static org.junit.Assert.*; + +import java.util.UUID; + +import org.junit.Test; + +public class PolicyGuardXacmlRequestAttributesTest { + + @Test + public void policyGuardXacmlRequestAttributesTest() { + assertNotNull(new PolicyGuardXacmlRequestAttributes(null, null, null, null, null)); + + UUID controlLoopID = UUID.randomUUID(); + UUID operationID = UUID.randomUUID(); + UUID requestID = UUID.randomUUID(); + UUID actorID = UUID.randomUUID(); + UUID targetID = UUID.randomUUID(); + + PolicyGuardXacmlRequestAttributes attributes = new PolicyGuardXacmlRequestAttributes( + controlLoopID.toString(), actorID.toString(), operationID.toString(), targetID.toString(), requestID.toString()); + + attributes.setRequestID(requestID.toString()); + assertEquals(requestID.toString(), attributes.getRequestID()); + + attributes.setOperationID(operationID.toString()); + assertEquals(operationID.toString(), attributes.getOperationID()); + + attributes.setActorID(actorID.toString()); + assertEquals(actorID.toString(), attributes.getActorID()); + + attributes.setTargetID(targetID.toString()); + assertEquals(targetID.toString(), attributes.getTargetID()); + + attributes.setTargetID(targetID.toString()); + assertEquals(targetID.toString(), attributes.getTargetID()); + + attributes.setClnameID(controlLoopID.toString()); + assertEquals(controlLoopID.toString(), attributes.getClnameID()); + + assertEquals("PolicyGuardXacmlRequestAttributes [actorID=", attributes.toString().substring(0, 43)); + } +} diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardYamlToXacmlTest.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardYamlToXacmlTest.java index 1e972c30f..b35356438 100644 --- a/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardYamlToXacmlTest.java +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/PolicyGuardYamlToXacmlTest.java @@ -22,48 +22,126 @@ package org.onap.policy.guard; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; +import org.junit.Before; import org.junit.Test; +import org.onap.policy.controlloop.policy.guard.Constraint; +import org.onap.policy.controlloop.policy.guard.ControlLoopGuard; +import org.onap.policy.controlloop.policy.guard.GuardPolicy; +import org.onap.policy.controlloop.policy.guard.MatchParameters; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; public class PolicyGuardYamlToXacmlTest { - - @Test - public void testFromYamlToXacml() { - //PolicyGuardYamlToXacml.fromYamlToXacml(yamlFile, xacmlTemplate, xacmlPolicyOutput); - //fail("Not yet implemented"); + private ControlLoopGuard clGuard; + + @Before + public void createControlLoopGuard() { + clGuard = new ControlLoopGuard(); + GuardPolicy guardPolicy = new GuardPolicy(); + MatchParameters matchParameters = new MatchParameters(); + matchParameters.setControlLoopName("WizardOfOz"); + matchParameters.setActor("Dorothy"); + matchParameters.setRecipe("GoToOz"); + List<String> targets = new ArrayList<>(); + targets.add("Wizard"); + targets.add("WickedWitchOfTheWest"); + matchParameters.setTargets(targets ); + guardPolicy.setMatch_parameters(matchParameters ); + Constraint limitConstraint = new Constraint(); + limitConstraint.setFreq_limit_per_target(5); + Map<String, String> timeWindow = new HashMap<>(); + timeWindow.put("value", "10"); + timeWindow.put("units", "hours"); + limitConstraint.setTime_window(timeWindow); + Map<String, String> activeTimeRange = new HashMap<>(); + activeTimeRange.put("start", "someStartTime"); + activeTimeRange.put("end", "someEndTime"); + limitConstraint.setActive_time_range(activeTimeRange ); + LinkedList<Constraint> limitConstraints = new LinkedList<>(); + limitConstraints.add(limitConstraint); + guardPolicy.setLimit_constraints(limitConstraints); + LinkedList<GuardPolicy> guardList = new LinkedList<>(); + guardList.add(guardPolicy); + clGuard.setGuards(guardList); } - + @Test - public void testGenerateXacmlGuard() { - String dummyFileContent = "${clname}, ${actor}, ${recipe}, ${targets}, ${limit}, ${twValue}, ${twUnits}, ${guardActiveStart}, ${guardActiveEnd}"; - List<String> targets = new ArrayList(); - targets.add("target1"); - targets.add("target2"); - Map<String, String> tw = new HashMap(); - tw.put("value", "10"); - tw.put("units", "hours"); - String res = PolicyGuardYamlToXacml.generateXacmlGuard(dummyFileContent, - "cl", "actor", "recipe", targets, 5, tw, "start", "end"); + public void testGenerateXacmlGuardFull() throws IOException { + File tempYAMLFile = File.createTempFile("ONAPPF", "yaml"); + File tempXACMLTemplateFile = new File("src/test/resources/frequency_limiter_template.xml"); + File tempXACMLOutputFile = File.createTempFile("ONAPPF", ".out.xacml"); + + Yaml clYaml = new Yaml(new Constructor(ControlLoopGuard.class)); + String clYamlString = clYaml.dump(clGuard); + + TextFileUtils.putStringAsFile(clYamlString, tempYAMLFile); + PolicyGuardYamlToXacml.fromYamlToXacml(tempYAMLFile.getCanonicalPath(), tempXACMLTemplateFile.getCanonicalPath(), tempXACMLOutputFile.getCanonicalPath()); + + String result = TextFileUtils.getTextFileAsString(tempXACMLOutputFile.getCanonicalPath()); // Assert no mote "${}" are left - assertFalse(res.contains("${")); - assertFalse(res.contains("}")); + assertFalse(result.contains("${")); + assertFalse(result.contains("}")); // Assert all substitutions are made - assertTrue(res.contains("cl")); - assertTrue(res.contains("actor")); - assertTrue(res.contains("recipe")); - assertTrue(res.contains("target1")); - assertTrue(res.contains("target2")); - assertTrue(res.contains("10")); - assertTrue(res.contains("hours")); - assertTrue(res.contains("start")); - assertTrue(res.contains("end")); + assertTrue(result.contains("cl")); + assertTrue(result.contains("actor")); + assertTrue(result.contains("GoToOz")); + assertTrue(result.contains("Wizard")); + assertTrue(result.contains("WickedWitchOfTheWest")); + assertTrue(result.contains("10")); + assertTrue(result.contains("hours")); + assertTrue(result.contains("someStartTime")); + assertTrue(result.contains("someEndTime")); + + tempYAMLFile.delete(); + tempXACMLOutputFile.delete(); } + + @Test + public void testGenerateXacmlGuardPartial() throws IOException { + File tempYAMLFile = File.createTempFile("ONAPPF", "yaml"); + File tempXACMLTemplateFile = new File("src/test/resources/frequency_limiter_template.xml"); + File tempXACMLOutputFile = File.createTempFile("ONAPPF", ".out.xacml"); + + clGuard.getGuards().getFirst().getMatch_parameters().setControlLoopName(null); + clGuard.getGuards().getFirst().getMatch_parameters().setActor(null); + clGuard.getGuards().getFirst().getMatch_parameters().setRecipe(null); + clGuard.getGuards().getFirst().getMatch_parameters().setTargets(null); + + Yaml clYaml = new Yaml(new Constructor(ControlLoopGuard.class)); + String clYamlString = clYaml.dump(clGuard); + + TextFileUtils.putStringAsFile(clYamlString, tempYAMLFile); + PolicyGuardYamlToXacml.fromYamlToXacml(tempYAMLFile.getCanonicalPath(), tempXACMLTemplateFile.getCanonicalPath(), tempXACMLOutputFile.getCanonicalPath()); + + String result = TextFileUtils.getTextFileAsString(tempXACMLOutputFile.getCanonicalPath()); + // Assert no mote "${}" are left + assertFalse(result.contains("${")); + assertFalse(result.contains("}")); + // Assert all substitutions are made + assertTrue(result.contains("cl")); + assertTrue(result.contains("actor")); + assertFalse(result.contains("GoToOz")); + assertFalse(result.contains("Wizard")); + assertFalse(result.contains("WickedWitchOfTheWest")); + assertTrue(result.contains("10")); + assertTrue(result.contains("hours")); + assertTrue(result.contains("someStartTime")); + assertTrue(result.contains("someEndTime")); + + tempYAMLFile.delete(); + tempXACMLOutputFile.delete(); + } + @Test public void testIsNullOrEmpty() { assertTrue(PolicyGuardYamlToXacml.isNullOrEmpty("")); @@ -73,7 +151,7 @@ public class PolicyGuardYamlToXacmlTest { @Test public void testIsNullOrEmptyList() { - List<String> l = new ArrayList(); + List<String> l = new ArrayList<>(); assertTrue(PolicyGuardYamlToXacml.isNullOrEmptyList(null)); assertTrue(PolicyGuardYamlToXacml.isNullOrEmptyList(l)); @@ -87,25 +165,67 @@ public class PolicyGuardYamlToXacmlTest { } @Test - public void testGenerateXacmlGuardBlacklist() { - String dummyFileContent = "${clname}, ${actor}, ${recipe}, ${blackListElement}, ${guardActiveStart}, ${guardActiveEnd}"; - List<String> blacklist = new ArrayList(); - blacklist.add("target1"); - blacklist.add("target2"); - String res = PolicyGuardYamlToXacml.generateXacmlGuardBlacklist(dummyFileContent, - "cl", "actor", "recipe", blacklist, "start", "end"); + public void testGenerateXacmlGuardBlacklist() throws IOException { + File tempYAMLFile = File.createTempFile("ONAPPF", "yaml"); + File tempXACMLTemplateFile = new File("src/test/resources/blacklist_template.xml"); + File tempXACMLOutputFile = File.createTempFile("ONAPPF", ".out.xacml"); + + List<String> blacklist = new ArrayList<>(); + blacklist.add("WestWitches"); + blacklist.add("EastWitches"); + clGuard.getGuards().getFirst().getLimit_constraints().getFirst().setBlacklist(blacklist ); + + Yaml clYaml = new Yaml(new Constructor(ControlLoopGuard.class)); + String clYamlString = clYaml.dump(clGuard); + + TextFileUtils.putStringAsFile(clYamlString, tempYAMLFile); + PolicyGuardYamlToXacml.fromYamlToXacmlBlacklist(tempYAMLFile.getCanonicalPath(), tempXACMLTemplateFile.getCanonicalPath(), tempXACMLOutputFile.getCanonicalPath()); + String result = TextFileUtils.getTextFileAsString(tempXACMLOutputFile.getCanonicalPath()); + System.err.println(result); // Assert no mote "${}" are left - assertFalse(res.contains("${")); - assertFalse(res.contains("}")); + assertFalse(result.contains("${")); + assertFalse(result.contains("}")); // Assert all substitutions are made - assertTrue(res.contains("cl")); - assertTrue(res.contains("actor")); - assertTrue(res.contains("recipe")); - assertTrue(res.contains("target1")); - assertTrue(res.contains("target2")); - assertTrue(res.contains("start")); - assertTrue(res.contains("end")); + assertTrue(result.contains("WestWitches")); + assertTrue(result.contains("EastWitches")); + + tempYAMLFile.delete(); + tempXACMLOutputFile.delete(); } + @Test + public void testGenerateXacmlGuardBlacklistPartial() throws IOException { + File tempYAMLFile = File.createTempFile("ONAPPF", "yaml"); + File tempXACMLTemplateFile = new File("src/test/resources/blacklist_template.xml"); + File tempXACMLOutputFile = File.createTempFile("ONAPPF", ".out.xacml"); + + List<String> blacklist = new ArrayList<>(); + blacklist.add("WestWitches"); + blacklist.add("EastWitches"); + clGuard.getGuards().getFirst().getLimit_constraints().getFirst().setBlacklist(blacklist ); + + clGuard.getGuards().getFirst().getMatch_parameters().setControlLoopName(null); + clGuard.getGuards().getFirst().getMatch_parameters().setActor(null); + clGuard.getGuards().getFirst().getMatch_parameters().setRecipe(null); + clGuard.getGuards().getFirst().getMatch_parameters().setTargets(null); + + Yaml clYaml = new Yaml(new Constructor(ControlLoopGuard.class)); + String clYamlString = clYaml.dump(clGuard); + + TextFileUtils.putStringAsFile(clYamlString, tempYAMLFile); + PolicyGuardYamlToXacml.fromYamlToXacmlBlacklist(tempYAMLFile.getCanonicalPath(), tempXACMLTemplateFile.getCanonicalPath(), tempXACMLOutputFile.getCanonicalPath()); + + String result = TextFileUtils.getTextFileAsString(tempXACMLOutputFile.getCanonicalPath()); + System.err.println(result); + // Assert no mote "${}" are left + assertFalse(result.contains("${")); + assertFalse(result.contains("}")); + // Assert all substitutions are made + assertTrue(result.contains("WestWitches")); + assertTrue(result.contains("EastWitches")); + + tempYAMLFile.delete(); + tempXACMLOutputFile.delete(); + } } diff --git a/controlloop/common/guard/src/test/java/org/onap/policy/guard/TextFileUtils.java b/controlloop/common/guard/src/test/java/org/onap/policy/guard/TextFileUtils.java new file mode 100644 index 000000000..21b75ed20 --- /dev/null +++ b/controlloop/common/guard/src/test/java/org/onap/policy/guard/TextFileUtils.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * guard + * ================================================================================ + * Copyright (C) 2018 Ericsson. 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.guard; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +/** + * The Class TextFileUtils is class that provides useful functions for handling text files. Functions to read and wrtie text files to strings and strings are + * provided. + * + * @author Liam Fallon (liam.fallon@ericsson.com) + */ +public abstract class TextFileUtils { + /** + * Method to return the contents of a text file as a string. + * + * @param textFilePath The path to the file as a string + * @return A string containing the contents of the file + * @throws IOException on errors reading text from the file + */ + public static String getTextFileAsString(final String textFilePath) throws IOException { + final File textFile = new File(textFilePath); + final FileInputStream textFileInputStream = new FileInputStream(textFile); + final byte[] textData = new byte[(int) textFile.length()]; + textFileInputStream.read(textData); + textFileInputStream.close(); + return new String(textData); + } + + /** + * Method to write contents of a string to a text file. + * + * @param outString The string to write + * @param textFile The file to write the string to + * @throws IOException on errors reading text from the file + */ + public static void putStringAsFile(final String outString, final File textFile) throws IOException { + final FileOutputStream textFileOutputStream = new FileOutputStream(textFile); + textFileOutputStream.write(outString.getBytes()); + textFileOutputStream.close(); + } +} diff --git a/controlloop/common/guard/src/test/resources/blacklist_template.xml b/controlloop/common/guard/src/test/resources/blacklist_template.xml new file mode 100644 index 000000000..5d31730db --- /dev/null +++ b/controlloop/common/guard/src/test/resources/blacklist_template.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny"> + <Description>Policy for frequency limiter.</Description> + <Target> + <AnyOf> + <AllOf> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <!-- <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">.*</AttributeValue>--> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${clname}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:clname:clname-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + + <!-- <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">--> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${actor}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${recipe}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Deny"> + <Description>DENY - only if target is in black list and guard is active.</Description> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <VariableReference VariableId="isGuardActive"/> + <VariableReference VariableId="isInBlackList"/> + </Apply> + </Condition> + </Rule> + <VariableDefinition VariableId="isInBlackList"> + <Apply FunctionId="urn:oasis:names:tc:xacml:3.0:function:any-of"> + <Function FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"/> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:target:target-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Apply> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> + ${blackListElement} + <!-- <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">vserver.vserver-name</AttributeValue>--> + </Apply> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isGuardActive"> + <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only"> + <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" DataType="http://www.w3.org/2001/XMLSchema#time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveStart}</AttributeValue> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveEnd}</AttributeValue> + </Apply> + </VariableDefinition> +</Policy> diff --git a/controlloop/common/guard/src/test/resources/frequency_limiter_template.xml b/controlloop/common/guard/src/test/resources/frequency_limiter_template.xml new file mode 100644 index 000000000..2d73a1e6d --- /dev/null +++ b/controlloop/common/guard/src/test/resources/frequency_limiter_template.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<Policy xmlns="urn:oasis:names:tc:xacml:3.0:core:schema:wd-17" PolicyId="urn:com:att:xacml:policy:id:25e12b06-11d5-4895-b2a2-6f6c594de069" Version="1" RuleCombiningAlgId="urn:oasis:names:tc:xacml:3.0:rule-combining-algorithm:permit-unless-deny"> + <Description>Policy for frequency limiter.</Description> + <Target> + <AnyOf> + <AllOf> + + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <!-- <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">.*</AttributeValue>--> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${clname}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:clname:clname-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + + <!-- <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal">--> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${actor}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:1.0:subject-category:access-subject" AttributeId="urn:oasis:names:tc:xacml:1.0:actor:actor-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${recipe}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:action" AttributeId="urn:oasis:names:tc:xacml:1.0:operation:operation-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + + <Match MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">${targets}</AttributeValue> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="urn:oasis:names:tc:xacml:1.0:target:target-id" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="false"/> + </Match> + + </AllOf> + </AnyOf> + </Target> + <Rule RuleId="urn:com:att:xacml:rule:id:e1e8c5c0-e2ba-47d5-9289-6c015305ed21" Effect="Deny"> + <Description>DENY - only if number of operations performed in the past is larger than the limit and the Guard is active.</Description> + <Condition> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:and"> + <VariableReference VariableId="isGuardActive"/> + <VariableReference VariableId="isHistoryGreaterThanLimit"/> + </Apply> + </Condition> + </Rule> + <VariableDefinition VariableId="isGuardActive"> + <Apply FunctionId="urn:oasis:names:tc:xacml:2.0:function:time-in-range"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:time-one-and-only"> + <AttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:environment:current-time" DataType="http://www.w3.org/2001/XMLSchema#time" Category="urn:oasis:names:tc:xacml:3.0:attribute-category:environment" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveStart}</AttributeValue> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#time">${guardActiveEnd}</AttributeValue> + </Apply> + </VariableDefinition> + <VariableDefinition VariableId="isHistoryGreaterThanLimit"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-greater-than-or-equal"> + <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only"> + <AttributeDesignator Category="urn:oasis:names:tc:xacml:3.0:attribute-category:resource" AttributeId="com:att:research:xacml:test:sql:resource:operations:count" DataType="http://www.w3.org/2001/XMLSchema#integer" Issuer="com:att:research:xacml:guard:historydb:tw:${twValue}:${twUnits}" MustBePresent="false"/> + </Apply> + <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#integer">${limit}</AttributeValue> + </Apply> + </VariableDefinition> +</Policy> diff --git a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl index c09e64abe..bdb57697b 100644 --- a/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl +++ b/controlloop/templates/archetype-cl-amsterdam/src/main/resources/archetype-resources/src/main/resources/__closedLoopControlName__.drl @@ -677,8 +677,8 @@ rule "${policyName}.GUARD.RESPONSE" //we will permit the operation if there was no Guard for it - if("Indeterminate".equalsIgnoreCase($guardResponse.result)){ - $guardResponse.result = "Permit"; + if("Indeterminate".equalsIgnoreCase($guardResponse.getResult())){ + $guardResponse.setResult("Permit"); } // @@ -686,7 +686,7 @@ rule "${policyName}.GUARD.RESPONSE" // VirtualControlLoopNotification notification = new VirtualControlLoopNotification($event); notification.setNotification(ControlLoopNotificationType.OPERATION); - notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe() + " is " + $guardResponse.result); + notification.setMessage("Guard result for " + $operation.policy.getActor() + " " + $operation.policy.getRecipe() + " is " + $guardResponse.getResult()); notification.setHistory($operation.getHistory()); notification.setFrom("policy"); notification.setPolicyName(drools.getRule().getName()); @@ -695,9 +695,9 @@ rule "${policyName}.GUARD.RESPONSE" PolicyEngine.manager.deliver("POLICY-CL-MGT", notification); - if("Permit".equalsIgnoreCase($guardResponse.result)){ + if("Permit".equalsIgnoreCase($guardResponse.getResult())){ - modify($operation){setGuardApprovalStatus($guardResponse.result)}; + modify($operation){setGuardApprovalStatus($guardResponse.getResult())}; } else { //This is the Deny case |