66b4120285b42ba7b172f2fba8cc17203b837421
[policy/drools-applications.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3   * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=========================================================
17  */
18
19 package org.onap.policy.database.operationshistory;
20
21 import static org.junit.Assert.assertEquals;
22 import static org.mockito.ArgumentMatchers.any;
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26
27 import com.att.research.xacml.api.Attribute;
28 import com.att.research.xacml.api.AttributeValue;
29 import com.att.research.xacml.api.XACML3;
30 import com.att.research.xacml.api.pip.PIPException;
31 import com.att.research.xacml.api.pip.PIPFinder;
32 import com.att.research.xacml.api.pip.PIPRequest;
33 import com.att.research.xacml.api.pip.PIPResponse;
34 import com.att.research.xacml.std.pip.StdPIPResponse;
35 import java.io.FileInputStream;
36 import java.sql.Date;
37 import java.time.Instant;
38 import java.util.Collection;
39 import java.util.Properties;
40 import java.util.UUID;
41 import javax.persistence.EntityManager;
42 import javax.persistence.EntityManagerFactory;
43 import javax.persistence.Persistence;
44 import javax.persistence.Query;
45 import org.junit.AfterClass;
46 import org.junit.Before;
47 import org.junit.BeforeClass;
48 import org.junit.Test;
49 import org.onap.policy.database.ToscaDictionary;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 public class CountRecentOperationsPipTest {
54     private static final String ID = "issuer";
55     private static final Logger LOGGER = LoggerFactory.getLogger(CountRecentOperationsPipTest.class);
56     private static final String ISSUER = ToscaDictionary.GUARD_ISSUER_PREFIX + "-my-issuer:tw:1:HOUR";
57     private static final String ACTOR = "Controller";
58     private static final String RECIPE = "operationA";
59     private static final String TARGET = "vnf-1";
60     private static final String EXPECTED_EXCEPTION = "expected exception";
61
62     private static MyPip pipEngine;
63     private static Properties properties;
64
65     private static EntityManagerFactory emf;
66     private static EntityManager em;
67
68     private PIPRequest req;
69
70     /**
71      * Create an instance of our engine and also the persistence
72      * factory.
73      *
74      * @throws Exception connectivity issues
75      */
76     @BeforeClass
77     public static void setUpBeforeClass() throws Exception {
78         LOGGER.info("Setting up PIP Testing");
79         //
80         // Create instance
81         //
82         pipEngine = new MyPip();
83         //
84         // Load our test properties to use
85         //
86         properties = new Properties();
87         try (FileInputStream is = new FileInputStream("src/test/resources/test.properties")) {
88             properties.load(is);
89         }
90         //
91         // Configure it using properties
92         //
93         pipEngine.configure(ID, properties);
94         LOGGER.info("PIP configured now creating our entity manager");
95         LOGGER.info("properties {}", properties);
96         //
97         // Connect to in-mem db
98         //
99         String persistenceUnit = CountRecentOperationsPip.ISSUER_NAME + ".persistenceunit";
100         LOGGER.info("persistenceunit {}", persistenceUnit);
101         emf = Persistence.createEntityManagerFactory(properties.getProperty(persistenceUnit), properties);
102         em = emf.createEntityManager();
103         //
104         //
105         //
106         LOGGER.info("Configured own entity manager");
107     }
108
109     @Before
110     public void setUp() {
111         req = mock(PIPRequest.class);
112         when(req.getIssuer()).thenReturn(ISSUER);
113     }
114
115     private Dbao createEntry(String cl, String target, String outcome) {
116         //
117         // Create entry
118         //
119         Dbao newEntry = new Dbao();
120         newEntry.setClosedLoopName(cl);
121         newEntry.setTarget(target);
122         newEntry.setOutcome(outcome);
123         newEntry.setActor(ACTOR);
124         newEntry.setOperation(RECIPE);
125         newEntry.setStarttime(Date.from(Instant.now().minusMillis(20000)));
126         newEntry.setEndtime(Date.from(Instant.now()));
127         newEntry.setRequestId(UUID.randomUUID().toString());
128         return newEntry;
129     }
130
131     @Test
132     public void testAttributesRequired() {
133         assertEquals(3, pipEngine.attributesRequired().size());
134     }
135
136     @Test
137     public void testGetAttributes_InvalidRequestInfo() throws PIPException {
138         // invalid request - null issuer
139         when(req.getIssuer()).thenReturn(null);
140         assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pipEngine.getAttributes(req, null));
141
142         /*
143          * Make a valid issuer in the request, for subsequent tests.
144          */
145         when(req.getIssuer()).thenReturn(ISSUER);
146
147         // null actor
148         MyPip pip = new MyPip() {
149             @Override
150             protected String getActor(PIPFinder pipFinder) {
151                 return null;
152             }
153         };
154         pip.configure(ID, properties);
155         assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null));
156
157         // null recipe
158         pip = new MyPip() {
159             @Override
160             protected String getRecipe(PIPFinder pipFinder) {
161                 return null;
162             }
163         };
164         pip.configure(ID, properties);
165         assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null));
166
167         // null target
168         pip = new MyPip() {
169             @Override
170             protected String getTarget(PIPFinder pipFinder) {
171                 return null;
172             }
173         };
174         pip.configure(ID, properties);
175         assertEquals(StdPIPResponse.PIP_RESPONSE_EMPTY, pip.getAttributes(req, null));
176     }
177
178     @Test
179     public void testDoDatabaseQuery() throws Exception {
180
181         //
182         // No entries yet
183         //
184         assertEquals(0, getCount(pipEngine.getAttributes(req, null)));
185         //
186         // Add entry
187         //
188         em.getTransaction().begin();
189         em.persist(createEntry("cl-foobar-1", TARGET, "SUCCESS"));
190         em.getTransaction().commit();
191         //
192         // Directly check ground truth
193         //
194         Query queryCount = em.createNativeQuery("select count(*) as numops from operationshistory")
195                 .setParameter(1, 1);
196         LOGGER.info("{} entries", queryCount.getSingleResult());
197         //
198         // Should count 1 entry now
199         //
200         assertEquals(1, getCount(pipEngine.getAttributes(req, null)));
201     }
202
203     @Test
204     public void testDoDatabaseQuery_InvalidTimeWindow() throws Exception {
205         when(req.getIssuer()).thenReturn(ISSUER + "invalid time window");
206
207         assertEquals(-1, getCount(pipEngine.getAttributes(req, null)));
208     }
209
210     @Test
211     public void testDoDatabaseQuery_NullEm() throws Exception {
212         assertEquals(-1, getCount(new MyPip().getAttributes(req, null)));
213     }
214
215     @Test
216     public void testDoDatabaseQuery_EmException() throws Exception {
217         MyPip pip = new MyPip() {
218             @Override
219             public void configure(String id, Properties properties) throws PIPException {
220                 em = mock(EntityManager.class);
221                 when(em.createNativeQuery(any())).thenThrow(new RuntimeException(EXPECTED_EXCEPTION));
222             }
223         };
224         pip.configure(ID, properties);
225
226         assertEquals(-1, getCount(pip.getAttributes(req, null)));
227     }
228
229     @Test
230     public void testDoDatabaseQuery_NonNumeric() throws Exception {
231         MyPip pip = new MyPip() {
232             @Override
233             public void configure(String id, Properties properties) throws PIPException {
234                 em = mock(EntityManager.class);
235                 Query query = mock(Query.class);
236                 when(em.createNativeQuery(any())).thenReturn(query);
237                 when(query.setParameter(anyInt(), any())).thenReturn(query);
238                 when(query.getSingleResult()).thenReturn("200");
239             }
240         };
241         pip.configure(ID, properties);
242
243         assertEquals(200, getCount(pip.getAttributes(req, null)));
244     }
245
246     private int getCount(PIPResponse resp) {
247         Collection<Attribute> attrs = resp.getAttributes();
248         assertEquals(1, attrs.size());
249
250         Attribute attr = attrs.iterator().next();
251         assertEquals(XACML3.ID_ATTRIBUTE_CATEGORY_RESOURCE, attr.getCategory());
252         assertEquals(ToscaDictionary.ID_RESOURCE_GUARD_OPERATIONCOUNT, attr.getAttributeId());
253
254         Collection<AttributeValue<?>> values = attr.getValues();
255         assertEquals(1, values.size());
256
257         AttributeValue<?> value = values.iterator().next();
258         return ((Number) value.getValue()).intValue();
259     }
260
261     /**
262      * Close the entity manager.
263      */
264     @AfterClass
265     public static void cleanup() {
266         if (emf != null) {
267             emf.close();
268         }
269     }
270
271     private static class MyPip extends CountRecentOperationsPip {
272
273         @Override
274         protected String getActor(PIPFinder pipFinder) {
275             return ACTOR;
276         }
277
278         @Override
279         protected String getRecipe(PIPFinder pipFinder) {
280             return RECIPE;
281         }
282
283         @Override
284         protected String getTarget(PIPFinder pipFinder) {
285             return TARGET;
286         }
287     }
288 }