2 * Copyright (c) 2019 Ericsson India Global Services Pvt Ltd. and others. All rights reserved.
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
8 package org.opendaylight.genius.cloudscaler.rpcservice;
10 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
12 import java.util.Objects;
13 import java.util.Optional;
14 import java.util.concurrent.ConcurrentHashMap;
15 import java.util.concurrent.ExecutionException;
16 import java.util.concurrent.ExecutorService;
17 import javax.inject.Inject;
18 import javax.inject.Singleton;
19 import org.eclipse.jdt.annotation.NonNull;
20 import org.opendaylight.genius.mdsalutil.cache.InstanceIdDataObjectCache;
21 import org.opendaylight.infrautils.caches.CacheProvider;
22 import org.opendaylight.infrautils.utils.concurrent.Executors;
23 import org.opendaylight.mdsal.binding.api.DataBroker;
24 import org.opendaylight.mdsal.binding.api.ReadWriteTransaction;
25 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
26 import org.opendaylight.mdsal.common.api.ReadFailedException;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.cloudscaler.rpcs.rev171220.ComputeNodes;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.cloudscaler.rpcs.rev171220.compute.nodes.ComputeNode;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.cloudscaler.rpcs.rev171220.compute.nodes.ComputeNodeBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.cloudscaler.rpcs.rev171220.compute.nodes.ComputeNodeKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.bridge.attributes.BridgeOtherConfigs;
33 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
34 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
35 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
36 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
37 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
38 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
39 import org.opendaylight.yangtools.yang.common.Uint64;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
44 public class ComputeNodeManager {
46 private static final Logger LOG = LoggerFactory.getLogger("GeniusEventLogger");
48 private final DataBroker dataBroker;
50 private final InstanceIdDataObjectCache<ComputeNode> computeNodeCache;
51 private final InstanceIdDataObjectCache<Node> ovsdbTopologyNodeCache;
52 private final Map<Uint64, ComputeNode> dpnIdVsComputeNode;
53 // FIXME: this service is never shut down
54 private final ExecutorService executorService = Executors.newSingleThreadExecutor("compute-node-manager", LOG);
57 @SuppressFBWarnings({"URF_UNREAD_FIELD", "NP_LOAD_OF_KNOWN_NULL_VALUE"})
58 public ComputeNodeManager(DataBroker dataBroker,
59 CacheProvider cacheProvider) {
60 this.dataBroker = dataBroker;
61 this.dpnIdVsComputeNode = new ConcurrentHashMap<>();
62 this.computeNodeCache = new InstanceIdDataObjectCache<>(ComputeNode.class, dataBroker,
63 LogicalDatastoreType.CONFIGURATION,
64 InstanceIdentifier.builder(ComputeNodes.class).child(ComputeNode.class).build(),
67 protected void added(InstanceIdentifier<ComputeNode> path, ComputeNode computeNode) {
68 LOG.info("ComputeNodeManager add compute {}", computeNode);
69 dpnIdVsComputeNode.put(computeNode.getDpnid(), computeNode);
73 protected void removed(InstanceIdentifier<ComputeNode> path, ComputeNode computeNode) {
74 LOG.info("ComputeNodeManager remove compute {}", computeNode);
75 dpnIdVsComputeNode.remove(computeNode.getDpnid());
78 this.ovsdbTopologyNodeCache = new InstanceIdDataObjectCache<>(Node.class, dataBroker,
79 LogicalDatastoreType.OPERATIONAL,
83 @SuppressWarnings("checkstyle:IllegalCatch")
84 protected void added(InstanceIdentifier<Node> path, Node dataObject) {
85 executorService.execute(() -> {
88 } catch (Exception e) {
89 LOG.error("ComputeNodeManager Failed to handle ovsdb node add", e);
94 //LOG.info("Compute node manager is initialized ");
97 public ComputeNode getComputeNodeFromName(String computeName) throws ReadFailedException {
98 InstanceIdentifier<ComputeNode> computeIid = buildComputeNodeIid(computeName);
99 return computeNodeCache.get(computeIid).orElse(null);
102 public void deleteComputeNode(ReadWriteTransaction tx, ComputeNode computeNode) {
103 tx.delete(LogicalDatastoreType.CONFIGURATION, buildComputeNodeIid(computeNode.getComputeName()));
106 public void add(@NonNull Node node) throws ExecutionException, InterruptedException {
107 OvsdbBridgeAugmentation bridgeAugmentation = node.augmentation(OvsdbBridgeAugmentation.class);
108 if (bridgeAugmentation != null && bridgeAugmentation.getBridgeOtherConfigs() != null) {
109 Uint64 datapathid = getDpnIdFromBridge(bridgeAugmentation);
110 Optional<BridgeOtherConfigs> otherConfigOptional = bridgeAugmentation.getBridgeOtherConfigs().values()
112 .filter(otherConfig -> otherConfig.getBridgeOtherConfigKey().equals("dp-desc"))
114 if (!otherConfigOptional.isPresent()) {
115 LOG.debug("ComputeNodeManager Compute node name is not present in bridge {}", node.getNodeId());
118 String computeName = otherConfigOptional.get().getBridgeOtherConfigValue();
119 String nodeId = node.getNodeId().getValue();
120 InstanceIdentifier<ComputeNode> computeIid = buildComputeNodeIid(computeName);
121 ComputeNode computeNode = new ComputeNodeBuilder()
122 .setComputeName(computeName)
123 .setDpnid(datapathid)
126 Optional<ComputeNode> computeNodeOptional = Optional.empty();
128 computeNodeOptional = computeNodeCache.get(computeIid);
129 } catch (ReadFailedException e) {
130 LOG.error("ComputeNodeManager Failed to read {}", computeIid);
132 if (computeNodeOptional.isPresent()) {
133 logErrorIfComputeNodeIsAlreadyTaken(datapathid, nodeId, computeNodeOptional);
135 LOG.info("ComputeNodeManager add ovsdb node {}", node.getNodeId());
136 putComputeDetailsInConfigDatastore(computeIid, computeNode);
141 public InstanceIdentifier<ComputeNode> buildComputeNodeIid(String computeName) {
142 return InstanceIdentifier.builder(ComputeNodes.class)
143 .child(ComputeNode.class, new ComputeNodeKey(computeName))
147 private Uint64 getDpnIdFromBridge(OvsdbBridgeAugmentation bridgeAugmentation) {
148 if (bridgeAugmentation.getDatapathId() == null) {
151 String datapathIdStr = bridgeAugmentation.getDatapathId().getValue() != null
152 ? bridgeAugmentation.getDatapathId().getValue().replace(":", "") : null;
153 return datapathIdStr != null ? Uint64.valueOf(datapathIdStr, 16) : Uint64.ZERO;
156 public void putComputeDetailsInConfigDatastore(InstanceIdentifier<ComputeNode> computeIid,
157 ComputeNode computeNode)
158 throws ExecutionException, InterruptedException {
159 ReadWriteTransaction tx = dataBroker.newReadWriteTransaction();
160 tx.put(LogicalDatastoreType.CONFIGURATION, computeIid, computeNode);
162 dpnIdVsComputeNode.put(computeNode.getDpnid(), computeNode);
163 //LOG.info("Write comute node details {}", computeNode);
167 private void logErrorIfComputeNodeIsAlreadyTaken(Uint64 datapathid, String nodeId, Optional<ComputeNode> optional) {
168 ComputeNode existingNode = optional.get();
169 if (!Objects.equals(existingNode.getNodeid(), nodeId)) {
170 LOG.error("ComputeNodeManager Compute is already connected by compute {}", existingNode);
173 if (!Objects.equals(existingNode.getDpnid(), datapathid)) {
174 LOG.error("ComputeNodeManager Compute is already connected by compute {}", existingNode);
178 private InstanceIdentifier<Node> getWildcardPath() {
179 return InstanceIdentifier
180 .create(NetworkTopology.class)
181 .child(Topology.class, new TopologyKey(new TopologyId("ovsdb:1")))
185 public ComputeNode getComputeNode(Uint64 dpnId) {
186 return dpnIdVsComputeNode.get(dpnId);