Merge "Adding basic logging to CDS Simulator"
[policy/models.git] / models-interactions / model-simulators / src / main / java / org / onap / policy / simulators / CdsSimulator.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2020 Nordix Foundation.
4  *  Modifications Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
5  *  Modifications Copyright (C) 2020 Bell Canada. 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.simulators;
24
25 import com.google.protobuf.InvalidProtocolBufferException;
26 import com.google.protobuf.util.JsonFormat;
27 import io.grpc.Server;
28 import io.grpc.netty.NettyServerBuilder;
29 import io.grpc.stub.StreamObserver;
30 import java.io.IOException;
31 import java.net.InetSocketAddress;
32 import java.util.concurrent.TimeUnit;
33 import java.util.concurrent.atomic.AtomicInteger;
34 import lombok.Getter;
35 import org.apache.commons.lang3.StringUtils;
36 import org.onap.ccsdk.cds.controllerblueprints.common.api.ActionIdentifiers;
37 import org.onap.ccsdk.cds.controllerblueprints.processing.api.BluePrintProcessingServiceGrpc.BluePrintProcessingServiceImplBase;
38 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput;
39 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput;
40 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceOutput.Builder;
41 import org.onap.policy.common.utils.resources.ResourceUtils;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44
45 public class CdsSimulator {
46
47     private static final Logger LOGGER = LoggerFactory.getLogger(CdsSimulator.class);
48
49     @Getter
50     private final int port;
51
52     private final Server server;
53
54     private final String resourceLocation;
55
56     private AtomicInteger countOfEvents = new AtomicInteger(1);
57
58     /**
59      * Constructs the object, but does not start it.
60      *
61      * @param host host name of the server
62      * @param port port of the server
63      */
64     public CdsSimulator(String host, int port) {
65         this(host, port, "org/onap/policy/simulators/cds/", 0, 0);
66     }
67
68     /**
69      * Constructs the object, but does not start it.
70      *
71      * @param host host name of the server
72      * @param port port of the server
73      * @param countOfSuccesfulEvents number of successive successful events
74      * @param requestedResponseDelayMs time for the request to be processed
75      */
76     public CdsSimulator(String host, int port, String resourceLocation, int countOfSuccesfulEvents,
77         long requestedResponseDelayMs) {
78         this.port = port;
79         this.resourceLocation = resourceLocation;
80
81         BluePrintProcessingServiceImplBase testCdsBlueprintServerImpl = new BluePrintProcessingServiceImplBase() {
82
83             @Override
84             public StreamObserver<ExecutionServiceInput> process(
85                             final StreamObserver<ExecutionServiceOutput> responseObserver) {
86
87                 return new StreamObserver<ExecutionServiceInput>() {
88
89                     @Override
90                     public void onNext(final ExecutionServiceInput executionServiceInput) {
91                         LOGGER.info("Received request input to CDS: {}", executionServiceInput);
92                         try {
93                             String responseString = getResponseString(executionServiceInput, countOfSuccesfulEvents);
94                             Builder builder = ExecutionServiceOutput.newBuilder();
95                             JsonFormat.parser().ignoringUnknownFields().merge(responseString, builder);
96                             TimeUnit.MILLISECONDS.sleep(requestedResponseDelayMs);
97                             responseObserver.onNext(builder.build());
98                         } catch (InvalidProtocolBufferException e) {
99                             throw new SimulatorRuntimeException("Cannot convert ExecutionServiceOutput output", e);
100                         } catch (InterruptedException e) {
101                             Thread.currentThread().interrupt();
102                             throw new SimulatorRuntimeException("Execution Interrupted", e);
103                         }
104                     }
105
106                     @Override
107                     public void onError(final Throwable throwable) {
108                         responseObserver.onError(throwable);
109                     }
110
111                     @Override
112                     public void onCompleted() {
113                         responseObserver.onCompleted();
114                     }
115                 };
116             }
117         };
118
119         server = NettyServerBuilder.forAddress(new InetSocketAddress(host, port)).addService(testCdsBlueprintServerImpl)
120                         .build();
121     }
122
123     public void start() throws IOException {
124         server.start();
125     }
126
127     public void stop() {
128         server.shutdown();
129     }
130
131     /**
132      * Constructs the ResponseString on the basis of request.
133      *
134      * @param executionServiceInput service input
135      * @param countOfSuccesfulEvents number of successive successful events
136      * @return  responseString
137      */
138     public String getResponseString(ExecutionServiceInput executionServiceInput, int countOfSuccesfulEvents) {
139         String resourceName = "DefaultResponseEvent";
140         if (!StringUtils.isBlank(executionServiceInput.getActionIdentifiers().getActionName())) {
141             ActionIdentifiers actionIdentifiers = executionServiceInput.getActionIdentifiers();
142             resourceName = actionIdentifiers.getBlueprintName() + "-" + actionIdentifiers.getActionName();
143         }
144         if (countOfSuccesfulEvents > 0 && countOfEvents.getAndIncrement() % countOfSuccesfulEvents == 0) {
145             // generating the failure response
146             resourceName = resourceName + "-error.json";
147         } else {
148             resourceName = resourceName + ".json";
149         }
150         LOGGER.info("Fetching response from {}", resourceName);
151         String responseString = ResourceUtils.getResourceAsString(resourceLocation + resourceName);
152         if (responseString == null) {
153             LOGGER.info("Expected response file {} not found in {}", resourceName, resourceLocation);
154             responseString = ResourceUtils.getResourceAsString(resourceLocation
155                 + "DefaultResponseEvent.json");
156         }
157         LOGGER.debug("Returning response from CDS Simulator: {}", responseString);
158         return responseString;
159     }
160 }