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