2 * ============LICENSE_START=======================================================
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
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.
18 * ============LICENSE_END=========================================================
21 package org.onap.policy.controlloop.actor.sdnc;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNotNull;
27 import java.util.Properties;
28 import java.util.concurrent.CompletableFuture;
29 import java.util.concurrent.ExecutionException;
30 import java.util.concurrent.TimeUnit;
31 import java.util.concurrent.TimeoutException;
32 import javax.ws.rs.Consumes;
33 import javax.ws.rs.POST;
34 import javax.ws.rs.Path;
35 import javax.ws.rs.Produces;
36 import javax.ws.rs.core.Response;
37 import javax.ws.rs.core.Response.Status;
39 import org.junit.After;
40 import org.junit.AfterClass;
41 import org.junit.Before;
42 import org.junit.BeforeClass;
43 import org.junit.Test;
44 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams;
45 import org.onap.policy.common.endpoints.event.comm.bus.internal.BusTopicParams.TopicParamsBuilder;
46 import org.onap.policy.common.endpoints.http.client.HttpClient;
47 import org.onap.policy.common.endpoints.http.client.HttpClientFactoryInstance;
48 import org.onap.policy.common.endpoints.http.server.HttpServletServer;
49 import org.onap.policy.common.endpoints.http.server.HttpServletServerFactoryInstance;
50 import org.onap.policy.common.endpoints.properties.PolicyEndPointProperties;
51 import org.onap.policy.common.gson.GsonMessageBodyHandler;
52 import org.onap.policy.common.utils.coder.CoderException;
53 import org.onap.policy.common.utils.coder.StandardCoder;
54 import org.onap.policy.common.utils.network.NetworkUtil;
55 import org.onap.policy.controlloop.VirtualControlLoopEvent;
56 import org.onap.policy.controlloop.actorserviceprovider.OperationOutcome;
57 import org.onap.policy.controlloop.actorserviceprovider.Util;
58 import org.onap.policy.controlloop.actorserviceprovider.controlloop.ControlLoopEventContext;
59 import org.onap.policy.controlloop.actorserviceprovider.parameters.ControlLoopOperationParams;
60 import org.onap.policy.controlloop.actorserviceprovider.parameters.HttpParams;
61 import org.onap.policy.controlloop.policy.PolicyResult;
62 import org.onap.policy.sdnc.SdncHealRequest;
63 import org.onap.policy.sdnc.SdncRequest;
64 import org.onap.policy.sdnc.SdncResponse;
65 import org.onap.policy.sdnc.SdncResponseOutput;
67 public class SdncOperatorTest {
68 public static final String MEDIA_TYPE_APPLICATION_JSON = "application/json";
69 private static final String EXPECTED_EXCEPTION = "expected exception";
70 public static final String HTTP_CLIENT = "my-http-client";
71 public static final String HTTP_NO_SERVER = "my-http-no-server-client";
72 private static final String ACTOR = "my-actor";
73 private static final String OPERATION = "my-operation";
76 * Outcome to be added to the response.
79 private static SdncResponseOutput output;
82 private VirtualControlLoopEvent event;
83 private ControlLoopEventContext context;
87 * Starts the SDNC simulator.
90 public static void setUpBeforeClass() throws Exception {
92 int port = NetworkUtil.allocPort();
95 * Start the simulator. Must use "Properties" to configure it, otherwise the
96 * server will use the wrong serialization provider.
98 Properties svrprops = getServerProperties("my-server", port);
99 HttpServletServerFactoryInstance.getServerFactory().build(svrprops).forEach(HttpServletServer::start);
102 * Start the clients, one to the server, and one to a non-existent server.
104 TopicParamsBuilder builder = BusTopicParams.builder().managed(true).hostname("localhost").basePath("sdnc")
105 .serializationProvider(GsonMessageBodyHandler.class.getName());
107 HttpClientFactoryInstance.getClientFactory().build(builder.clientName(HTTP_CLIENT).port(port).build());
109 HttpClientFactoryInstance.getClientFactory()
110 .build(builder.clientName(HTTP_NO_SERVER).port(NetworkUtil.allocPort()).build());
114 public static void tearDownAfterClass() {
115 HttpClientFactoryInstance.getClientFactory().destroy();
116 HttpServletServerFactoryInstance.getServerFactory().destroy();
120 * Initializes {@link #oper} and sets {@link #output} to a success code.
123 public void setUp() {
124 event = new VirtualControlLoopEvent();
125 context = new ControlLoopEventContext(event);
127 initOper(HTTP_CLIENT);
129 output = new SdncResponseOutput();
130 output.setResponseCode("200");
134 public void tearDown() {
139 public void testSdncOperator() {
140 assertEquals(ACTOR, oper.getActorName());
141 assertEquals(OPERATION, oper.getName());
142 assertEquals(ACTOR + "." + OPERATION, oper.getFullName());
146 public void testGetClient() {
147 assertNotNull(oper.getTheClient());
151 public void testStartOperationAsync_testPostRequest() throws Exception {
152 OperationOutcome outcome = runOperation();
153 assertNotNull(outcome);
154 assertEquals(PolicyResult.SUCCESS, outcome.getResult());
158 * Tests postRequest() when decode() throws an exception.
161 public void testPostRequestDecodeException() throws Exception {
163 oper.setDecodeFailure(true);
165 OperationOutcome outcome = runOperation();
166 assertNotNull(outcome);
167 assertEquals(PolicyResult.FAILURE_EXCEPTION, outcome.getResult());
171 * Tests postRequest() when there is no "output" field in the response.
174 public void testPostRequestNoOutput() throws Exception {
178 OperationOutcome outcome = runOperation();
179 assertNotNull(outcome);
180 assertEquals(PolicyResult.FAILURE, outcome.getResult());
184 * Tests postRequest() when the output is not a success.
187 public void testPostRequestOutputFailure() throws Exception {
189 output.setResponseCode(null);
191 OperationOutcome outcome = runOperation();
192 assertNotNull(outcome);
193 assertEquals(PolicyResult.FAILURE, outcome.getResult());
197 * Tests postRequest() when the post() request throws an exception retrieving the
201 public void testPostRequestException() throws Exception {
203 // reset "oper" to point to a non-existent server
205 initOper(HTTP_NO_SERVER);
207 OperationOutcome outcome = runOperation();
208 assertNotNull(outcome);
209 assertEquals(PolicyResult.FAILURE_EXCEPTION, outcome.getResult());
212 private static Properties getServerProperties(String name, int port) {
213 final Properties props = new Properties();
214 props.setProperty(PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES, name);
216 final String svcpfx = PolicyEndPointProperties.PROPERTY_HTTP_SERVER_SERVICES + "." + name;
218 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_REST_CLASSES_SUFFIX, Server.class.getName());
219 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_HOST_SUFFIX, "localhost");
220 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_PORT_SUFFIX, String.valueOf(port));
221 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_MANAGED_SUFFIX, "true");
222 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SWAGGER_SUFFIX, "false");
224 props.setProperty(svcpfx + PolicyEndPointProperties.PROPERTY_HTTP_SERIALIZATION_PROVIDER,
225 GsonMessageBodyHandler.class.getName());
230 * Initializes {@link #oper}.
232 * @param clientName name of the client which it should use
234 private void initOper(String clientName) {
237 HttpParams params = HttpParams.builder().clientName(clientName).path("request").build();
238 Map<String, Object> mapParams = Util.translateToMap(OPERATION, params);
239 oper.configure(mapParams);
244 * Runs the operation.
246 * @return the outcome of the operation, or {@code null} if it does not complete in
249 private OperationOutcome runOperation() throws InterruptedException, ExecutionException, TimeoutException {
250 ControlLoopOperationParams params =
251 ControlLoopOperationParams.builder().actor(ACTOR).operation(OPERATION).context(context).build();
253 CompletableFuture<OperationOutcome> future = oper.startOperationAsync(params, 1, params.makeOutcome());
255 return future.get(5, TimeUnit.SECONDS);
259 private class MyOper extends SdncOperator {
262 * Set to {@code true} to cause the decoder to throw an exception.
265 private boolean decodeFailure = false;
268 super(ACTOR, OPERATION);
271 protected HttpClient getTheClient() {
276 protected SdncRequest constructRequest(ControlLoopEventContext context) {
277 SdncRequest request = new SdncRequest();
279 SdncHealRequest heal = new SdncHealRequest();
280 request.setHealRequest(heal);
286 protected StandardCoder makeDecoder() {
288 // return a coder that throws exceptions when decode() is invoked
289 return new StandardCoder() {
291 public <T> T decode(String json, Class<T> clazz) throws CoderException {
292 throw new CoderException(EXPECTED_EXCEPTION);
297 return super.makeDecoder();
306 @Produces(MEDIA_TYPE_APPLICATION_JSON)
307 public static class Server {
310 * Generates a response.
312 * @param request incoming request
313 * @return resulting response
317 @Consumes(value = {MEDIA_TYPE_APPLICATION_JSON})
318 public Response postRequest(SdncRequest request) {
320 SdncResponse response = new SdncResponse();
321 response.setResponseOutput(output);
323 return Response.status(Status.OK).entity(response).build();