f228ccd768b585f84fa39421b0ce39c1fc24b36f
[policy/apex-pdp.git] / examples / examples-onap-vcpe / src / test / java / org / onap / policy / apex / domains / onap / vcpe / OnapVCpeSimEndpoint.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019-2020 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.domains.onap.vcpe;
23
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertTrue;
26
27 import com.google.gson.Gson;
28 import com.google.gson.GsonBuilder;
29 import com.google.gson.JsonElement;
30 import com.google.gson.JsonParser;
31
32 import java.io.IOException;
33 import java.time.Instant;
34 import java.util.Map;
35 import java.util.Random;
36 import java.util.concurrent.BlockingQueue;
37 import java.util.concurrent.LinkedBlockingQueue;
38 import java.util.concurrent.TimeUnit;
39 import java.util.concurrent.atomic.AtomicInteger;
40
41 import javax.ws.rs.GET;
42 import javax.ws.rs.POST;
43 import javax.ws.rs.PUT;
44 import javax.ws.rs.Path;
45 import javax.ws.rs.QueryParam;
46 import javax.ws.rs.core.Response;
47
48 import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
49 import org.onap.policy.common.utils.resources.TextFileUtils;
50 import org.onap.policy.controlloop.util.Serialization;
51 import org.slf4j.ext.XLogger;
52 import org.slf4j.ext.XLoggerFactory;
53
54 /**
55  * The Class AaiAndGuardSimEndpoint.
56  */
57 @Path("/sim")
58 public class OnapVCpeSimEndpoint {
59     private static final XLogger LOGGER = XLoggerFactory.getXLogger(OnapVCpeSimEndpoint.class);
60
61     private static BlockingQueue<String> appcResponseQueue = new LinkedBlockingQueue<>();
62
63     private static AtomicInteger guardMessagesReceived = new AtomicInteger();
64     private static AtomicInteger postMessagesReceived = new AtomicInteger();
65     private static AtomicInteger putMessagesReceived = new AtomicInteger();
66     private static AtomicInteger statMessagesReceived = new AtomicInteger();
67     private static AtomicInteger getMessagesReceived = new AtomicInteger();
68
69     private static final Random randomDelayInc = new Random();
70
71     private static final Gson gson = new GsonBuilder()
72             .registerTypeAdapter(Instant.class, new Serialization.GsonInstantAdapter()).setPrettyPrinting().create();
73
74     private static final AtomicInteger nextVnfId = new AtomicInteger(0);
75     private static Boolean nextControlLoopMessageIsOnset = true;
76
77     /**
78      * Service get stats.
79      *
80      * @return the response
81      */
82     @Path("/pdp/api/Stats")
83     @GET
84     public Response serviceGetStats() {
85         statMessagesReceived.incrementAndGet();
86         String returnString = "{\"GET\": " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived + ",\"POST\": "
87                 + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}";
88
89         return Response.status(200).entity(prettifyJsonString(returnString)).build();
90     }
91
92     /**
93      * Service guard post request.
94      *
95      * @param jsonString the json string
96      * @return the response
97      */
98     @Path("/pdp/api/getDecision")
99     @POST
100     public Response serviceGuardPostRequest(final String jsonString) {
101         LOGGER.info("\n*** GUARD REQUEST START ***\n" + jsonString + "\n *** GUARD REQUEST END ***");
102
103         String target = jsonString.substring(jsonString.indexOf("00000000"));
104         target = target.substring(0, target.indexOf('"'));
105
106         int thisGuardMessageNumber = guardMessagesReceived.incrementAndGet();
107         postMessagesReceived.incrementAndGet();
108
109         String responseJsonString = null;
110         if (thisGuardMessageNumber % 2 == 0) {
111             responseJsonString = "{\"decision\": \"PERMIT\", \"details\": \"Decision Permit. OK!\"}";
112         } else {
113             responseJsonString = "{\"decision\": \"DENY\", \"details\": \"Decision Denied. NOK :-(\"}";
114         }
115
116         responseJsonString = prettifyJsonString(responseJsonString);
117
118         LOGGER.info("\n*** GUARD RESPONSE START ***\n" + target + "\n" + responseJsonString
119                 + "\n*** GUARD RESPONSE END ***");
120
121         return Response.status(200).entity(responseJsonString).build();
122     }
123
124     /**
125      * AAI named query search request.
126      * http://localhost:54321/aai/v16/search/nodes-query?search-node-type=vserver&filter=vserver-name:EQUALS:
127      *
128      * @param searchNodeType the node type to search for
129      * @param filter the filter to apply in the search
130      * @return the response
131      * @throws IOException on I/O errors
132      */
133     @Path("aai/v16/search/nodes-query")
134     @GET
135     public Response aaiNamedQuerySearchRequest(@QueryParam("search-node-type") final String searchNodeType,
136             @QueryParam("filter") final String filter) throws IOException {
137         getMessagesReceived.incrementAndGet();
138
139         LOGGER.info("\n*** AAI NODE QUERY GET START ***\nsearchNodeType=" + searchNodeType + "\nfilter=" + filter
140                 + "\n *** AAI REQUEST END ***");
141
142         String adjustedVserverUuid =
143                 "b4fe00ac-1da6-4b00-ac0d-8e8300db" + String.format("%04d", nextVnfId.getAndIncrement());
144
145         String responseJsonString =
146                 TextFileUtils.getTextFileAsString("src/test/resources/aai/SearchNodeTypeResponse.json")
147                         .replaceAll("b4fe00ac-1da6-4b00-ac0d-8e8300db0007", adjustedVserverUuid);
148
149         responseJsonString = prettifyJsonString(responseJsonString);
150
151         LOGGER.info("\n*** AAI RESPONSE START ***\n" + responseJsonString + "\n *** AAI RESPONSE END ***");
152
153         return Response.status(200).entity(responseJsonString).build();
154     }
155
156     /**
157      * AAI named query request on a particular resource.
158      * http://localhost:54321/OnapVCpeSim/sim/aai/v16/query?format=resource
159      *
160      * @param format the format of the request
161      * @param jsonString the body of the request
162      * @return the response
163      * @throws IOException on I/O errors
164      */
165     @Path("aai/v16/query")
166     @PUT
167     public Response aaiNamedQueryResourceRequest(@QueryParam("format") final String format, final String jsonString)
168             throws IOException {
169         putMessagesReceived.incrementAndGet();
170
171         LOGGER.info("\n*** AAI NODE RESOURE POST QUERY START ***\\nformat=" + format + "\njson=" + jsonString
172                 + "\n *** AAI REQUEST END ***");
173
174         int beginIndex =
175                 jsonString.indexOf("b4fe00ac-1da6-4b00-ac0d-8e8300db") + "b4fe00ac-1da6-4b00-ac0d-8e8300db".length();
176         String nextVnfIdUrlEnding = jsonString.substring(beginIndex, beginIndex + 4);
177         String responseJsonString = TextFileUtils.getTextFileAsString("src/test/resources/aai/NodeQueryResponse.json")
178                 .replaceAll("bbb3cefd-01c8-413c-9bdd-2b92f9ca3d38",
179                         "00000000-0000-0000-0000-00000000" + nextVnfIdUrlEnding);
180
181         responseJsonString = prettifyJsonString(responseJsonString);
182
183         LOGGER.info("\n*** AAI RESPONSE START ***\n" + responseJsonString + "\n *** AAI RESPONSE END ***");
184
185         return Response.status(200).entity(responseJsonString).build();
186     }
187
188     /**
189      * DCAE input of events (simulation of DMaaP).
190      *
191      * @param timeout the timeout to wait for
192      * @return the response
193      * @throws IOException on I/O errors
194      */
195     @Path("events/unauthenticated.DCAE_CL_OUTPUT/APEX/1")
196     @GET
197     public Response dcaeClOutput(@QueryParam("timeout") final int timeout) throws IOException {
198         getMessagesReceived.incrementAndGet();
199
200         ThreadUtilities.sleep(timeout - 500);
201
202         if (nextControlLoopMessageIsOnset) {
203             nextControlLoopMessageIsOnset = false;
204
205             String clOnsetEvent = TextFileUtils
206                     .getTextFileAsString("src/main/resources/examples/events/ONAPvCPEStandalone/CLOnsetEvent.json");
207             LOGGER.info("\n*** CONTROL LOOP ONSET START ***\n" + clOnsetEvent + "\n *** CONTROL LOOP ONSET END ***");
208
209             return Response.status(200).entity(clOnsetEvent).build();
210         } else {
211             nextControlLoopMessageIsOnset = true;
212
213             String clAbatedEvent = TextFileUtils
214                     .getTextFileAsString("src/main/resources/examples/events/ONAPvCPEStandalone/CLAbatedEvent.json");
215             LOGGER.info("\n*** CONTROL LOOP ABATED START ***\n" + clAbatedEvent + "\n *** CONTROL LOOP ABATED END ***");
216
217             return Response.status(200).entity(clAbatedEvent).build();
218         }
219     }
220
221     /**
222      * APPC response events (simulation of DMaaP).
223      *
224      * @param timeout the timeout to wait for
225      * @return the response
226      * @throws InterruptedException on queue interrupts
227      */
228     @Path("events/APPC_LCM_WRITE/APEX/1")
229     @GET
230     public Response appcResponseOutput(@QueryParam("timeout") final int timeout) throws InterruptedException {
231         getMessagesReceived.incrementAndGet();
232
233         int timeLeft = timeout - 500;
234
235         do {
236             String appcResponse = appcResponseQueue.poll(100, TimeUnit.MILLISECONDS);
237
238             if (appcResponse != null) {
239                 LOGGER.info("\n*** CONTROLLER RESPONSE START ***");
240                 System.err.println(appcResponse);
241                 LOGGER.info("\n*** CONTROLLER RESPONSE END ***");
242
243                 return Response.status(200).entity(appcResponse).build();
244             }
245             timeLeft -= 100;
246         }
247         while (timeLeft > 0);
248
249         return Response.status(200).build();
250     }
251
252     /**
253      * Post to Policy management log (Simulation of DMaaP).
254      *
255      * @param jsonString the json string
256      * @return the response
257      */
258     @Path("/events/POLICY_CL_MGT")
259     @POST
260     public Response policyLogRequest(final String jsonString) {
261         postMessagesReceived.incrementAndGet();
262
263         String logJsonString = prettifyJsonString(jsonString);
264
265         LOGGER.info("\n*** POLICY LOG ENTRY START ***\n" + logJsonString + "\n *** POLICY LOG ENTRY END ***");
266
267         return Response.status(200).build();
268     }
269
270     /**
271      * Post to APPC LCM (Simulation of DMaaP).
272      *
273      * @param jsonString the json string
274      * @return the response
275      */
276     @Path("/events/APPC-LCM-READ")
277     @POST
278     public Response appcRequest(final String jsonString) {
279         postMessagesReceived.incrementAndGet();
280
281         String appcJsonString = prettifyJsonString(jsonString);
282
283         LOGGER.info("\n*** CONTROLLER REQUEST START ***\n" + appcJsonString + "\n *** CONTROLLER REQUEST END ***");
284
285         new AppcResponseCreator(appcResponseQueue, appcJsonString, 10000 + randomDelayInc.nextInt(10000));
286
287         return Response.status(200).build();
288     }
289
290     /**
291      * Post to BLACK WHITE LIST READ (Simulation of DMaaP).
292      *
293      * @param jsonString the json string
294      * @return the response
295      */
296     @Path("/events/BLACK-WHITE-LIST-READ")
297     @POST
298     public Response blackWhiteListRead(final String jsonString) {
299         postMessagesReceived.incrementAndGet();
300
301         String bwJsonString = prettifyJsonString(jsonString);
302
303         LOGGER.info("\n*** BLACK WHITE LIST START ***\n" + bwJsonString + "\n *** BLACK WHITE LIST END ***");
304
305         return Response.status(200).build();
306     }
307
308     /**
309      * Service get event.
310      *
311      * @return the response
312      */
313     @Path("/event/GetEvent")
314     @GET
315     public Response serviceGetEvent() {
316         final Random rand = new Random();
317         final int nextMatchCase = rand.nextInt(4);
318         final String nextEventName = "Event0" + rand.nextInt(2) + "00";
319
320         final String eventString = "{\n" + "\"nameSpace\": \"org.onap.policy.apex.sample.events\",\n" + "\"name\": \""
321                 + nextEventName + "\",\n" + "\"version\": \"0.0.1\",\n" + "\"source\": \"REST_" + getMessagesReceived
322                 + "\",\n" + "\"target\": \"apex\",\n" + "\"TestSlogan\": \"Test slogan for External Event0\",\n"
323                 + "\"TestMatchCase\": " + nextMatchCase + ",\n" + "\"TestTimestamp\": " + System.currentTimeMillis()
324                 + ",\n" + "\"TestTemperature\": 9080.866\n" + "}";
325
326         getMessagesReceived.incrementAndGet();
327
328         return Response.status(200).entity(eventString).build();
329     }
330
331     /**
332      * Service get empty event.
333      *
334      * @return the response
335      */
336     @Path("/event/GetEmptyEvent")
337     @GET
338     public Response serviceGetEmptyEvent() {
339         return Response.status(200).build();
340     }
341
342     /**
343      * Service get event bad response.
344      *
345      * @return the response
346      */
347     @Path("/event/GetEventBadResponse")
348     @GET
349     public Response serviceGetEventBadResponse() {
350         return Response.status(400).build();
351     }
352
353     /**
354      * Service post request.
355      *
356      * @param jsonString the json string
357      * @return the response
358      */
359     @Path("/event/PostEvent")
360     @POST
361     public Response servicePostRequest(final String jsonString) {
362         postMessagesReceived.incrementAndGet();
363
364         @SuppressWarnings("unchecked")
365         final Map<String, Object> jsonMap = gson.fromJson(jsonString, Map.class);
366         assertTrue(jsonMap.containsKey("name"));
367         assertEquals("0.0.1", jsonMap.get("version"));
368         assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace"));
369         assertEquals("Act", jsonMap.get("source"));
370         assertEquals("Outside", jsonMap.get("target"));
371
372         return Response.status(200).entity("{\"GET\": , " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived
373                 + ",\"POST\": , " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}").build();
374     }
375
376     /**
377      * Service post request bad response.
378      *
379      * @param jsonString the json string
380      * @return the response
381      */
382     @Path("/event/PostEventBadResponse")
383     @POST
384     public Response servicePostRequestBadResponse(final String jsonString) {
385         return Response.status(400).build();
386     }
387
388     /**
389      * Service put request.
390      *
391      * @param jsonString the json string
392      * @return the response
393      */
394     @Path("/event/PutEvent")
395     @PUT
396     public Response servicePutRequest(final String jsonString) {
397         putMessagesReceived.incrementAndGet();
398
399         @SuppressWarnings("unchecked")
400         final Map<String, Object> jsonMap = gson.fromJson(jsonString, Map.class);
401         assertTrue(jsonMap.containsKey("name"));
402         assertEquals("0.0.1", jsonMap.get("version"));
403         assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace"));
404         assertEquals("Act", jsonMap.get("source"));
405         assertEquals("Outside", jsonMap.get("target"));
406
407         return Response.status(200).entity("{\"GET\": , " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived
408                 + ",\"POST\": , " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}").build();
409     }
410
411     private static final String prettifyJsonString(final String uglyJsonString) {
412         JsonElement je = JsonParser.parseString(uglyJsonString);
413         return gson.toJson(je);
414     }
415 }