Fix checkstyle violations
[l2switch.git] / hosttracker / implementation / src / main / java / org / opendaylight / l2switch / hosttracker / plugin / inventory / Host.java
1 /**
2  * Copyright (c) 2014 AndrĂ© Martins, Colin Dixon, Evan Zeller 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 package org.opendaylight.l2switch.hosttracker.plugin.inventory;
9
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;
33
34 public class Host {
35     private static final Logger LOG = LoggerFactory.getLogger(Host.class);
36
37     /**
38      * Hosttracker's prefix for nodes stored on MD-SAL.
39      */
40     public static final String NODE_PREFIX = "host:";
41
42     private final List<AttachmentPointsBuilder> attachmentPointsBuilders = new ArrayList<>();
43     private final HostNodeBuilder hostNodeBuilder = new HostNodeBuilder();
44     private final NodeBuilder nodeBuilder;
45
46     public static Host createHost(Node node) {
47         HostNode hostNode = node.getAugmentation(HostNode.class);
48         return new Host(hostNode.getId(), hostNode.getAddresses(), hostNode.getAttachmentPoints());
49     }
50
51     public Host(HostId hostId, List<Addresses> addrs, List<AttachmentPoints> aps) throws InvalidParameterException {
52         hostNodeBuilder.setAddresses(addrs);
53         if (hostId == null) {
54             throw new InvalidParameterException("A host must have a HostId");
55         }
56         hostNodeBuilder.setId(hostId);
57         for (AttachmentPoints ap : aps) {
58             attachmentPointsBuilders.add(new AttachmentPointsBuilder(ap));
59         }
60         nodeBuilder = createNodeBuilder(hostNodeBuilder, attachmentPointsBuilders);
61     }
62
63     public Host(Addresses addrs, NodeConnector nodeConnector) throws InvalidParameterException {
64         List<Addresses> setAddrs = new ArrayList<>();
65         if (addrs != null) {
66             setAddrs.add(addrs);
67         }
68         hostNodeBuilder.setAddresses(setAddrs);
69         HostId hostId = createHostId(addrs);
70         if (hostId == null) {
71             throw new InvalidParameterException(
72                     "This host doesn't contain a valid MAC address to assign a valid HostId");
73         }
74         hostNodeBuilder.setId(hostId);
75         if (nodeConnector != null) {
76             AttachmentPointsBuilder apb = Utilities.createAPsfromNodeConnector(nodeConnector);
77             apb.setActive(Boolean.TRUE);
78             attachmentPointsBuilders.add(apb);
79         }
80         nodeBuilder = createNodeBuilder(hostNodeBuilder, attachmentPointsBuilders);
81     }
82
83     public synchronized Node getHostNode() {
84         List<AttachmentPoints> attachmentPoints = new ArrayList<>();
85         for (AttachmentPointsBuilder apb : attachmentPointsBuilders) {
86             attachmentPoints.add(apb.build());
87         }
88         hostNodeBuilder.setAttachmentPoints(attachmentPoints);
89         return nodeBuilder.addAugmentation(HostNode.class, hostNodeBuilder.build()).build();
90     }
91
92     /**
93      * Creates a NodeBuilder based on the given HostNodeBuilder.
94      *
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.
98      */
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);
103             tps.add(tp);
104             apb.setCorrespondingTp(tp.getTpId());
105         }
106         NodeBuilder node = new NodeBuilder().setNodeId(createNodeId(hostNode))
107                 .setTerminationPoint(tps);
108         node.setKey(new NodeKey(node.getNodeId()));
109
110         return node;
111     }
112
113     /**
114      * Creates a NodeId based on the Id stored on the given HostNodeBuilder
115      * adding the NODE_PREFIX.
116      *
117      * @param host HostNodeBuilder that contains an Id
118      * @return A new NodeId.
119      */
120     private static NodeId createNodeId(HostNodeBuilder host) {
121         return new NodeId(NODE_PREFIX + host.getId().getValue());
122     }
123
124     /**
125      * Creates a new TerminationPoint for this Host.
126      *
127      * @param hn HostNodeBuilder containing an Id
128      * @return A new TerminationPoint with an unique TpId
129      */
130     private TerminationPoint createTerminationPoint(HostNodeBuilder hn) {
131         TerminationPoint tp = new TerminationPointBuilder()
132                 .setTpId(new TpId(NODE_PREFIX + hn.getId().getValue()))
133                 .build();
134         return tp;
135     }
136
137     /**
138      * Creates a HostId based on the MAC values present in Addresses, if MAC is null then returns null.
139      *
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.
142      */
143     public static HostId createHostId(Addresses addrs) {
144         if (addrs != null && addrs.getMac() != null) {
145             return new HostId(addrs.getMac().getValue());
146         } else {
147             return null;
148         }
149     }
150
151     /**
152      * Returns this HostId.
153      *
154      * @return this HostId.
155      */
156     public synchronized HostId getId() {
157         return hostNodeBuilder.getId();
158     }
159
160     /**
161      * Creates links that have this Host's AttachmentPoints in the given
162      * dstNode.
163      *
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.
166      */
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()),
176                                 apb.getTpId());
177                     }
178                 }
179             }
180         }
181         return null;
182     }
183
184     /**
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.
188      *
189      *
190      * @param newHost The new Host to merge information with.
191      */
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)) {
199                     oldLIAddrs.remove();
200                     break;
201                 }
202             }
203             this.hostNodeBuilder.getAddresses().add(newAddrs);
204         }
205
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)) {
212                     oldLIAPs.remove();
213                     break;
214                 }
215             }
216             this.attachmentPointsBuilders.add(newAPs);
217         }
218     }
219
220     /**
221      * Sets the given AttachmentPointsBuilder to inactive from the list of this
222      * Host's AttachmentPoints.
223      *
224      * @param apb The AttachmentPointsBuilder to set inactive
225      */
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);
231             }
232         }
233     }
234
235     /**
236      * Sets the AttachmentPointsBuilder that have the given TerminationPoint to
237      * inactive from the list of this Host's AttachmentPoints.
238      *
239      * @param tp The TerminationPoint to set inactive
240      */
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);
246             }
247         }
248     }
249
250     /**
251      * If a host does not have any AttachmentPoints active it means it is an
252      * orphan.
253      *
254      * @return true if a host is an orphan, false otherwise.
255      */
256     public synchronized boolean isOrphan() {
257         for (AttachmentPointsBuilder attachmentPointsBuilder : attachmentPointsBuilders) {
258             if (attachmentPointsBuilder.isActive()) {
259                 return false;
260             }
261         }
262         return true;
263     }
264 }