2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020-2021 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.event.comm.bus.internal.BusTopicParams;
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 BusTopicParams clientParams = new BusTopicParams();
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();