2 * Copyright (c) 2014 André Martins, Colin Dixon, Evan Zeller 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.l2switch.hosttracker.plugin.inventory;
10 import java.security.InvalidParameterException;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.ListIterator;
14 import org.opendaylight.l2switch.hosttracker.plugin.util.Compare;
15 import org.opendaylight.l2switch.hosttracker.plugin.util.Utilities;
16 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.Addresses;
17 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostId;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNode;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNodeBuilder;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.host.AttachmentPoints;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.host.AttachmentPointsBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
23 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TpId;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Link;
26 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeBuilder;
28 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey;
29 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPoint;
30 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointBuilder;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
35 private static final Logger LOG = LoggerFactory.getLogger(Host.class);
38 * Hosttracker's prefix for nodes stored on MD-SAL.
40 public static final String NODE_PREFIX = "host:";
42 private final List<AttachmentPointsBuilder> attachmentPointsBuilders = new ArrayList<>();
43 private final HostNodeBuilder hostNodeBuilder = new HostNodeBuilder();
44 private final NodeBuilder nodeBuilder;
46 public static Host createHost(Node node) {
47 HostNode hostNode = node.getAugmentation(HostNode.class);
48 return new Host(hostNode.getId(), hostNode.getAddresses(), hostNode.getAttachmentPoints());
51 public Host(HostId hostId, List<Addresses> addrs, List<AttachmentPoints> aps) throws InvalidParameterException {
52 hostNodeBuilder.setAddresses(addrs);
54 throw new InvalidParameterException("A host must have a HostId");
56 hostNodeBuilder.setId(hostId);
57 for (AttachmentPoints ap : aps) {
58 attachmentPointsBuilders.add(new AttachmentPointsBuilder(ap));
60 nodeBuilder = createNodeBuilder(hostNodeBuilder, attachmentPointsBuilders);
63 public Host(Addresses addrs, NodeConnector nodeConnector) throws InvalidParameterException {
64 List<Addresses> setAddrs = new ArrayList<>();
68 hostNodeBuilder.setAddresses(setAddrs);
69 HostId hostId = createHostId(addrs);
71 throw new InvalidParameterException(
72 "This host doesn't contain a valid MAC address to assign a valid HostId");
74 hostNodeBuilder.setId(hostId);
75 if (nodeConnector != null) {
76 AttachmentPointsBuilder apb = Utilities.createAPsfromNodeConnector(nodeConnector);
77 apb.setActive(Boolean.TRUE);
78 attachmentPointsBuilders.add(apb);
80 nodeBuilder = createNodeBuilder(hostNodeBuilder, attachmentPointsBuilders);
83 public synchronized Node getHostNode() {
84 List<AttachmentPoints> attachmentPoints = new ArrayList<>();
85 for (AttachmentPointsBuilder apb : attachmentPointsBuilders) {
86 attachmentPoints.add(apb.build());
88 hostNodeBuilder.setAttachmentPoints(attachmentPoints);
89 return nodeBuilder.addAugmentation(HostNode.class, hostNodeBuilder.build()).build();
93 * Creates a NodeBuilder based on the given HostNodeBuilder.
95 * @param hostNode The HostNodeBuilder where the AttachmentPoints and Id are.
96 * @return A NodeBuilder with the same Id of HostNodeBuilder and a list of TerminationPoint corresponding to
97 * each HostNodeBuilder's AttachmentPoints.
99 private NodeBuilder createNodeBuilder(HostNodeBuilder hostNode, List<AttachmentPointsBuilder> apbs) {
100 List<TerminationPoint> tps = new ArrayList<>();
101 for (AttachmentPointsBuilder apb : apbs) {
102 TerminationPoint tp = createTerminationPoint(hostNode);
104 apb.setCorrespondingTp(tp.getTpId());
106 NodeBuilder node = new NodeBuilder().setNodeId(createNodeId(hostNode))
107 .setTerminationPoint(tps);
108 node.setKey(new NodeKey(node.getNodeId()));
114 * Creates a NodeId based on the Id stored on the given HostNodeBuilder
115 * adding the NODE_PREFIX.
117 * @param host HostNodeBuilder that contains an Id
118 * @return A new NodeId.
120 private static NodeId createNodeId(HostNodeBuilder host) {
121 return new NodeId(NODE_PREFIX + host.getId().getValue());
125 * Creates a new TerminationPoint for this Host.
127 * @param hn HostNodeBuilder containing an Id
128 * @return A new TerminationPoint with an unique TpId
130 private TerminationPoint createTerminationPoint(HostNodeBuilder hn) {
131 TerminationPoint tp = new TerminationPointBuilder()
132 .setTpId(new TpId(NODE_PREFIX + hn.getId().getValue()))
138 * Creates a HostId based on the MAC values present in Addresses, if MAC is null then returns null.
140 * @param addrs Address containing a MAC address.
141 * @return A new HostId based on the MAC address present in addrs, null ifcaddrs is null or MAC is null.
143 public static HostId createHostId(Addresses addrs) {
144 if (addrs != null && addrs.getMac() != null) {
145 return new HostId(addrs.getMac().getValue());
152 * Returns this HostId.
154 * @return this HostId.
156 public synchronized HostId getId() {
157 return hostNodeBuilder.getId();
161 * Creates links that have this Host's AttachmentPoints in the given
164 * @param dstNode Node that could have Host's AttachmentPoints.
165 * @return A list of links containing a link from this Host's TerminationPoint to the given dstNode and vice-versa.
167 public synchronized List<Link> createLinks(
168 org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node dstNode) {
169 for (AttachmentPointsBuilder apb : attachmentPointsBuilders) {
170 if (apb.isActive()) {
171 for (NodeConnector nc : dstNode.getNodeConnector()) {
172 if (nc.getId().getValue().equals(apb.getTpId().getValue())) {
173 return Utilities.createLinks(nodeBuilder.getNodeId(),
174 apb.getCorrespondingTp(),
175 new NodeId(dstNode.getId().getValue()),
185 * Updates this Host with the given Host. Merge the newHostNodeBuilder
186 * information into the hostToUpdate. Merges the list of addresses and the
187 * list of attachment points into the current host.
190 * @param newHost The new Host to merge information with.
192 public synchronized void mergeHostWith(Host newHost) {
193 ListIterator<Addresses> oldLIAddrs;
194 for (Addresses newAddrs : newHost.hostNodeBuilder.getAddresses()) {
195 oldLIAddrs = this.hostNodeBuilder.getAddresses().listIterator();
196 while (oldLIAddrs.hasNext()) {
197 Addresses oldAddrs = oldLIAddrs.next();
198 if (Compare.addresses(oldAddrs, newAddrs)) {
203 this.hostNodeBuilder.getAddresses().add(newAddrs);
206 ListIterator<AttachmentPointsBuilder> oldLIAPs;
207 for (AttachmentPointsBuilder newAPs : newHost.attachmentPointsBuilders) {
208 oldLIAPs = this.attachmentPointsBuilders.listIterator();
209 while (oldLIAPs.hasNext()) {
210 AttachmentPointsBuilder oldAPs = oldLIAPs.next();
211 if (Compare.attachmentPointsBuilder(oldAPs, newAPs)) {
216 this.attachmentPointsBuilders.add(newAPs);
221 * Sets the given AttachmentPointsBuilder to inactive from the list of this
222 * Host's AttachmentPoints.
224 * @param apb The AttachmentPointsBuilder to set inactive
226 public synchronized void removeAttachmentPoints(AttachmentPointsBuilder apb) {
227 LOG.debug("Setting attachment points {} to inactive state", apb);
228 for (AttachmentPointsBuilder apbi : attachmentPointsBuilders) {
229 if (apbi.getKey().equals(apb.getKey())) {
230 apbi.setActive(Boolean.FALSE);
236 * Sets the AttachmentPointsBuilder that have the given TerminationPoint to
237 * inactive from the list of this Host's AttachmentPoints.
239 * @param tp The TerminationPoint to set inactive
241 public synchronized void removeTerminationPoint(TpId tp) {
242 LOG.debug("Setting termination point {} to inactive state", tp);
243 for (AttachmentPointsBuilder apbi : attachmentPointsBuilders) {
244 if (apbi.getCorrespondingTp().equals(tp)) {
245 apbi.setActive(Boolean.FALSE);
251 * If a host does not have any AttachmentPoints active it means it is an
254 * @return true if a host is an orphan, false otherwise.
256 public synchronized boolean isOrphan() {
257 for (AttachmentPointsBuilder attachmentPointsBuilder : attachmentPointsBuilders) {
258 if (attachmentPointsBuilder.isActive()) {