Refactoring of cisco-xr-driver and impl modules.
[unimgr.git] / impl / src / main / java / org / opendaylight / unimgr / utils / CapabilitiesService.java
1 /*
2  * Copyright (c) 2016 Cisco Systems Inc and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.unimgr.utils;
10
11 import com.google.common.base.Optional;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
17 import org.opendaylight.yang.gen.v1.urn.onf.core.network.module.rev160630.g_forwardingconstruct.FcPort;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.netconf.node.topology.rev150114.NetconfNode;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
20 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
21 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
25 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 import java.util.function.BiFunction;
30
31
32 public class CapabilitiesService {
33
34     public interface Capability<T> {
35         enum Mode {
36             AND,
37             OR;
38         }
39
40         BiFunction<DataBroker, T, Boolean> getCondition();
41     }
42
43     public interface Context<T> {
44         boolean isSupporting(Capability<T> capability);
45     }
46
47     public static class NodeContext implements Context<Node> {
48         public enum NodeCapability implements Capability<Node> {
49             NETCONF((dbBroker, node) -> node.getAugmentation(NetconfNode.class) != null),
50             NETCONF_CISCO_IOX_L2VPN((dbBroker, node) ->
51                     checkForNetconfCapability(node,NetconfConstants.CAPABILITY_IOX_L2VPN)),
52             NETCONF_CISCO_IOX_IFMGR((dbBroker, node) ->
53                     checkForNetconfCapability(node,NetconfConstants.CAPABILITY_IOX_IFMGR)),
54             NETCONF_CISCO_IOX_POLICYMGR((dbBroker, node) ->
55                     checkForNetconfCapability(node,NetconfConstants.CAPABILITY_IOX_ASR9K_POLICYMGR)),
56             OVSDB((dbBroker,node) -> node.getAugmentation(OvsdbBridgeAugmentation.class) != null);
57
58             private BiFunction<DataBroker, Node, Boolean> condition;
59
60             NodeCapability(BiFunction<DataBroker, Node, Boolean> condition) {
61                 this.condition = condition;
62             }
63
64             @Override
65             public BiFunction<DataBroker, Node, Boolean> getCondition() {
66                 return condition;
67             }
68
69             private static boolean checkForNetconfCapability(Node node, String netconf_capability){
70                 return node.getAugmentation(NetconfNode.class)
71                         .getAvailableCapabilities()
72                         .getAvailableCapability()
73                         .stream()
74                         .anyMatch(capability -> capability.getCapability().equals(netconf_capability));
75             }
76         }
77
78         private CapabilitiesService service;
79
80         private Optional<Node> nodeOpt;
81
82         NodeContext(CapabilitiesService service, Optional<Node> nodeOpt) {
83             this.service = service;
84             this.nodeOpt = nodeOpt;
85         }
86
87         public Optional<Node> getNode() {
88             return nodeOpt;
89         }
90
91         public boolean isSupporting(Capability<Node> capability) {
92             if (!nodeOpt.isPresent()) {
93                 return false;
94             }
95
96             return service.checkCondition(capability, nodeOpt.get());
97         }
98
99         public boolean isSupporting(Capability.Mode mode, Capability<Node>... capabilities) {
100             boolean result = (mode == Capability.Mode.AND);
101
102             for (Capability capability : capabilities) {
103                 boolean isSupporting = isSupporting(capability);
104                 result = (mode == Capability.Mode.AND ? result && isSupporting: result || isSupporting);
105
106                 if(result ^ (mode == Capability.Mode.AND)) {
107                     break;
108                 }
109             }
110
111             return result;
112         }
113     }
114
115     private static final Logger LOG = LoggerFactory.getLogger(CapabilitiesService.class);
116
117     private DataBroker dataBroker;
118
119     public CapabilitiesService(DataBroker dataBroker) {
120         this.dataBroker = dataBroker;
121     }
122
123     public NodeContext node(Node node) {
124         return new NodeContext(this, Optional.of(node));
125     }
126
127     public NodeContext nodeByPort(FcPort port) {
128         return new NodeContext(this, readNode(port));
129     }
130
131     private Optional<Node> readNode(FcPort port) {
132         InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(NetworkTopology.class)
133                 .child(Topology.class, new TopologyKey(port.getTopology()))
134                 .child(Node.class, new NodeKey(port.getNode()))
135                 .build();
136
137         final ReadTransaction tx = dataBroker.newReadOnlyTransaction();
138         final CheckedFuture<Optional<Node>, ReadFailedException> nodeFuture = tx.read(LogicalDatastoreType.OPERATIONAL, nodeIid);
139         Optional<Node> result = Optional.absent();
140
141         try {
142             result = nodeFuture.checkedGet();
143         } catch (final ReadFailedException e) {
144             LOG.error("Unable to read node with Iid {}", nodeIid, e);
145         }
146
147         return result;
148     }
149
150     private <T> boolean checkCondition(Capability<T> capability, T data) {
151         return capability.getCondition().apply(dataBroker, data);
152     }
153 }