blob: 9936ff68107d2b346c6698ef3d071c385b965042 [file] [log] [blame]
Yi Tseng890dc3f2018-11-01 13:23:11 -07001/*
2 * Copyright 2018-present Open Networking Foundation
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 */
16package protocols.gnmi.ctl.java.org.onosproject.gnmi.ctl;
17
18import gnmi.Gnmi.CapabilityRequest;
19import gnmi.Gnmi.CapabilityResponse;
20import gnmi.Gnmi.GetRequest;
21import gnmi.Gnmi.GetResponse;
Yi Tseng5f7fef52018-11-05 11:30:47 -080022import gnmi.Gnmi.Path;
23import gnmi.Gnmi.PathElem;
Yi Tseng890dc3f2018-11-01 13:23:11 -070024import gnmi.Gnmi.SetRequest;
25import gnmi.Gnmi.SetResponse;
Yi Tsenge616d752018-11-27 10:53:27 -080026import gnmi.Gnmi.SubscribeRequest;
Yi Tseng890dc3f2018-11-01 13:23:11 -070027import gnmi.gNMIGrpc;
28import io.grpc.ManagedChannel;
Yi Tseng5f7fef52018-11-05 11:30:47 -080029import io.grpc.Status;
Yi Tseng890dc3f2018-11-01 13:23:11 -070030import io.grpc.StatusRuntimeException;
Yi Tsengd7716482018-10-31 15:34:30 -070031import org.onosproject.gnmi.api.GnmiClient;
Yi Tseng890dc3f2018-11-01 13:23:11 -070032import org.onosproject.gnmi.api.GnmiClientKey;
33import org.onosproject.grpc.ctl.AbstractGrpcClient;
34import org.slf4j.Logger;
Yi Tseng890dc3f2018-11-01 13:23:11 -070035
36import java.util.concurrent.CompletableFuture;
37
38import static org.slf4j.LoggerFactory.getLogger;
39
40/**
41 * Implementation of gNMI client.
42 */
43public class GnmiClientImpl extends AbstractGrpcClient implements GnmiClient {
Yi Tseng5f7fef52018-11-05 11:30:47 -080044 private static final PathElem DUMMY_PATH_ELEM = PathElem.newBuilder().setName("onos-gnmi-test").build();
45 private static final Path DUMMY_PATH = Path.newBuilder().addElem(DUMMY_PATH_ELEM).build();
46 private static final GetRequest DUMMY_REQUEST = GetRequest.newBuilder().addPath(DUMMY_PATH).build();
Yi Tseng890dc3f2018-11-01 13:23:11 -070047 private final Logger log = getLogger(getClass());
48 private final gNMIGrpc.gNMIBlockingStub blockingStub;
Yi Tsenga7f76c12018-12-14 14:19:18 -080049 private GnmiSubscriptionManager gnmiSubscriptionManager;
Yi Tseng890dc3f2018-11-01 13:23:11 -070050
Yi Tsenge616d752018-11-27 10:53:27 -080051 GnmiClientImpl(GnmiClientKey clientKey, ManagedChannel managedChannel, GnmiControllerImpl controller) {
Yi Tsengd7716482018-10-31 15:34:30 -070052 super(clientKey);
Yi Tseng890dc3f2018-11-01 13:23:11 -070053 this.blockingStub = gNMIGrpc.newBlockingStub(managedChannel);
Yi Tsenga7f76c12018-12-14 14:19:18 -080054 this.gnmiSubscriptionManager =
55 new GnmiSubscriptionManager(managedChannel, deviceId, controller);
Yi Tseng890dc3f2018-11-01 13:23:11 -070056 }
57
58 @Override
59 public CompletableFuture<CapabilityResponse> capability() {
60 return supplyInContext(this::doCapability, "capability");
61 }
62
63 @Override
64 public CompletableFuture<GetResponse> get(GetRequest request) {
65 return supplyInContext(() -> doGet(request), "get");
66 }
67
68 @Override
69 public CompletableFuture<SetResponse> set(SetRequest request) {
70 return supplyInContext(() -> doSet(request), "set");
71 }
72
Yi Tseng5f7fef52018-11-05 11:30:47 -080073 @Override
Yi Tsenge616d752018-11-27 10:53:27 -080074 public boolean subscribe(SubscribeRequest request) {
Yi Tsenga7f76c12018-12-14 14:19:18 -080075 return gnmiSubscriptionManager.subscribe(request);
Yi Tsenge616d752018-11-27 10:53:27 -080076 }
77
78 @Override
79 public void terminateSubscriptionChannel() {
Yi Tsenga7f76c12018-12-14 14:19:18 -080080 gnmiSubscriptionManager.complete();
Yi Tsenge616d752018-11-27 10:53:27 -080081 }
82
83 @Override
Yi Tseng5f7fef52018-11-05 11:30:47 -080084 public CompletableFuture<Boolean> isServiceAvailable() {
85 return supplyInContext(this::doServiceAvailable, "isServiceAvailable");
86 }
87
Yi Tsenge616d752018-11-27 10:53:27 -080088 @Override
89 protected Void doShutdown() {
Yi Tsenga7f76c12018-12-14 14:19:18 -080090 gnmiSubscriptionManager.shutdown();
Yi Tsenge616d752018-11-27 10:53:27 -080091 return super.doShutdown();
92 }
93
Yi Tseng890dc3f2018-11-01 13:23:11 -070094 private CapabilityResponse doCapability() {
95 CapabilityRequest request = CapabilityRequest.newBuilder().build();
96 try {
97 return blockingStub.capabilities(request);
98 } catch (StatusRuntimeException e) {
99 log.warn("Unable to get capability from {}: {}", deviceId, e.getMessage());
Yi Tseng59d5f3e2018-11-27 23:09:41 -0800100 return CapabilityResponse.getDefaultInstance();
Yi Tseng890dc3f2018-11-01 13:23:11 -0700101 }
102 }
103
104 private GetResponse doGet(GetRequest request) {
105 try {
106 return blockingStub.get(request);
107 } catch (StatusRuntimeException e) {
108 log.warn("Unable to get data from {}: {}", deviceId, e.getMessage());
Yi Tseng59d5f3e2018-11-27 23:09:41 -0800109 return GetResponse.getDefaultInstance();
Yi Tseng890dc3f2018-11-01 13:23:11 -0700110 }
111 }
112
113 private SetResponse doSet(SetRequest request) {
114 try {
115 return blockingStub.set(request);
116 } catch (StatusRuntimeException e) {
117 log.warn("Unable to set data to {}: {}", deviceId, e.getMessage());
Yi Tseng59d5f3e2018-11-27 23:09:41 -0800118 return SetResponse.getDefaultInstance();
Yi Tseng890dc3f2018-11-01 13:23:11 -0700119 }
120 }
Yi Tseng5f7fef52018-11-05 11:30:47 -0800121
122 private boolean doServiceAvailable() {
123 try {
Yi Tsengd7716482018-10-31 15:34:30 -0700124 return blockingStub.get(DUMMY_REQUEST) != null;
Yi Tseng5f7fef52018-11-05 11:30:47 -0800125 } catch (StatusRuntimeException e) {
126 // This gRPC call should throw INVALID_ARGUMENT status exception
127 // since "/onos-gnmi-test" path does not exists in any config model
128 // For other status code such as UNIMPLEMENT, means the gNMI
129 // service is not available on the device.
130 return e.getStatus().getCode().equals(Status.Code.INVALID_ARGUMENT);
131 }
132 }
Yi Tseng890dc3f2018-11-01 13:23:11 -0700133}