blob: f49ad1853f1131414879f86b96e83bfd6cbd6ec9 [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;
21import org.onosproject.net.device.DeviceHandshaker;
Carmelo Cascone59f57de2017-07-11 19:55:09 -040022import org.onosproject.p4runtime.api.P4RuntimeController;
Andrea Campanella241896c2017-05-10 13:11:04 -070023
24import java.util.concurrent.CompletableFuture;
25
Andrea Campanella241896c2017-05-10 13:11:04 -070026/**
Carmelo Casconee3a7c742017-09-01 01:25:52 +020027 * Implementation of DeviceHandshaker for P4Runtime.
Andrea Campanella241896c2017-05-10 13:11:04 -070028 */
Carmelo Casconee3a7c742017-09-01 01:25:52 +020029public class P4RuntimeHandshaker extends AbstractP4RuntimeHandlerBehaviour implements DeviceHandshaker {
Andrea Campanella241896c2017-05-10 13:11:04 -070030
Carmelo Cascone59f57de2017-07-11 19:55:09 -040031 // TODO: consider abstract class with empty connect method and implementation into a protected one for reusability.
32
Andrea Campanella241896c2017-05-10 13:11:04 -070033 @Override
34 public CompletableFuture<Boolean> connect() {
Carmelo Cascone59f57de2017-07-11 19:55:09 -040035 return CompletableFuture.supplyAsync(this::doConnect);
36 }
37
38 private boolean doConnect() {
Carmelo Casconee3a7c742017-09-01 01:25:52 +020039 return super.createClient();
Andrea Campanella241896c2017-05-10 13:11:04 -070040 }
41
42 @Override
43 public CompletableFuture<Boolean> disconnect() {
Carmelo Cascone59f57de2017-07-11 19:55:09 -040044 return CompletableFuture.supplyAsync(() -> {
45 P4RuntimeController controller = handler().get(P4RuntimeController.class);
46 DeviceId deviceId = handler().data().deviceId();
47 controller.removeClient(deviceId);
48 return true;
49 });
Andrea Campanella241896c2017-05-10 13:11:04 -070050 }
51
52 @Override
53 public CompletableFuture<Boolean> isReachable() {
Carmelo Cascone59f57de2017-07-11 19:55:09 -040054 return CompletableFuture.supplyAsync(() -> {
55 P4RuntimeController controller = handler().get(P4RuntimeController.class);
56 DeviceId deviceId = handler().data().deviceId();
57 return controller.isReacheable(deviceId);
58 });
Andrea Campanella241896c2017-05-10 13:11:04 -070059 }
60
61 @Override
62 public CompletableFuture<MastershipRole> roleChanged(MastershipRole newRole) {
Yi Tseng3e7f1452017-10-20 10:31:53 -070063 deviceId = handler().data().deviceId();
64 controller = handler().get(P4RuntimeController.class);
Andrea Campanella241896c2017-05-10 13:11:04 -070065 CompletableFuture<MastershipRole> result = new CompletableFuture<>();
Yi Tseng3e7f1452017-10-20 10:31:53 -070066
67 client = controller.getClient(deviceId);
68 if (client == null || !controller.isReacheable(deviceId)) {
Andrea Campanella14e196d2017-07-24 18:11:36 +020069 result.complete(MastershipRole.NONE);
Yi Tseng3e7f1452017-10-20 10:31:53 -070070 return result;
71 }
72 if (newRole.equals(MastershipRole.MASTER)) {
73 client.sendMasterArbitrationUpdate().thenAcceptAsync(success -> {
74 if (!success) {
75 log.warn("Device {} arbitration failed", deviceId);
76 result.complete(MastershipRole.STANDBY);
77 } else {
78 result.complete(MastershipRole.MASTER);
79 }
80 });
81 } else {
82 // Since we don't need to do anything, we can complete it directly
83 // Spec: The client with the highest election id is referred to as the
84 // "master", while all other clients are referred to as "slaves".
85 result.complete(newRole);
86 }
Andrea Campanella241896c2017-05-10 13:11:04 -070087 return result;
88 }
Andrea Campanella241896c2017-05-10 13:11:04 -070089}