blob: 15836b1b69756e3acaf862016628822556ef8800 [file] [log] [blame]
Andrea Campanella241896c2017-05-10 13:11:04 -07001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Andrea Campanella241896c2017-05-10 13:11:04 -07003 *
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
Andrea Campanella0288c872017-08-07 18:32:51 +020017package org.onosproject.drivers.p4runtime;
Andrea Campanella241896c2017-05-10 13:11:04 -070018
Andrea Campanella378e21a2017-06-07 12:09:59 +020019import org.onosproject.net.DeviceId;
Andrea Campanella241896c2017-05-10 13:11:04 -070020import org.onosproject.net.MastershipRole;
Carmelo Casconee5b28722018-06-22 17:28:28 +020021import org.onosproject.net.device.DeviceAgentListener;
Andrea Campanella241896c2017-05-10 13:11:04 -070022import org.onosproject.net.device.DeviceHandshaker;
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070023import org.onosproject.net.provider.ProviderId;
Carmelo Cascone158b8c42018-07-04 19:42:37 +020024import org.onosproject.p4runtime.api.P4RuntimeClient;
Carmelo Cascone59f57de2017-07-11 19:55:09 -040025import org.onosproject.p4runtime.api.P4RuntimeController;
Andrea Campanella241896c2017-05-10 13:11:04 -070026
27import java.util.concurrent.CompletableFuture;
28
Andrea Campanella241896c2017-05-10 13:11:04 -070029/**
Carmelo Casconee3a7c742017-09-01 01:25:52 +020030 * Implementation of DeviceHandshaker for P4Runtime.
Andrea Campanella241896c2017-05-10 13:11:04 -070031 */
Carmelo Casconee3a7c742017-09-01 01:25:52 +020032public class P4RuntimeHandshaker extends AbstractP4RuntimeHandlerBehaviour implements DeviceHandshaker {
Andrea Campanella241896c2017-05-10 13:11:04 -070033
34 @Override
35 public CompletableFuture<Boolean> connect() {
Carmelo Casconee5b28722018-06-22 17:28:28 +020036 return CompletableFuture
37 .supplyAsync(super::createClient)
Carmelo Cascone158b8c42018-07-04 19:42:37 +020038 .thenComposeAsync(client -> {
Carmelo Casconee5b28722018-06-22 17:28:28 +020039 if (client == null) {
40 return CompletableFuture.completedFuture(false);
41 }
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070042 return client.startStreamChannel();
Carmelo Casconee5b28722018-06-22 17:28:28 +020043 });
Andrea Campanella241896c2017-05-10 13:11:04 -070044 }
45
46 @Override
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070047 public boolean isConnected() {
48 final P4RuntimeController controller = handler().get(P4RuntimeController.class);
49 final DeviceId deviceId = handler().data().deviceId();
50 final P4RuntimeClient client = controller.getClient(deviceId);
51 return client != null && client.isStreamChannelOpen();
52 }
53
54 @Override
Andrea Campanella241896c2017-05-10 13:11:04 -070055 public CompletableFuture<Boolean> disconnect() {
Carmelo Casconee5b28722018-06-22 17:28:28 +020056 final P4RuntimeController controller = handler().get(P4RuntimeController.class);
57 final DeviceId deviceId = handler().data().deviceId();
Carmelo Cascone158b8c42018-07-04 19:42:37 +020058 final P4RuntimeClient client = controller.getClient(deviceId);
59 if (client == null) {
Carmelo Casconee5b28722018-06-22 17:28:28 +020060 return CompletableFuture.completedFuture(true);
Carmelo Casconee5b28722018-06-22 17:28:28 +020061 }
Carmelo Cascone158b8c42018-07-04 19:42:37 +020062 return client.shutdown()
63 .thenApplyAsync(v -> {
64 controller.removeClient(deviceId);
65 return true;
66 });
Andrea Campanella241896c2017-05-10 13:11:04 -070067 }
68
69 @Override
70 public CompletableFuture<Boolean> isReachable() {
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070071 return CompletableFuture
72 // P4RuntimeController requires a client to be created to
73 // check for reachability.
74 .supplyAsync(super::createClient)
75 .thenApplyAsync(client -> {
76 if (client == null) {
77 return false;
78 }
79 return handler()
80 .get(P4RuntimeController.class)
81 .isReachable(handler().data().deviceId());
82 });
Andrea Campanella241896c2017-05-10 13:11:04 -070083 }
84
85 @Override
Carmelo Casconee5b28722018-06-22 17:28:28 +020086 public void roleChanged(MastershipRole newRole) {
87 if (setupBehaviour() && newRole.equals(MastershipRole.MASTER)) {
88 client.becomeMaster().thenAcceptAsync(result -> {
89 if (!result) {
90 log.error("Unable to notify mastership role {} to {}",
91 newRole, deviceId);
Yi Tseng3e7f1452017-10-20 10:31:53 -070092 }
93 });
Yi Tseng3e7f1452017-10-20 10:31:53 -070094 }
Andrea Campanella241896c2017-05-10 13:11:04 -070095 }
Andrea Campanella1e573442018-05-17 17:07:13 +020096
97 @Override
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070098 public MastershipRole getRole() {
99 final P4RuntimeController controller = handler().get(P4RuntimeController.class);
100 final DeviceId deviceId = handler().data().deviceId();
101 final P4RuntimeClient client = controller.getClient(deviceId);
102 if (client == null || !client.isStreamChannelOpen()) {
103 return MastershipRole.NONE;
104 }
105 return client.isMaster() ? MastershipRole.MASTER : MastershipRole.STANDBY;
Andrea Campanella1e573442018-05-17 17:07:13 +0200106 }
107
108 @Override
Carmelo Cascone9e4972c2018-08-30 00:29:16 -0700109 public void addDeviceAgentListener(ProviderId providerId, DeviceAgentListener listener) {
110 // Don't use controller/deviceId class variables as they might be uninitialized.
111 handler().get(P4RuntimeController.class)
112 .addDeviceAgentListener(data().deviceId(), providerId, listener);
113 }
114
115 @Override
116 public void removeDeviceAgentListener(ProviderId providerId) {
Carmelo Cascone7044efd2018-07-06 13:01:36 +0200117 // Don't use controller/deviceId class variable as they might be uninitialized.
Carmelo Cascone158b8c42018-07-04 19:42:37 +0200118 handler().get(P4RuntimeController.class)
Carmelo Cascone9e4972c2018-08-30 00:29:16 -0700119 .removeDeviceAgentListener(data().deviceId(), providerId);
Andrea Campanella1e573442018-05-17 17:07:13 +0200120 }
Andrea Campanella241896c2017-05-10 13:11:04 -0700121}