XACML pdp support for clc.
[policy/xacml-pdp.git] / applications / guard / src / test / java / org / onap / policy / xacml / pdp / application / guard / SonCoordinationTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.xacml.pdp.application.guard;
24
25 import static org.assertj.core.api.Assertions.assertThat;
26
27 import com.att.research.xacml.api.Response;
28 import java.io.File;
29 import java.io.IOException;
30 import java.sql.Date;
31 import java.time.Instant;
32 import java.util.Iterator;
33 import java.util.Map;
34 import java.util.Properties;
35 import java.util.ServiceLoader;
36 import java.util.UUID;
37
38 import javax.persistence.EntityManager;
39 import javax.persistence.Persistence;
40
41 import org.apache.commons.lang3.tuple.Pair;
42 import org.junit.AfterClass;
43 import org.junit.Before;
44 import org.junit.BeforeClass;
45 import org.junit.ClassRule;
46 import org.junit.FixMethodOrder;
47 import org.junit.Test;
48 import org.junit.rules.TemporaryFolder;
49 import org.junit.runners.MethodSorters;
50 import org.onap.policy.common.endpoints.parameters.RestServerParameters;
51 import org.onap.policy.common.utils.coder.CoderException;
52 import org.onap.policy.common.utils.coder.StandardCoder;
53 import org.onap.policy.common.utils.resources.TextFileUtils;
54 import org.onap.policy.models.decisions.concepts.DecisionRequest;
55 import org.onap.policy.models.decisions.concepts.DecisionResponse;
56 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
57 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
58 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
59 import org.onap.policy.pdp.xacml.application.common.operationshistory.CountRecentOperationsPip;
60 import org.onap.policy.pdp.xacml.application.common.operationshistory.Dbao;
61 import org.onap.policy.pdp.xacml.xacmltest.TestUtils;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64
65 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
66 public class SonCoordinationTest {
67
68     private static final Logger LOGGER = LoggerFactory.getLogger(CoordinationTest.class);
69     private static Properties properties = new Properties();
70     private static File propertiesFile;
71     private static RestServerParameters clientParams = new RestServerParameters();
72     private static XacmlApplicationServiceProvider service;
73     private static DecisionRequest requestVpciNode1;
74     private static DecisionRequest requestVsonhNode1;
75     private static StandardCoder gson = new StandardCoder();
76     private static EntityManager em;
77     private static final String DENY = "Deny";
78     private static final String PERMIT = "Permit";
79     private static final String OPEN = "Success";
80     private static final String CLOSE = "Closed";
81
82     @ClassRule
83     public static final TemporaryFolder policyFolder = new TemporaryFolder();
84
85     /**
86      * Copies the xacml.properties and policies files into
87      * temporary folder and loads the service provider saving
88      * instance of provider off for other tests to use.
89      */
90     @BeforeClass
91     public static void setup() throws Exception {
92         LOGGER.info("Setting up class");
93         //
94         // Setup our temporary folder
95         //
96         XacmlPolicyUtils.FileCreator myCreator =
97             (String filename) -> policyFolder.newFile(filename);
98         propertiesFile = XacmlPolicyUtils.copyXacmlPropertiesContents(
99             "src/test/resources/xacml.properties", properties, myCreator);
100         //
101         // Load service
102         //
103         ServiceLoader<XacmlApplicationServiceProvider> applicationLoader =
104             ServiceLoader.load(XacmlApplicationServiceProvider.class);
105         //
106         // Find the guard service application and save for use in all the tests
107         //
108         StringBuilder strDump =
109             new StringBuilder("Loaded applications:" + XacmlPolicyUtils.LINE_SEPARATOR);
110         Iterator<XacmlApplicationServiceProvider> iterator = applicationLoader.iterator();
111         while (iterator.hasNext()) {
112             XacmlApplicationServiceProvider application = iterator.next();
113             //
114             // Is it our service?
115             //
116             if (application instanceof GuardPdpApplication) {
117                 //
118                 // Should be the first and only one
119                 //
120                 assertThat(service).isNull();
121                 service = application;
122             }
123             strDump.append(application.applicationName());
124             strDump.append(" supports ");
125             strDump.append(application.supportedPolicyTypes());
126             strDump.append(XacmlPolicyUtils.LINE_SEPARATOR);
127         }
128         LOGGER.info("{}", strDump);
129         //
130         // Tell it to initialize based on the properties file
131         // we just built for it.
132         //
133         service.initialize(propertiesFile.toPath().getParent(), clientParams);
134         //
135         // Load Decision Requests
136         //
137         requestVpciNode1 = gson.decode(
138             TextFileUtils.getTextFileAsString(
139                 "src/test/resources/requests/coordination.cl.vPci.node.1.json"),
140             DecisionRequest.class);
141         requestVsonhNode1 = gson.decode(
142             TextFileUtils.getTextFileAsString(
143                 "src/test/resources/requests/coordination.cl.vSonh.node.1.json"),
144             DecisionRequest.class);
145         String persistenceUnit = CountRecentOperationsPip.ISSUER_NAME + ".persistenceunit";
146         em = Persistence
147             .createEntityManagerFactory(SonCoordinationTest.properties.getProperty(persistenceUnit),
148                 properties)
149             .createEntityManager();
150     }
151
152     /**
153      * Clears the database before each test.
154      *
155      */
156     @Before
157     public void startClean() throws Exception {
158         em.getTransaction().begin();
159         em.createQuery("DELETE FROM Dbao").executeUpdate();
160         em.getTransaction().commit();
161     }
162
163     /**
164      * Close the entity manager.
165      */
166     @AfterClass
167     public static void cleanup() throws Exception {
168         if (em != null) {
169             em.close();
170         }
171     }
172
173     /**
174      * Check that decision matches expectation.
175      *
176      * @param expected from the response
177      * @param response received
178      *
179      **/
180     public void checkDecision(String expected, DecisionResponse response) throws CoderException {
181         LOGGER.info("Looking for {} Decision", expected);
182         assertThat(response).isNotNull();
183         assertThat(response.getStatus()).isNotNull();
184         assertThat(response.getStatus()).isEqualTo(expected);
185         //
186         // Dump it out as Json
187         //
188         LOGGER.info(gson.encode(response));
189     }
190
191     /**
192      * Request a decision and check that it matches expectation.
193      *
194      * @param request to send to Xacml PDP
195      * @param expected from the response
196      *
197      **/
198     public void requestAndCheckDecision(DecisionRequest request, String expected)
199         throws CoderException {
200
201         //
202         // Ask for a decision
203         //
204         Pair<DecisionResponse, Response> decision = service.makeDecision(request, null);
205         //
206         // Check decision
207         //
208         checkDecision(expected, decision.getKey());
209     }
210
211     @Test
212     public void test1() throws CoderException, IOException, XacmlApplicationException {
213         LOGGER.info("**************** Running vPci and vSonh Control Loops ****************");
214         //
215         // Now load the test coordination policy - make sure
216         // the pdp can support it and have it load
217         // into the PDP.
218         //
219         TestUtils.loadPolicies(
220             "src/test/resources/test.policy.guard.coordination.vPciBlocksVsonh.tosca.yaml",
221             service);
222         TestUtils.loadPolicies(
223             "src/test/resources/test.policy.guard.coordination.vSonhBlocksVpci.tosca.yaml",
224             service);
225         //
226         // vSonh doesn't have open action: vPci should get permit
227         //
228         requestAndCheckDecision(requestVpciNode1, PERMIT);
229         //
230         // vPci doesn't have open action: vSonh should get permit
231         //
232         requestAndCheckDecision(requestVsonhNode1, PERMIT);
233         //
234         // Open vSonh on node1
235         //
236         insertOperationEvent(requestVsonhNode1, OPEN);
237         //
238         // Under current coordination policy vPci should get a deny
239         //
240         requestAndCheckDecision(requestVpciNode1, DENY);
241         //
242         // Open vPci on node1
243         //
244         insertOperationEvent(requestVpciNode1, OPEN);
245         //
246         // Under current coordination policy vSonh should get a deny
247         //
248         requestAndCheckDecision(requestVsonhNode1, DENY);
249         //
250         // Close vSonh on node1
251         //
252         insertOperationEvent(requestVsonhNode1, CLOSE);
253         //
254         // With vSonh closed on node 1, vPci now should get a permit
255         //
256         requestAndCheckDecision(requestVpciNode1, PERMIT);
257         //
258         // Close cl1 on node1
259         //
260         insertOperationEvent(requestVpciNode1, CLOSE);
261         //
262         // With vPci closed on node 1, vSonh now should get a permit
263         //
264         requestAndCheckDecision(requestVsonhNode1, PERMIT);
265     }
266
267     @SuppressWarnings("unchecked")
268     private void insertOperationEvent(DecisionRequest request, String outcome) {
269         //
270         // Get the properties
271         //
272         Map<String, Object> properties = (Map<String, Object>) request.getResource().get("guard");
273         //
274         // Add an entry
275         //
276         Dbao newEntry = new Dbao();
277         newEntry.setActor(properties.get("actor").toString());
278         newEntry.setOperation(properties.get("recipe").toString());
279         newEntry.setClosedLoopName(properties.get("clname").toString());
280         newEntry.setOutcome(outcome);
281         newEntry.setStarttime(Date.from(Instant.now().minusMillis(20000)));
282         newEntry.setEndtime(Date.from(Instant.now()));
283         newEntry.setRequestId(UUID.randomUUID().toString());
284         newEntry.setTarget(properties.get("target").toString());
285         em.getTransaction().begin();
286         em.persist(newEntry);
287         em.getTransaction().commit();
288     }
289
290 }