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();