2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019-2020 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
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.apex.domains.onap.vcpe;
25 import static org.junit.Assert.assertEquals;
26 import static org.junit.Assert.assertTrue;
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;
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;
53 * The Class AaiAndGuardSimEndpoint.
56 public class OnapVCpeSimEndpoint {
57 private static final XLogger LOGGER = XLoggerFactory.getXLogger(OnapVCpeSimEndpoint.class);
59 private static BlockingQueue<String> appcResponseQueue = new LinkedBlockingQueue<>();
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();
67 private static final Random randomDelayInc = new Random();
69 private static final Gson gson = new GsonBuilder()
70 .registerTypeAdapter(Instant.class, new InstantAsMillisTypeAdapter()).setPrettyPrinting().create();
72 private static final AtomicInteger nextVnfId = new AtomicInteger(0);
73 private static Boolean nextControlLoopMessageIsOnset = true;
78 * @return the response
80 @Path("/pdp/api/Stats")
82 public Response serviceGetStats() {
83 statMessagesReceived.incrementAndGet();
84 String returnString = "{\"GET\": " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived + ",\"POST\": "
85 + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}";
87 return Response.status(200).entity(prettifyJsonString(returnString)).build();
91 * Service guard post request.
93 * @param jsonString the json string
94 * @return the response
96 @Path("/pdp/api/getDecision")
98 public Response serviceGuardPostRequest(final String jsonString) {
99 LOGGER.info("\n*** GUARD REQUEST START ***\n" + jsonString + "\n *** GUARD REQUEST END ***");
101 String target = jsonString.substring(jsonString.indexOf("00000000"));
102 target = target.substring(0, target.indexOf('"'));
104 int thisGuardMessageNumber = guardMessagesReceived.incrementAndGet();
105 postMessagesReceived.incrementAndGet();
107 String responseJsonString = null;
108 if (thisGuardMessageNumber % 2 == 0) {
109 responseJsonString = "{\"decision\": \"PERMIT\", \"details\": \"Decision Permit. OK!\"}";
111 responseJsonString = "{\"decision\": \"DENY\", \"details\": \"Decision Denied. NOK :-(\"}";
114 responseJsonString = prettifyJsonString(responseJsonString);
116 LOGGER.info("\n*** GUARD RESPONSE START ***\n" + target + "\n" + responseJsonString
117 + "\n*** GUARD RESPONSE END ***");
119 return Response.status(200).entity(responseJsonString).build();
123 * AAI named query search request.
124 * http://localhost:54321/aai/v16/search/nodes-query?search-node-type=vserver&filter=vserver-name:EQUALS:
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
131 @Path("aai/v16/search/nodes-query")
133 public Response aaiNamedQuerySearchRequest(@QueryParam("search-node-type") final String searchNodeType,
134 @QueryParam("filter") final String filter) throws IOException {
135 getMessagesReceived.incrementAndGet();
137 LOGGER.info("\n*** AAI NODE QUERY GET START ***\nsearchNodeType=" + searchNodeType + "\nfilter=" + filter
138 + "\n *** AAI REQUEST END ***");
140 String adjustedVserverUuid =
141 "b4fe00ac-1da6-4b00-ac0d-8e8300db" + String.format("%04d", nextVnfId.getAndIncrement());
143 String responseJsonString =
144 TextFileUtils.getTextFileAsString("src/test/resources/aai/SearchNodeTypeResponse.json")
145 .replaceAll("b4fe00ac-1da6-4b00-ac0d-8e8300db0007", adjustedVserverUuid);
147 responseJsonString = prettifyJsonString(responseJsonString);
149 LOGGER.info("\n*** AAI RESPONSE START ***\n" + responseJsonString + "\n *** AAI RESPONSE END ***");
151 return Response.status(200).entity(responseJsonString).build();
155 * AAI named query request on a particular resource.
156 * http://localhost:54321/OnapVCpeSim/sim/aai/v16/query?format=resource
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
163 @Path("aai/v16/query")
165 public Response aaiNamedQueryResourceRequest(@QueryParam("format") final String format, final String jsonString)
167 putMessagesReceived.incrementAndGet();
169 LOGGER.info("\n*** AAI NODE RESOURE POST QUERY START ***\\nformat=" + format + "\njson=" + jsonString
170 + "\n *** AAI REQUEST END ***");
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);
179 responseJsonString = prettifyJsonString(responseJsonString);
181 LOGGER.info("\n*** AAI RESPONSE START ***\n" + responseJsonString + "\n *** AAI RESPONSE END ***");
183 return Response.status(200).entity(responseJsonString).build();
187 * DCAE input of events (simulation of DMaaP).
189 * @param timeout the timeout to wait for
190 * @return the response
191 * @throws IOException on I/O errors
193 @Path("events/unauthenticated.DCAE_CL_OUTPUT/APEX/1")
195 public Response dcaeClOutput(@QueryParam("timeout") final int timeout) throws IOException {
196 getMessagesReceived.incrementAndGet();
198 ThreadUtilities.sleep(timeout - 500);
200 if (nextControlLoopMessageIsOnset) {
201 nextControlLoopMessageIsOnset = false;
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 ***");
207 return Response.status(200).entity(clOnsetEvent).build();
209 nextControlLoopMessageIsOnset = true;
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 ***");
215 return Response.status(200).entity(clAbatedEvent).build();
220 * APPC response events (simulation of DMaaP).
222 * @param timeout the timeout to wait for
223 * @return the response
224 * @throws InterruptedException on queue interrupts
226 @Path("events/APPC_LCM_WRITE/APEX/1")
228 public Response appcResponseOutput(@QueryParam("timeout") final int timeout) throws InterruptedException {
229 getMessagesReceived.incrementAndGet();
231 int timeLeft = timeout - 500;
234 String appcResponse = appcResponseQueue.poll(100, TimeUnit.MILLISECONDS);
236 if (appcResponse != null) {
237 LOGGER.info("\n*** CONTROLLER RESPONSE START ***");
238 System.err.println(appcResponse);
239 LOGGER.info("\n*** CONTROLLER RESPONSE END ***");
241 return Response.status(200).entity(appcResponse).build();
244 } while (timeLeft > 0);
246 return Response.status(200).build();
250 * Post to Policy management log (Simulation of DMaaP).
252 * @param jsonString the json string
253 * @return the response
255 @Path("/events/POLICY_CL_MGT")
257 public Response policyLogRequest(final String jsonString) {
258 postMessagesReceived.incrementAndGet();
260 String logJsonString = prettifyJsonString(jsonString);
262 LOGGER.info("\n*** POLICY LOG ENTRY START ***\n" + logJsonString + "\n *** POLICY LOG ENTRY END ***");
264 return Response.status(200).build();
268 * Post to APPC LCM (Simulation of DMaaP).
270 * @param jsonString the json string
271 * @return the response
273 @Path("/events/APPC-LCM-READ")
275 public Response appcRequest(final String jsonString) {
276 postMessagesReceived.incrementAndGet();
278 String appcJsonString = prettifyJsonString(jsonString);
280 LOGGER.info("\n*** CONTROLLER REQUEST START ***\n" + appcJsonString + "\n *** CONTROLLER REQUEST END ***");
282 new AppcResponseCreator(appcResponseQueue, appcJsonString, 10000 + randomDelayInc.nextInt(10000));
284 return Response.status(200).build();
288 * Post to BLACK WHITE LIST READ (Simulation of DMaaP).
290 * @param jsonString the json string
291 * @return the response
293 @Path("/events/BLACK-WHITE-LIST-READ")
295 public Response blackWhiteListRead(final String jsonString) {
296 postMessagesReceived.incrementAndGet();
298 String bwJsonString = prettifyJsonString(jsonString);
300 LOGGER.info("\n*** BLACK WHITE LIST START ***\n" + bwJsonString + "\n *** BLACK WHITE LIST END ***");
302 return Response.status(200).build();
308 * @return the response
310 @Path("/event/GetEvent")
312 public Response serviceGetEvent() {
313 final Random rand = new Random();
314 final int nextMatchCase = rand.nextInt(4);
315 final String nextEventName = "Event0" + rand.nextInt(2) + "00";
317 final String eventString = "{\n" + "\"nameSpace\": \"org.onap.policy.apex.sample.events\",\n" + "\"name\": \""
318 + nextEventName + "\",\n" + "\"version\": \"0.0.1\",\n" + "\"source\": \"REST_" + getMessagesReceived
319 + "\",\n" + "\"target\": \"apex\",\n" + "\"TestSlogan\": \"Test slogan for External Event0\",\n"
320 + "\"TestMatchCase\": " + nextMatchCase + ",\n" + "\"TestTimestamp\": " + System.currentTimeMillis()
321 + ",\n" + "\"TestTemperature\": 9080.866\n" + "}";
323 getMessagesReceived.incrementAndGet();
325 return Response.status(200).entity(eventString).build();
329 * Service get empty event.
331 * @return the response
333 @Path("/event/GetEmptyEvent")
335 public Response serviceGetEmptyEvent() {
336 return Response.status(200).build();
340 * Service get event bad response.
342 * @return the response
344 @Path("/event/GetEventBadResponse")
346 public Response serviceGetEventBadResponse() {
347 return Response.status(400).build();
351 * Service post request.
353 * @param jsonString the json string
354 * @return the response
356 @Path("/event/PostEvent")
358 public Response servicePostRequest(final String jsonString) {
359 postMessagesReceived.incrementAndGet();
361 @SuppressWarnings("unchecked")
362 final Map<String, Object> jsonMap = gson.fromJson(jsonString, Map.class);
363 assertTrue(jsonMap.containsKey("name"));
364 assertEquals("0.0.1", jsonMap.get("version"));
365 assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace"));
366 assertEquals("Act", jsonMap.get("source"));
367 assertEquals("Outside", jsonMap.get("target"));
369 return Response.status(200).entity("{\"GET\": , " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived
370 + ",\"POST\": , " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}").build();
374 * Service post request bad response.
376 * @param jsonString the json string
377 * @return the response
379 @Path("/event/PostEventBadResponse")
381 public Response servicePostRequestBadResponse(final String jsonString) {
382 return Response.status(400).build();
386 * Service put request.
388 * @param jsonString the json string
389 * @return the response
391 @Path("/event/PutEvent")
393 public Response servicePutRequest(final String jsonString) {
394 putMessagesReceived.incrementAndGet();
396 @SuppressWarnings("unchecked")
397 final Map<String, Object> jsonMap = gson.fromJson(jsonString, Map.class);
398 assertTrue(jsonMap.containsKey("name"));
399 assertEquals("0.0.1", jsonMap.get("version"));
400 assertEquals("org.onap.policy.apex.sample.events", jsonMap.get("nameSpace"));
401 assertEquals("Act", jsonMap.get("source"));
402 assertEquals("Outside", jsonMap.get("target"));
404 return Response.status(200).entity("{\"GET\": , " + getMessagesReceived + ",\"STAT\": " + statMessagesReceived
405 + ",\"POST\": , " + postMessagesReceived + ",\"PUT\": " + putMessagesReceived + "}").build();
408 private static final String prettifyJsonString(final String uglyJsonString) {
409 JsonElement je = JsonParser.parseString(uglyJsonString);
410 return gson.toJson(je);