2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  19  * SPDX-License-Identifier: Apache-2.0
 
  20  * ============LICENSE_END=========================================================
 
  23 package org.onap.policy.xacml.pdp.application.guard;
 
  25 import static org.assertj.core.api.Assertions.assertThat;
 
  27 import com.att.research.xacml.api.Response;
 
  29 import java.io.IOException;
 
  30 import java.time.Instant;
 
  31 import java.util.Date;
 
  32 import java.util.Iterator;
 
  34 import java.util.Properties;
 
  35 import java.util.ServiceLoader;
 
  36 import java.util.UUID;
 
  37 import javax.persistence.EntityManager;
 
  38 import javax.persistence.Persistence;
 
  39 import org.apache.commons.lang3.tuple.Pair;
 
  40 import org.junit.AfterClass;
 
  41 import org.junit.Before;
 
  42 import org.junit.BeforeClass;
 
  43 import org.junit.ClassRule;
 
  44 import org.junit.FixMethodOrder;
 
  45 import org.junit.Test;
 
  46 import org.junit.rules.TemporaryFolder;
 
  47 import org.junit.runners.MethodSorters;
 
  48 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
 
  49 import org.onap.policy.common.utils.coder.CoderException;
 
  50 import org.onap.policy.common.utils.coder.StandardCoder;
 
  51 import org.onap.policy.common.utils.resources.TextFileUtils;
 
  52 import org.onap.policy.guard.OperationsHistory;
 
  53 import org.onap.policy.models.decisions.concepts.DecisionRequest;
 
  54 import org.onap.policy.models.decisions.concepts.DecisionResponse;
 
  55 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
 
  56 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
 
  57 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
 
  58 import org.onap.policy.pdp.xacml.application.common.operationshistory.CountRecentOperationsPip;
 
  59 import org.onap.policy.pdp.xacml.xacmltest.TestUtils;
 
  60 import org.slf4j.Logger;
 
  61 import org.slf4j.LoggerFactory;
 
  63 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 
  64 public class SonCoordinationTest {
 
  66     private static final Logger LOGGER = LoggerFactory.getLogger(SonCoordinationTest.class);
 
  67     private static Properties properties = new Properties();
 
  68     private static File propertiesFile;
 
  69     private static RestServerParameters clientParams = new RestServerParameters();
 
  70     private static XacmlApplicationServiceProvider service;
 
  71     private static DecisionRequest requestVpciNode1;
 
  72     private static DecisionRequest requestVsonhNode1;
 
  73     private static StandardCoder gson = new StandardCoder();
 
  74     private static EntityManager em;
 
  75     private static final String DENY = "Deny";
 
  76     private static final String PERMIT = "Permit";
 
  79     public static final TemporaryFolder policyFolder = new TemporaryFolder();
 
  82      * Copies the xacml.properties and policies files into
 
  83      * temporary folder and loads the service provider saving
 
  84      * instance of provider off for other tests to use.
 
  87     public static void setup() throws Exception {
 
  88         LOGGER.info("Setting up class");
 
  90         // Setup our temporary folder
 
  92         XacmlPolicyUtils.FileCreator myCreator =
 
  93             (String filename) -> policyFolder.newFile(filename);
 
  94         propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents(
 
  95             "src/test/resources/xacml.properties", properties, myCreator);
 
  99         ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
 
 100             ServiceLoader.load(XacmlApplicationServiceProvider.class);
 
 102         // Find the guard service application and save for use in all the tests
 
 104         StringBuilder strDump =
 
 105             new StringBuilder("Loaded applications:" + XacmlPolicyUtils.LINE_SEPARATOR);
 
 106         Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
 
 107         while (iterator.hasNext()) {
 
 108             XacmlApplicationServiceProvider application = iterator.next();
 
 110             // Is it our service?
 
 112             if (application instanceof GuardPdpApplication) {
 
 114                 // Should be the first and only one
 
 116                 assertThat(service).isNull();
 
 117                 service = application;
 
 119             strDump.append(application.applicationName());
 
 120             strDump.append(" supports ");
 
 121             strDump.append(application.supportedPolicyTypes());
 
 122             strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
 
 124         LOGGER.info("{}", strDump);
 
 126         // Tell it to initialize based on the properties file
 
 127         // we just built for it.
 
 129         service.initialize(propertiesFile.toPath().getParent(), clientParams);
 
 131         // Load Decision Requests
 
 133         requestVpciNode1 = gson.decode(
 
 134             TextFileUtils.getTextFileAsString(
 
 135                 "src/test/resources/requests/coordination.cl.vPci.node.1.json"),
 
 136             DecisionRequest.class);
 
 137         requestVsonhNode1 = gson.decode(
 
 138             TextFileUtils.getTextFileAsString(
 
 139                 "src/test/resources/requests/coordination.cl.vSonh.node.1.json"),
 
 140             DecisionRequest.class);
 
 141         String persistenceUnit = CountRecentOperationsPip.ISSUER_NAME + ".persistenceunit";
 
 143             .createEntityManagerFactory(SonCoordinationTest.properties.getProperty(persistenceUnit),
 
 145             .createEntityManager();
 
 149      * Clears the database before each test.
 
 153     public void startClean() throws Exception {
 
 154         em.getTransaction().begin();
 
 155         em.createQuery("DELETE FROM OperationsHistory").executeUpdate();
 
 156         em.getTransaction().commit();
 
 160      * Close the entity manager.
 
 163     public static void cleanup() throws Exception {
 
 170      * Check that decision matches expectation.
 
 172      * @param expected from the response
 
 173      * @param response received
 
 176     public void checkDecision(String expected, DecisionResponse response) throws CoderException {
 
 177         LOGGER.info("Looking for {} Decision", expected);
 
 178         assertThat(response).isNotNull();
 
 179         assertThat(response.getStatus()).isNotNull();
 
 180         assertThat(response.getStatus()).isEqualTo(expected);
 
 182         // Dump it out as Json
 
 184         LOGGER.info(gson.encode(response));
 
 188      * Request a decision and check that it matches expectation.
 
 190      * @param request to send to Xacml PDP
 
 191      * @param expected from the response
 
 194     public void requestAndCheckDecision(DecisionRequest request, String expected)
 
 195         throws CoderException {
 
 198         // Ask for a decision
 
 200         Pair<DecisionResponse, Response> decision = service.makeDecision(request, null);
 
 204         checkDecision(expected, decision.getKey());
 
 208     public void test1() throws CoderException, IOException, XacmlApplicationException {
 
 209         LOGGER.info("**************** Running vPci and vSonh Control Loops ****************");
 
 211         // Now load the test coordination policy - make sure
 
 212         // the pdp can support it and have it load
 
 215         TestUtils.loadPolicies(
 
 216             "src/test/resources/test.policy.guard.coordination.vPciBlocksVsonh.tosca.yaml",
 
 218         TestUtils.loadPolicies(
 
 219             "src/test/resources/test.policy.guard.coordination.vSonhBlocksVpci.tosca.yaml",
 
 222         // vSonh doesn't have open action: vPci should get permit
 
 224         requestAndCheckDecision(requestVpciNode1, PERMIT);
 
 226         // vPci doesn't have open action: vSonh should get permit
 
 228         requestAndCheckDecision(requestVsonhNode1, PERMIT);
 
 230         // Open vSonh on node1
 
 232         long vsonhId = insertOperationEvent(requestVsonhNode1, "Started");
 
 234         // Under current coordination policy vPci should get a deny
 
 236         requestAndCheckDecision(requestVpciNode1, DENY);
 
 238         // Close vSonh on node1
 
 240         updateOperationEvent(vsonhId, "Success");
 
 242         // With vSonh closed on node 1, vPci now should get a permit
 
 244         requestAndCheckDecision(requestVpciNode1, PERMIT);
 
 246         // Open vPci on node1
 
 248         long vpciId = insertOperationEvent(requestVpciNode1, "Started");
 
 250         // Under current coordination policy vSonh should get a deny
 
 252         requestAndCheckDecision(requestVsonhNode1, DENY);
 
 254         // Close cl1 on node1
 
 256         updateOperationEvent(vpciId, "Failed");
 
 258         // With vPci closed on node 1, vSonh now should get a permit
 
 260         requestAndCheckDecision(requestVsonhNode1, PERMIT);
 
 263     @SuppressWarnings("unchecked")
 
 264     private long insertOperationEvent(DecisionRequest request, String outcome) {
 
 266         // Get the properties
 
 268         Map<String, Object> properties = (Map<String, Object>) request.getResource().get("guard");
 
 272         OperationsHistory newEntry = new OperationsHistory();
 
 273         newEntry.setActor(properties.get("actor").toString());
 
 274         newEntry.setOperation(properties.get("operation").toString());
 
 275         newEntry.setClosedLoopName(properties.get("clname").toString());
 
 276         newEntry.setOutcome(outcome);
 
 277         newEntry.setStarttime(Date.from(Instant.now().minusMillis(20000)));
 
 278         newEntry.setEndtime(Date.from(Instant.now()));
 
 279         newEntry.setRequestId(UUID.randomUUID().toString());
 
 280         newEntry.setTarget(properties.get("target").toString());
 
 281         em.getTransaction().begin();
 
 282         em.persist(newEntry);
 
 283         em.getTransaction().commit();
 
 284         return newEntry.getId();
 
 287     private void updateOperationEvent(long id, String outcome) {
 
 289         OperationsHistory updateEntry = em.find(OperationsHistory.class, id);
 
 290         updateEntry.setOutcome(outcome);
 
 291         updateEntry.setEndtime(Date.from(Instant.now()));
 
 292         em.getTransaction().begin();
 
 293         em.persist(updateEntry);
 
 294         em.getTransaction().commit();