2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 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;
28 import java.io.IOException;
30 import java.time.Instant;
31 import java.util.Iterator;
33 import java.util.Properties;
34 import java.util.ServiceLoader;
35 import java.util.UUID;
37 import javax.persistence.EntityManager;
38 import javax.persistence.Persistence;
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.utils.coder.CoderException;
49 import org.onap.policy.common.utils.coder.StandardCoder;
50 import org.onap.policy.common.utils.resources.TextFileUtils;
51 import org.onap.policy.models.decisions.concepts.DecisionRequest;
52 import org.onap.policy.models.decisions.concepts.DecisionResponse;
53 import org.onap.policy.pdp.xacml.application.common.TestUtils;
54 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
55 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
56 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
57 import org.onap.policy.pdp.xacml.application.common.operationshistory.CountRecentOperationsPip;
58 import org.onap.policy.pdp.xacml.application.common.operationshistory.Dbao;
59 import org.slf4j.Logger;
60 import org.slf4j.LoggerFactory;
62 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
63 public class CoordinationTest {
65 private static final Logger LOGGER = LoggerFactory.getLogger(CoordinationTest.class);
66 private static Properties properties = new Properties();
67 private static File propertiesFile;
68 private static XacmlApplicationServiceProvider service;
69 private static DecisionRequest requestCl1Node1;
70 private static DecisionRequest requestCl1Node2;
71 private static DecisionRequest requestCl2Node1;
72 private static DecisionRequest requestCl2Node2;
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";
77 private static final String OPEN = "Success";
78 private static final String CLOSE = "Closed";
82 public static final TemporaryFolder policyFolder = new TemporaryFolder();
85 * Copies the xacml.properties and policies files into
86 * temporary folder and loads the service provider saving
87 * instance of provider off for other tests to use.
90 public static void setup() throws Exception {
91 LOGGER.info("Setting up class");
93 // Setup our temporary folder
95 XacmlPolicyUtils.FileCreator myCreator = (String filename) -> policyFolder.newFile(filename);
96 propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents("src/test/resources/xacml.properties",
97 properties, myCreator);
101 ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
102 ServiceLoader.load(XacmlApplicationServiceProvider.class);
104 // Find the guard service application and save for use in all the tests
106 StringBuilder strDump = new StringBuilder("Loaded applications:" + System.lineSeparator());
107 Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
108 while (iterator.hasNext()) {
109 XacmlApplicationServiceProvider application = iterator.next();
111 // Is it our service?
113 if (application instanceof GuardPdpApplication) {
115 // Should be the first and only one
117 assertThat(service).isNull();
118 service = application;
120 strDump.append(application.applicationName());
121 strDump.append(" supports ");
122 strDump.append(application.supportedPolicyTypes());
123 strDump.append(System.lineSeparator());
125 LOGGER.info("{}", strDump);
127 // Tell it to initialize based on the properties file
128 // we just built for it.
130 service.initialize(propertiesFile.toPath().getParent());
132 // Load Decision Requests
134 requestCl1Node1 = gson.decode(
135 TextFileUtils.getTextFileAsString(
136 "src/test/resources/requests/coordination.cl.1.node.1.json"),
137 DecisionRequest.class);
138 requestCl2Node1 = gson.decode(
139 TextFileUtils.getTextFileAsString(
140 "src/test/resources/requests/coordination.cl.2.node.1.json"),
141 DecisionRequest.class);
142 requestCl1Node2 = gson.decode(
143 TextFileUtils.getTextFileAsString(
144 "src/test/resources/requests/coordination.cl.1.node.2.json"),
145 DecisionRequest.class);
146 requestCl2Node2 = gson.decode(
147 TextFileUtils.getTextFileAsString(
148 "src/test/resources/requests/coordination.cl.2.node.2.json"),
149 DecisionRequest.class);
151 // Create EntityManager for manipulating DB
153 String persistenceUnit = CountRecentOperationsPip.ISSUER_NAME + ".persistenceunit";
154 em = Persistence.createEntityManagerFactory(
155 CoordinationTest.properties.getProperty(persistenceUnit), properties)
156 .createEntityManager();
160 * Clears the database before each test.
164 public void startClean() throws Exception {
165 em.getTransaction().begin();
166 em.createQuery("DELETE FROM Dbao").executeUpdate();
167 em.getTransaction().commit();
171 * Check that decision matches expectation.
173 * @param expected from the response
174 * @param response received
177 public void checkDecision(String expected, DecisionResponse response) throws CoderException {
178 LOGGER.info("Looking for {} Decision", expected);
179 assertThat(response).isNotNull();
180 assertThat(response.getStatus()).isNotNull();
181 assertThat(response.getStatus()).isEqualTo(expected);
183 // Dump it out as Json
185 LOGGER.info(gson.encode(response));
189 * Request a decision and check that it matches expectation.
191 * @param request to send to Xacml PDP
192 * @param expected from the response
195 public void requestAndCheckDecision(DecisionRequest request, String expected) throws CoderException {
197 // Ask for a decision
199 DecisionResponse response = service.makeDecision(request);
203 checkDecision(expected, response);
207 public void test1() throws CoderException, IOException, XacmlApplicationException {
208 LOGGER.info("**************** Running test1 ****************");
210 // Now load the test coordination policy - make sure
211 // the pdp can support it and have it load
214 TestUtils.loadPolicies("src/test/resources/test.policy.guard.coordination.firstBlocksSecond.tosca.yaml",
217 // cl1 doesn't have open action: cl2 should get permit
219 requestAndCheckDecision(requestCl2Node1, PERMIT);
223 insertOperationEvent(requestCl2Node1, OPEN);
225 // Under current coordination policy cl1 always can go
227 requestAndCheckDecision(requestCl1Node1, PERMIT);
231 insertOperationEvent(requestCl1Node1, OPEN);
233 // Close cl2 on node1
235 insertOperationEvent(requestCl2Node1, CLOSE);
237 // Try cl2 again, cl1 has open action on node1: should get deny
239 requestAndCheckDecision(requestCl2Node1, DENY);
241 // Close cl1 on node1
243 insertOperationEvent(requestCl1Node1, CLOSE);
245 // Under current coordination policy cl1 always can go
247 requestAndCheckDecision(requestCl1Node1, PERMIT);
251 insertOperationEvent(requestCl1Node1, OPEN);
253 // Try cl2 on node2, cl1 only open on node1: should get permit
255 requestAndCheckDecision(requestCl2Node2, PERMIT);
259 insertOperationEvent(requestCl2Node2, OPEN);
261 // Try cl2 on node1, cl1 open on node1: should get DENY
263 requestAndCheckDecision(requestCl2Node1, DENY);
266 @SuppressWarnings("unchecked")
267 private void insertOperationEvent(DecisionRequest request, String outcome) {
269 // Get the properties
271 Map<String, Object> properties = (Map<String, Object>) request.getResource().get("guard");
275 Dbao newEntry = new Dbao();
276 newEntry.setActor(properties.get("actor").toString());
277 newEntry.setOperation(properties.get("recipe").toString());
278 newEntry.setClosedLoopName(properties.get("clname").toString());
279 newEntry.setOutcome(outcome);
280 newEntry.setStarttime(Date.from(Instant.now().minusMillis(20000)));
281 newEntry.setEndtime(Date.from(Instant.now()));
282 newEntry.setRequestId(UUID.randomUUID().toString());
283 newEntry.setTarget(properties.get("target").toString());
284 em.getTransaction().begin();
285 em.persist(newEntry);
286 em.getTransaction().commit();
290 * Close the entity manager.
293 public static void cleanup() throws Exception {