2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.ccsdk.features.a1.adapter;
23 import static org.apache.http.HttpStatus.SC_INTERNAL_SERVER_ERROR;
24 import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE;
26 import com.google.common.util.concurrent.Futures;
27 import com.google.common.util.concurrent.ListenableFuture;
28 import java.lang.reflect.Method;
29 import java.util.Properties;
30 import java.util.concurrent.ExecutorService;
31 import java.util.concurrent.Executors;
32 import org.onap.ccsdk.sli.core.sli.provider.MdsalHelper;
33 import org.opendaylight.controller.md.sal.binding.api.NotificationPublishService;
34 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
35 import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;
36 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.A1ADAPTERAPIService;
37 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.DeleteA1PolicyInput;
38 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.DeleteA1PolicyInputBuilder;
39 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.DeleteA1PolicyOutput;
40 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.DeleteA1PolicyOutputBuilder;
41 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyInput;
42 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyInputBuilder;
43 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyOutput;
44 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyOutputBuilder;
45 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyStatusInput;
46 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyStatusInputBuilder;
47 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyStatusOutput;
48 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyStatusOutputBuilder;
49 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyTypeInput;
50 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyTypeInputBuilder;
51 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyTypeOutput;
52 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.GetA1PolicyTypeOutputBuilder;
53 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.PutA1PolicyInput;
54 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.PutA1PolicyInputBuilder;
55 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.PutA1PolicyOutput;
56 import org.opendaylight.yang.gen.v1.org.onap.a1.adapter.rev200122.PutA1PolicyOutputBuilder;
57 import org.opendaylight.yangtools.concepts.Builder;
58 import org.opendaylight.yangtools.yang.common.RpcResult;
59 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
64 * This class implements the generated interface from the YANG model and implements the request model for the A1
65 * interface. This class identifies the Near-RT RIC throughout the IP passed over the payload and calls the
66 * corresponding Near-RT RIC over Rest API.
68 @SuppressWarnings("squid:S1874") // "@Deprecated" code should not be used
69 public class A1AdapterProvider implements AutoCloseable, A1ADAPTERAPIService {
71 private static final String START_OPERATION_MESSAGE = "Start of {}";
72 private static final String END_OPERATION_MESSAGE = "End of {}";
74 private static final String A1_ADAPTER_API = "A1-ADAPTER-API";
75 private static final String RESPONSE_BODY = "responseBody";
76 private static final String RESPONSE_CODE = "response-code";
77 private static final String SYNC = "sync";
79 private static final Logger log = LoggerFactory.getLogger(A1AdapterProvider.class);
81 private static final String APPLICATION_NAME = "a1Adapter-api";
83 private final ExecutorService executor;
84 protected NotificationPublishService notificationService;
85 protected RpcProviderRegistry rpcRegistry;
86 protected BindingAwareBroker.RpcRegistration<A1ADAPTERAPIService> rpcRegistration;
87 private final A1AdapterClient a1AdapterClient;
89 public A1AdapterProvider(final NotificationPublishService notificationPublishService,
90 final RpcProviderRegistry rpcProviderRegistry, final A1AdapterClient a1AdapterClient) {
92 log.info("Creating provider for {}", APPLICATION_NAME);
93 executor = Executors.newFixedThreadPool(1);
94 this.notificationService = notificationPublishService;
95 this.rpcRegistry = rpcProviderRegistry;
96 this.a1AdapterClient = a1AdapterClient;
100 public void initialize() {
101 log.info("Initializing provider for {}", APPLICATION_NAME);
102 rpcRegistration = rpcRegistry.addRpcImplementation(A1ADAPTERAPIService.class, this);
103 log.info("Initialization complete for {}", APPLICATION_NAME);
107 public void close() throws Exception {
108 log.info("Closing provider for {}", APPLICATION_NAME);
110 rpcRegistration.close();
111 log.info("Successfully closed provider for {}", APPLICATION_NAME);
115 public ListenableFuture<RpcResult<DeleteA1PolicyOutput>> deleteA1Policy(DeleteA1PolicyInput deletePolicyInput) {
116 final String svcOperation = "deleteA1Policy";
117 log.info(START_OPERATION_MESSAGE, svcOperation);
118 DeleteA1PolicyOutputBuilder deletePolicyResponse = new DeleteA1PolicyOutputBuilder();
119 setUpAndExecuteOperation(svcOperation, new DeleteA1PolicyInputBuilder(deletePolicyInput), deletePolicyResponse);
121 RpcResult<DeleteA1PolicyOutput> deletePolicyResult =
122 RpcResultBuilder.<DeleteA1PolicyOutput>status(true).withResult(deletePolicyResponse.build()).build();
123 log.info(END_OPERATION_MESSAGE, svcOperation);
124 return Futures.immediateFuture(deletePolicyResult);
128 public ListenableFuture<RpcResult<GetA1PolicyOutput>> getA1Policy(GetA1PolicyInput getPolicyInput) {
129 final String svcOperation = "getA1Policy";
130 log.info(START_OPERATION_MESSAGE, svcOperation);
131 GetA1PolicyOutputBuilder getPolicyResponse = new GetA1PolicyOutputBuilder();
132 setUpAndExecuteOperation(svcOperation, new GetA1PolicyInputBuilder(getPolicyInput), getPolicyResponse);
134 RpcResult<GetA1PolicyOutput> getPolicyResult =
135 RpcResultBuilder.<GetA1PolicyOutput>status(true).withResult(getPolicyResponse.build()).build();
136 log.info(END_OPERATION_MESSAGE, svcOperation);
137 return Futures.immediateFuture(getPolicyResult);
141 public ListenableFuture<RpcResult<GetA1PolicyStatusOutput>> getA1PolicyStatus(
142 GetA1PolicyStatusInput getPolicyStatusInput) {
143 final String svcOperation = "getA1PolicyStatus";
144 log.info(START_OPERATION_MESSAGE, svcOperation);
145 GetA1PolicyStatusOutputBuilder getPolicyStatusResponse = new GetA1PolicyStatusOutputBuilder();
146 setUpAndExecuteOperation(svcOperation, new GetA1PolicyStatusInputBuilder(getPolicyStatusInput),
147 getPolicyStatusResponse);
149 RpcResult<GetA1PolicyStatusOutput> getPolicyStatusResult =
150 RpcResultBuilder.<GetA1PolicyStatusOutput>status(true).withResult(getPolicyStatusResponse.build()).build();
151 log.info(END_OPERATION_MESSAGE, svcOperation);
152 return Futures.immediateFuture(getPolicyStatusResult);
156 public ListenableFuture<RpcResult<GetA1PolicyTypeOutput>> getA1PolicyType(GetA1PolicyTypeInput getPolicyTypeInput) {
157 final String svcOperation = "getA1PolicyType";
158 log.info(START_OPERATION_MESSAGE, svcOperation);
159 GetA1PolicyTypeOutputBuilder getPolicyTypeResponse = new GetA1PolicyTypeOutputBuilder();
160 setUpAndExecuteOperation(svcOperation, new GetA1PolicyTypeInputBuilder(getPolicyTypeInput),
161 getPolicyTypeResponse);
163 RpcResult<GetA1PolicyTypeOutput> getPolicyTypeResult =
164 RpcResultBuilder.<GetA1PolicyTypeOutput>status(true).withResult(getPolicyTypeResponse.build()).build();
165 log.info(END_OPERATION_MESSAGE, svcOperation);
166 return Futures.immediateFuture(getPolicyTypeResult);
170 public ListenableFuture<RpcResult<PutA1PolicyOutput>> putA1Policy(PutA1PolicyInput putPolicyInput) {
171 final String svcOperation = "putA1Policy";
172 log.info(START_OPERATION_MESSAGE, svcOperation);
173 PutA1PolicyOutputBuilder putPolicyResponse = new PutA1PolicyOutputBuilder();
174 setUpAndExecuteOperation(svcOperation, new PutA1PolicyInputBuilder(putPolicyInput), putPolicyResponse);
176 RpcResult<PutA1PolicyOutput> putPolicyResult =
177 RpcResultBuilder.<PutA1PolicyOutput>status(true).withResult(putPolicyResponse.build()).build();
178 log.info(END_OPERATION_MESSAGE, svcOperation);
179 return Futures.immediateFuture(putPolicyResult);
182 private <T> boolean hasGraph(final String svcOperation, Builder<T> response) {
184 return a1AdapterClient.hasGraph(A1_ADAPTER_API, svcOperation, null, SYNC);
185 } catch (Exception e) {
186 log.error("Caught exception looking for service logic, {}", e.getMessage());
187 setHttpResponse(response, SC_INTERNAL_SERVER_ERROR);
192 private <U, T> void setUpAndExecuteOperation(final String svcOperation, Builder<U> inputBuilder,
193 Builder<T> responseBuilder) {
194 log.info("Adding INPUT data for {} input: {}", svcOperation, inputBuilder);
195 // add input to parms
196 Properties parms = new Properties();
197 MdsalHelper.toProperties(parms, inputBuilder.build());
198 logSliParameters(parms);
199 // Call SLI sync method
200 if (hasGraph(svcOperation, responseBuilder)) {
201 log.info("A1AdapterClient has a Directed Graph for '{}'", svcOperation);
202 executeOperation(svcOperation, parms, responseBuilder);
204 log.error("No service logic active for A1Adapter: '{}'", svcOperation);
205 setHttpResponse(responseBuilder, Integer.valueOf(SC_SERVICE_UNAVAILABLE));
209 private <T> void executeOperation(final String svcOperation, Properties parms, Builder<T> response) {
211 Properties responseParms =
212 a1AdapterClient.execute(A1_ADAPTER_API, svcOperation, null, SYNC, response, parms);
213 logResponse(responseParms);
214 setBody(response, responseParms.getProperty(RESPONSE_BODY));
215 setHttpResponse(response, Integer.valueOf(responseParms.getProperty(RESPONSE_CODE)));
216 } catch (Exception e) {
217 log.error("Caught exception executing service logic for {}, {}", svcOperation, e.getMessage());
218 setHttpResponse(response, Integer.valueOf(SC_INTERNAL_SERVER_ERROR));
222 private <T> void setBody(Builder<T> responseBuilder, String body) {
224 Method method = responseBuilder.getClass().getMethod("setBody", String.class);
225 method.invoke(responseBuilder, body);
226 } catch (Exception reflectionException) {
227 throw new MissingResponseMethodRuntimeException(reflectionException);
231 private <T> void setHttpResponse(Builder<T> responseBuilder, Integer response) {
233 Method method = responseBuilder.getClass().getMethod("setHttpStatus", Integer.class);
234 method.invoke(responseBuilder, response);
235 } catch (Exception reflectionException) {
236 throw new MissingResponseMethodRuntimeException(reflectionException);
240 private void logSliParameters(Properties parms) {
241 log.info("Printing SLI parameters to be passed");
242 // iterate properties file to get key-value pairs
243 for (String key : parms.stringPropertyNames()) {
244 String value = parms.getProperty(key);
245 log.info("The SLI parameter in {} is: {}", key, value);
249 private void logResponse(Properties responseParms) {
250 log.info("responseBody::{}", responseParms.getProperty(RESPONSE_BODY));
251 log.info("responseCode::{}", responseParms.getProperty(RESPONSE_CODE));
252 log.info("responseMessage::{}", responseParms.getProperty("response-message"));
255 public class MissingResponseMethodRuntimeException extends RuntimeException {
256 private static final long serialVersionUID = -6803869291161765099L;
258 MissingResponseMethodRuntimeException(Exception e) {