1e372112f112eb2902eb948e510ce42d01e3d2bb
[so.git] / common / src / main / java / org / onap / so / client / cds / CDSProcessingClient.java
1 /*
2  * Copyright (C) 2019 Bell Canada.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.onap.so.client.cds;
17
18 import io.grpc.ManagedChannel;
19 import io.grpc.internal.DnsNameResolverProvider;
20 import io.grpc.internal.PickFirstLoadBalancerProvider;
21 import io.grpc.netty.NettyChannelBuilder;
22 import java.util.concurrent.CountDownLatch;
23 import org.onap.ccsdk.apps.controllerblueprints.processing.api.ExecutionServiceInput;
24 import org.onap.so.client.PreconditionFailedException;
25 import org.onap.so.client.RestPropertiesLoader;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * <p>
31  * The CDS processing client is using gRPC for communication between SO and CDS.
32  * That communication is configured to use a streaming approach, meaning that
33  * client can send an event to which server can reply will multiple sub-responses,
34  * until full completion of the processing.
35  * </p>
36  * <p>
37  * In order for the caller to manage the callback, it is the responsibility of the
38  * caller to implement and provide a {@link CDSProcessingListener} so received messages
39  * can be handled appropriately.
40  * </p>
41  *
42  * Here is an example of implementation of such listener:
43  * <pre>
44  * new CDSProcessingListener {
45  *
46  *     &#64;Override
47  *     public void onMessage(ExecutionServiceOutput message) {
48  *         log.info("Received notification from CDS: {}", message);
49  *     }
50  *
51  *     &#64;Override
52  *     public void onError(Throwable t) {
53  *         Status status = Status.fromThrowable(t);
54  *         log.error("Failed processing blueprint {}", status, t);
55  *     }
56  * }
57  * </pre>
58  */
59 public class CDSProcessingClient implements AutoCloseable {
60
61     private static final Logger log = LoggerFactory.getLogger(CDSProcessingClient.class);
62
63     private ManagedChannel channel;
64     private CDSProcessingHandler handler;
65
66     public CDSProcessingClient(final CDSProcessingListener listener) {
67         CDSProperties props = RestPropertiesLoader.getInstance().getNewImpl(CDSProperties.class);
68         if (props == null) {
69             throw new PreconditionFailedException(
70                 "No RestProperty.CDSProperties implementation found on classpath, can't create client.");
71         }
72         this.channel = NettyChannelBuilder
73             .forAddress(props.getHost(), props.getPort())
74             .nameResolverFactory(new DnsNameResolverProvider())
75             .loadBalancerFactory(new PickFirstLoadBalancerProvider())
76             .intercept(new BasicAuthClientInterceptor(props))
77             .usePlaintext()
78             .build();
79         this.handler = new CDSProcessingHandler(listener);
80         log.info("CDSProcessingClient started");
81     }
82
83     CDSProcessingClient(final ManagedChannel channel, final CDSProcessingHandler handler) {
84         this.channel = channel;
85         this.handler = handler;
86     }
87
88     /**
89      * Sends a request to the CDS backend micro-service.
90      *
91      * The caller will be returned a CountDownLatch that can be used
92      * to define how long the processing can wait. The CountDownLatch is
93      * initiated with just 1 count. When the client receives an #onCompleted callback,
94      * the counter will decrement.
95      *
96      * It is the user responsibility to close the client.
97      *
98      * @param input request to send
99      * @return CountDownLatch instance that can be use to #await for
100      * completeness of processing
101      */
102     public CountDownLatch sendRequest(ExecutionServiceInput input) {
103         return handler.process(input, channel);
104     }
105
106     @Override
107     public void close() {
108         if (channel != null) {
109             channel.shutdown();
110         }
111         log.info("CDSProcessingClient stopped");
112     }
113 }