Provide the SPCE module
[alto.git] / alto-hosttracker / implementation / src / main / java / org / opendaylight / alto / altohosttracker / plugin / internal / AltoHostTrackerImpl.java
1 /*
2  * Copyright (c) 2015 Yale University 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.alto.altohosttracker.plugin.internal;
10
11 import java.util.Iterator;
12 import java.util.Map;
13 import java.util.HashMap;
14 import java.util.Set;
15 import java.util.ArrayList;
16 import java.util.List;
17 import java.util.concurrent.ExecutorService;
18 import java.util.concurrent.Executors;
19 import java.util.concurrent.ExecutionException;
20 import java.util.regex.Pattern;
21 import java.util.regex.Matcher;
22
23 import com.google.common.base.Optional;
24 import com.google.common.base.Preconditions;
25 import com.google.common.util.concurrent.FutureCallback;
26 import com.google.common.util.concurrent.Futures;
27 import com.google.common.util.concurrent.ListenableFuture;
28 import com.google.common.util.concurrent.CheckedFuture;
29
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.hosttracker.rev150416.DstCosts1;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.hosttracker.rev150416.DstCosts1Builder;
32 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
33 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
34 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
35 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
36 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
37 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataChangeEvent;
38 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.host.tracker.rev140624.HostNode;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.AddressCapableNodeConnector;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.address.tracker.rev140617.address.node.connector.Addresses;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.node.NodeConnector;
44 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology;
45 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId;
46 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
47 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.Topology;
48 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.Resources;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.ResourcesBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.NetworkMaps;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMapKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.NetworkMapsBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMap;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.network.maps.NetworkMapBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.CostMaps;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.CostMapsBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.cost.maps.CostMap;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.cost.maps.CostMapBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.EndpointPropertyMap;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.resources.EndpointPropertyMapBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedIpv4Address;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TypedEndpointAddress;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.EndpointPropertyType;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.EndpointPropertyValue;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.data.EndpointProperties;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.data.EndpointPropertiesBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.data.EndpointPropertiesKey;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.data.endpoint.properties.Properties;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.data.endpoint.properties.PropertiesBuilder;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ResourceSpecificEndpointProperty;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.MapBuilder;
73 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ResourceId;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.TagString;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.ValidIdString;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.PidName;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.cost.map.meta.CostType;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.cost.map.meta.CostTypeBuilder;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.dependent.vtags.DependentVtags;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.dependent.vtags.DependentVtagsBuilder;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.CostMode;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.CostMetric;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.map.DstCosts;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.map.DstCostsBuilder;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.address.group.EndpointAddressGroup;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.address.group.EndpointAddressGroupBuilder;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.address.group.EndpointAddressGroupKey;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.EndpointAddressType;
91 import org.opendaylight.yangtools.concepts.ListenerRegistration;
92 import org.opendaylight.yangtools.yang.binding.DataObject;
93 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96
97 public class AltoHostTrackerImpl implements DataChangeListener {
98
99     private Pattern p;
100     private static final int CPUS = Runtime.getRuntime().availableProcessors();
101
102     /**
103      * As defined on
104      * controller/opendaylight/md-sal/topology-manager/src/main/java
105      * /org/opendaylight
106      * /md/controller/topology/manager/FlowCapableTopologyProvider.java
107      */
108     private static final String TOPOLOGY_NAME = "flow:1";
109
110     private static final String NMRESOURCEID = "hosttracker-network-map";
111
112     private static final String CMRESOURCEID = "hosttracker-cost-map";
113
114     private static final String EPMRESOURCEID = "hosttracker-endpoint-property-map";
115
116     private static final Logger log = LoggerFactory
117             .getLogger(AltoHostTrackerImpl.class);
118
119     private static Map<String, String> networkMap;
120     private static Map<String, String> endpointPropertyMap;
121
122     private final DataBroker dataService;
123     private final String topologyId;
124
125     private String networkTag=null;
126     // public static final InstanceIdentifier<Resources> ALTO_IID =
127     // InstanceIdentifier.builder(Resources.class).toInstance();
128
129     ExecutorService exec = Executors.newFixedThreadPool(CPUS);
130
131     private ListenerRegistration<DataChangeListener> hostNodeListerRegistration;
132
133     private ListenerRegistration<DataChangeListener> networkMapListerRegistration;
134
135     public AltoHostTrackerImpl(DataBroker dataService, String topologyId) {
136         networkMap = new HashMap<String, String>();
137         endpointPropertyMap = new HashMap<String, String>();
138
139         p = Pattern.compile("[0-9]+.[0-9]+.[0-9]+.[0-9]+");
140
141         Preconditions.checkNotNull(dataService,
142                 "dataBrokerService should not be null.");
143         this.dataService = dataService;
144         if (topologyId == null || topologyId.isEmpty()) {
145             this.topologyId = TOPOLOGY_NAME;
146         } else {
147             this.topologyId = topologyId;
148         }
149     }
150
151     public void submit(final WriteTransaction writeTx) {
152         final CheckedFuture writeTxResultFuture = writeTx.submit();
153         Futures.addCallback(writeTxResultFuture, new FutureCallback() {
154             @Override
155             public void onSuccess(Object o) {
156                 log.debug("ConcurrentHashMap write successful for tx :{}",
157                         writeTx.getIdentifier());
158             }
159
160             @Override
161             public void onFailure(Throwable throwable) {
162                 log.error("ConcurrentHashMap write transaction {} failed",
163                         writeTx.getIdentifier(), throwable.getCause());
164             }
165         });
166     }
167
168     public void writeDefaultCostMaps() {
169         ResourceId nm_rid = new ResourceId(new ValidIdString(NMRESOURCEID));
170         ResourceId rid = new ResourceId(new ValidIdString(CMRESOURCEID));
171
172         InstanceIdentifier<CostMaps> ALTO_CMS = InstanceIdentifier
173                 .builder(Resources.class).child(CostMaps.class).build();
174
175         TagString tag = new TagString(TagGenerator.getTag(32));
176         ValidIdString vis0 = new ValidIdString("pid0");
177         PidName pid0 = new PidName(vis0);
178         ValidIdString vis1 = new ValidIdString("pid1");
179         PidName pid1 = new PidName(vis1);
180
181         TagString dtag = new TagString(this.networkTag);
182         DependentVtags dv = new DependentVtagsBuilder().setResourceId(nm_rid)
183                 .setTag(dtag).build();
184         List<DependentVtags> dvList = new ArrayList<DependentVtags>();
185         dvList.add(dv);
186         CostType ct = new CostTypeBuilder().setCostMode(CostMode.Numerical)
187                 .setCostMetric(new CostMetric("hcm"))
188                 .setDescription("hosttracker cost metric").build();
189         org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.Meta meta = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.MetaBuilder()
190                 .setDependentVtags(dvList).setCostType(ct).build();
191
192         DstCosts1 dcs11 = new DstCosts1Builder().setCostInHosttracker(10)
193                 .build();
194         DstCosts1 dcs12 = new DstCosts1Builder().setCostInHosttracker(0)
195                 .build();
196         DstCosts dcs1 = new DstCostsBuilder().setDst(pid1)
197                 .addAugmentation(DstCosts1.class, dcs12).build();
198         DstCosts dcs2 = new DstCostsBuilder().setDst(pid0)
199                 .addAugmentation(DstCosts1.class, dcs11).build();
200         List<DstCosts> dcsList = new ArrayList<DstCosts>();
201         dcsList.add(dcs1);
202         dcsList.add(dcs2);
203
204         org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.Map map = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.MapBuilder()
205                 .setSrc(pid1).setDstCosts(dcsList).build();
206
207         List<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.Map> mapList = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.cost.map.Map>();
208
209         mapList.add(map);
210
211         CostMap cm = new CostMapBuilder().setResourceId(rid).setTag(tag)
212                 .setMeta(meta).setMap(mapList).build();
213
214         List<CostMap> cmList = new ArrayList<CostMap>();
215
216         cmList.add(cm);
217
218         CostMaps cms = new CostMapsBuilder().setCostMap(cmList).build();
219
220         final WriteTransaction writeTx = this.dataService
221                 .newWriteOnlyTransaction();
222         try {
223             writeTx.put(LogicalDatastoreType.CONFIGURATION, ALTO_CMS, cms, true);
224         } catch (Exception e) {
225             e.printStackTrace();
226         }
227         submit(writeTx);
228     }
229
230     public void writeDefaultNetworkMaps() {
231         InstanceIdentifier<NetworkMaps> ALTO_NM = InstanceIdentifier
232                 .builder(Resources.class).child(NetworkMaps.class).build();
233         final WriteTransaction tx = dataService.newWriteOnlyTransaction();
234         try {
235             tx.put(LogicalDatastoreType.CONFIGURATION, ALTO_NM,
236                     loadNetworkMaps(), true);
237         } catch (Exception e) {
238             e.printStackTrace();
239         }
240         submit(tx);
241     }
242
243     public void writeDefaultEndpointpropertyMap() {
244         InstanceIdentifier<EndpointPropertyMap> ALTO_EPM = InstanceIdentifier
245                 .builder(Resources.class).child(EndpointPropertyMap.class)
246                 .build();
247         ResourceId rid = new ResourceId(new ValidIdString(
248                 "default-endpoint-property-map"));
249         TagString tag = new TagString(TagGenerator.getTag(32));
250
251         DependentVtags dv = new DependentVtagsBuilder().setResourceId(rid)
252                 .setTag(tag).build();
253         List<DependentVtags> dvList = new ArrayList<DependentVtags>();
254         dvList.add(dv);
255
256         org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.Meta meta = new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.service.types.rev150404.endpoint.property.map.MetaBuilder()
257                 .setDependentVtags(dvList).build();
258         TypedIpv4Address ti4 = new TypedIpv4Address("ipv4:0.0.0.0");
259         TypedEndpointAddress tea = new TypedEndpointAddress(ti4);
260         EndpointPropertyType etp = new EndpointPropertyType(
261                 new ResourceSpecificEndpointProperty(
262                         "default-endpoint-property-map.property"));
263         EndpointPropertyValue epv = new EndpointPropertyValue("PID1");
264
265         endpointPropertyMap.put("0.0.0.0", "ipv4");
266
267         Properties ps = new PropertiesBuilder().setPropertyType(etp)
268                 .setProperty(epv).build();
269         List<Properties> psList = new ArrayList<Properties>();
270         psList.add(ps);
271
272         EndpointProperties ep = new EndpointPropertiesBuilder()
273                 .setEndpoint(tea).setProperties(psList).build();
274         List<EndpointProperties> epList = new ArrayList<EndpointProperties>();
275         epList.add(ep);
276
277         EndpointPropertyMap epm = new EndpointPropertyMapBuilder()
278                 .setMeta(meta).setEndpointProperties(epList).build();
279
280         final WriteTransaction tx = dataService.newWriteOnlyTransaction();
281         try {
282             tx.put(LogicalDatastoreType.CONFIGURATION, ALTO_EPM, epm, true);
283         } catch (Exception e) {
284             e.printStackTrace();
285         }
286         submit(tx);
287
288     }
289
290     private Resources buildResources() {
291         try {
292             return new ResourcesBuilder().setNetworkMaps(loadNetworkMaps())
293                     .build();
294         } catch (Exception e) {
295             e.printStackTrace();
296         }
297
298         return null;
299     }
300
301     private NetworkMaps loadNetworkMaps() throws Exception {
302         return new NetworkMapsBuilder().setNetworkMap(loadNetworkMapList())
303                 .build();
304     }
305
306     private List<NetworkMap> loadNetworkMapList() {
307         List<NetworkMap> networkMapList = new ArrayList<NetworkMap>();
308         ResourceId rid = new ResourceId(new ValidIdString(NMRESOURCEID));
309         this.networkTag = TagGenerator.getTag(32);
310         TagString tag = new TagString(this.networkTag);
311         ValidIdString vis = new ValidIdString("pid0");
312         PidName pid = new PidName(vis);
313         IpPrefix ep = new IpPrefix(new Ipv4Prefix("0.0.0.0/0"));
314
315         networkMap.put("0.0.0.0/0", "pid0");
316
317         List<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map> mapList = new ArrayList<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map>();
318
319         List<IpPrefix> epList = new ArrayList<IpPrefix>();
320         epList.add(ep);
321
322         EndpointAddressGroup eag = new EndpointAddressGroupBuilder()
323                 .setAddressType(
324                         new EndpointAddressType(
325                                 EndpointAddressType.Enumeration.Ipv4))
326                 .setEndpointPrefix(epList).build();
327
328         List<EndpointAddressGroup> eagList = new ArrayList<EndpointAddressGroup>();
329         eagList.add(eag);
330
331         org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map map = new MapBuilder()
332                 .setPid(pid).setEndpointAddressGroup(eagList).build();
333
334         mapList.add(map);
335
336         NetworkMap networkMap = new NetworkMapBuilder().setResourceId(rid)
337                 .setTag(tag).setMap(mapList).build();
338
339         networkMapList.add(networkMap);
340
341         return networkMapList;
342     }
343
344     public void writeTest() {
345         InstanceIdentifier<NetworkMaps> ALTO_IID = InstanceIdentifier
346                 .builder(Resources.class).child(NetworkMaps.class).build();
347         final WriteTransaction tx = dataService.newWriteOnlyTransaction();
348         try {
349             tx.put(LogicalDatastoreType.CONFIGURATION, ALTO_IID,
350                     loadNetworkMaps(), true);
351         } catch (Exception e) {
352         }
353         final CheckedFuture writeTxResultFuture = tx.submit();
354         Futures.addCallback(writeTxResultFuture, new FutureCallback<Void>() {
355             @Override
356             public void onSuccess(final Void result) {
357                 log.info("write success.");
358                 notifyCallback(true);
359             }
360
361             @Override
362             public void onFailure(final Throwable t) {
363                 log.error("Failed to initiate resources", t);
364                 notifyCallback(false);
365             }
366
367             void notifyCallback(final boolean result) {
368             }
369         });
370     }
371
372     public void readTest() {
373         InstanceIdentifier<Resources> resources = InstanceIdentifier.builder(
374                 Resources.class).build();
375         ListenableFuture<Optional<Resources>> futureResources;
376         try (ReadOnlyTransaction readTx = dataService.newReadOnlyTransaction()) {
377             futureResources = readTx.read(LogicalDatastoreType.OPERATIONAL,
378                     resources);
379             readTx.close();
380         }
381         Optional<Resources> opNodes = null;
382         try {
383             opNodes = futureResources.get();
384         } catch (ExecutionException | InterruptedException ex) {
385             log.warn(ex.getLocalizedMessage());
386         }
387         if (opNodes != null && opNodes.isPresent())
388             log.info("resources:" + opNodes.get());
389     }
390
391     public void mergeEndpointPropertyMapForAddresses(Addresses addrs) {
392         if (addrs == null) {// || addrs.getIp() == null || addrs.getMac() ==
393                             // null
394             // IpPrefix ep = new IpPrefix(new Ipv4Prefix("1.1.1.1/32"));
395             // epList.add(ep);
396             return;
397         } else {
398             String ipAddress = addrs.getIp().toString();
399             String mac = addrs.getMac().toString();
400             Matcher m = p.matcher(ipAddress);
401             if (m.find())
402                 ipAddress = m.group();
403             else
404                 return;
405             if (endpointPropertyMap.containsKey(ipAddress))
406                 return;
407
408             TypedIpv4Address ti4 = new TypedIpv4Address("ipv4:" + ipAddress);
409             TypedEndpointAddress tea = new TypedEndpointAddress(ti4);
410
411             EndpointPropertyType etp1 = new EndpointPropertyType(
412                     new ResourceSpecificEndpointProperty(
413                             "default-endpoint-property-map.pid"));
414             EndpointPropertyValue epv1 = new EndpointPropertyValue("PID1");
415
416             EndpointPropertyType etp2 = new EndpointPropertyType(
417                     new ResourceSpecificEndpointProperty("priv:ietf-mac.prop"));
418             EndpointPropertyValue epv2 = new EndpointPropertyValue(mac);
419
420             endpointPropertyMap.put(ipAddress, "ipv4");
421
422             Properties ps1 = new PropertiesBuilder().setPropertyType(etp1)
423                     .setProperty(epv1).build();
424             Properties ps2 = new PropertiesBuilder().setPropertyType(etp2)
425                     .setProperty(epv2).build();
426
427             List<Properties> psList = new ArrayList<Properties>();
428             psList.add(ps1);
429             psList.add(ps2);
430
431             EndpointProperties ep = new EndpointPropertiesBuilder()
432                     .setEndpoint(tea).setProperties(psList).build();
433
434             InstanceIdentifier<EndpointProperties> ALTO_EP = InstanceIdentifier
435                     .builder(Resources.class)
436                     .child(EndpointPropertyMap.class)
437                     .child(EndpointProperties.class,
438                             new EndpointPropertiesKey(tea)).build();
439
440             final WriteTransaction tx = dataService.newWriteOnlyTransaction();
441             if (tx == null)
442                 return;
443             try {
444                 tx.merge(LogicalDatastoreType.CONFIGURATION, ALTO_EP, ep, true);
445             } catch (Exception e) {
446                 e.printStackTrace();
447             }
448             submit(tx);
449         }
450
451     }
452
453     public void mergeNetworkMapForAddressesList(List<Addresses> addrsList,
454             String resourceIdString, String pidString, String addressType) {
455         ResourceId rid = new ResourceId(new ValidIdString(resourceIdString));
456         ValidIdString vis = new ValidIdString(pidString);
457         PidName pid = new PidName(vis);
458
459         EndpointAddressType eat;
460         if (addressType == "ipv4") {
461             eat = new EndpointAddressType(EndpointAddressType.Enumeration.Ipv4);
462         } else {
463             eat = new EndpointAddressType(EndpointAddressType.Enumeration.Ipv6);
464         }
465
466         InstanceIdentifier<EndpointAddressGroup> ALTO_EAG = InstanceIdentifier
467                 .builder(Resources.class)
468                 .child(NetworkMaps.class)
469                 .child(NetworkMap.class, new NetworkMapKey(rid))
470                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map.class,
471                         new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.MapKey(
472                                 pid))
473                 .child(EndpointAddressGroup.class,
474                         new EndpointAddressGroupKey(eat)).build();
475
476         List<IpPrefix> epList = new ArrayList<IpPrefix>();
477
478         if (addrsList == null) {
479             // IpPrefix ep = new IpPrefix(new Ipv4Prefix("1.1.1.1/32"));
480             // epList.add(ep);
481             return;
482         } else {
483             for (int i = 0; i < addrsList.size(); i++) {
484                 Addresses addrs = addrsList.get(i);
485                 if (addrs.getIp() == null)
486                     continue;
487                 String ipAddress = addrs.getIp().toString();
488
489                 Matcher m = p.matcher(ipAddress);
490                 if (m.find())
491                     ipAddress = m.group();
492                 else
493                     continue;
494                 ipAddress += "/32";
495                 if (networkMap.containsKey(ipAddress))
496                     continue;
497                 IpPrefix ep = new IpPrefix(new Ipv4Prefix(ipAddress));
498                 epList.add(ep);
499                 networkMap.put(ipAddress, pidString);
500             }
501         }
502         if (epList.size() == 0)
503             return;
504
505         final WriteTransaction tx = dataService.newWriteOnlyTransaction();
506
507         if (tx == null)
508             return;
509
510         EndpointAddressGroup eag = new EndpointAddressGroupBuilder()
511                 .setAddressType(
512                         new EndpointAddressType(
513                                 EndpointAddressType.Enumeration.Ipv4))
514                 .setEndpointPrefix(epList).build();
515
516         try {
517             tx.merge(LogicalDatastoreType.CONFIGURATION, ALTO_EAG, eag, true);
518         } catch (Exception e) {
519             e.printStackTrace();
520         }
521         submit(tx);
522     }
523
524     public void removeAddressesList(List<Addresses> addrsList,
525             String resourceIdString, String pidString, String addressType) {
526         if (addrsList == null) {
527             return;
528         } else {
529             for (int i = 0; i < addrsList.size(); i++) {
530                 Addresses addrs = addrsList.get(i);
531                 if (addrs.getIp() == null)
532                     continue;
533                 String ipAddress = addrs.getIp().toString();
534
535                 Matcher m = p.matcher(ipAddress);
536                 if (m.find())
537                     ipAddress = m.group();
538                 else
539                     continue;
540
541                 if (endpointPropertyMap.containsKey(ipAddress))
542                     endpointPropertyMap.remove(ipAddress);
543                 else
544                     continue;
545
546                 TypedIpv4Address ti4 = new TypedIpv4Address("ipv4:" + ipAddress);
547                 TypedEndpointAddress tea = new TypedEndpointAddress(ti4);
548
549                 InstanceIdentifier<EndpointProperties> ALTO_EP = InstanceIdentifier
550                         .builder(Resources.class)
551                         .child(EndpointPropertyMap.class)
552                         .child(EndpointProperties.class,
553                                 new EndpointPropertiesKey(tea)).build();
554
555                 final WriteTransaction writeTx = this.dataService
556                         .newWriteOnlyTransaction();
557                 writeTx.delete(LogicalDatastoreType.OPERATIONAL, ALTO_EP);
558                 submit(writeTx);
559
560                 ipAddress += "/32";
561                 if (networkMap.containsKey(ipAddress))
562                     networkMap.remove(ipAddress);
563                 else
564                     continue;
565
566             }
567         }
568
569         ResourceId rid = new ResourceId(new ValidIdString(resourceIdString));
570         ValidIdString vis = new ValidIdString(pidString);
571         PidName pid = new PidName(vis);
572
573         EndpointAddressType eat;
574         if (addressType == "ipv4") {
575             eat = new EndpointAddressType(EndpointAddressType.Enumeration.Ipv4);
576         } else {
577             eat = new EndpointAddressType(EndpointAddressType.Enumeration.Ipv6);
578         }
579
580         InstanceIdentifier<EndpointAddressGroup> ALTO_EAG = InstanceIdentifier
581                 .builder(Resources.class)
582                 .child(NetworkMaps.class)
583                 .child(NetworkMap.class, new NetworkMapKey(rid))
584                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map.class,
585                         new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.MapKey(
586                                 pid))
587                 .child(EndpointAddressGroup.class,
588                         new EndpointAddressGroupKey(eat)).build();
589
590         List<IpPrefix> epList = new ArrayList<IpPrefix>();
591
592         Iterator iter = networkMap.entrySet().iterator();
593         while (iter.hasNext()) {
594             Map.Entry<String, String> entry = (Map.Entry<String, String>) iter
595                     .next();
596             String ipAddress = entry.getKey();
597
598             IpPrefix ep = new IpPrefix(new Ipv4Prefix(ipAddress));
599             epList.add(ep);
600         }
601
602         if (epList.size() == 0) {
603             InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map> ALTO_MP = InstanceIdentifier
604                     .builder(Resources.class)
605                     .child(NetworkMaps.class)
606                     .child(NetworkMap.class, new NetworkMapKey(rid))
607                     .child(org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.Map.class,
608                             new org.opendaylight.yang.gen.v1.urn.opendaylight.alto.rev150404.network.map.MapKey(
609                                     pid)).build();
610
611             final WriteTransaction tx = dataService.newWriteOnlyTransaction();
612             if (tx == null)
613                 return;
614             try {
615                 tx.delete(LogicalDatastoreType.CONFIGURATION, ALTO_MP);
616             } catch (Exception e) {
617                 e.printStackTrace();
618             }
619             submit(tx);
620         } else {
621             EndpointAddressGroup eag = new EndpointAddressGroupBuilder()
622                     .setAddressType(
623                             new EndpointAddressType(
624                                     EndpointAddressType.Enumeration.Ipv4))
625                     .setEndpointPrefix(epList).build();
626
627             final WriteTransaction tx = dataService.newWriteOnlyTransaction();
628             if (tx == null)
629                 return;
630             try {
631                 tx.put(LogicalDatastoreType.CONFIGURATION, ALTO_EAG, eag, true);
632             } catch (Exception e) {
633                 e.printStackTrace();
634             }
635             submit(tx);
636         }
637     }
638
639     public void registerAsDataChangeListener() {
640         ResourceId ridForDelete = new ResourceId(NMRESOURCEID);
641         InstanceIdentifier<NetworkMap> networkMapForDelete = InstanceIdentifier
642                 .builder(Resources.class).child(NetworkMaps.class)
643                 .child(NetworkMap.class, new NetworkMapKey(ridForDelete))
644                 .build();
645
646         InstanceIdentifier<HostNode> hostNodes = InstanceIdentifier
647                 .builder(NetworkTopology.class)//
648                 .child(Topology.class,
649                         new TopologyKey(new TopologyId(topologyId)))//
650                 .child(Node.class).augmentation(HostNode.class).build();
651
652         InstanceIdentifier<Addresses> addrCapableNodeConnectors = //
653         InstanceIdentifier
654                 .builder(Nodes.class)
655                 //
656                 .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class) //
657                 .child(NodeConnector.class) //
658                 .augmentation(AddressCapableNodeConnector.class)//
659                 .child(Addresses.class).build();
660
661         // ReadOnlyTransaction newReadOnlyTransaction =
662         // dataService.newReadOnlyTransaction();
663         InstanceIdentifier<Nodes> iins = addrCapableNodeConnectors
664                 .firstIdentifierOf(Nodes.class);
665         // InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node>
666         // iin//
667         // =
668         // addrCapableNodeConnectors.firstIdentifierOf(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class);
669         // ListenableFuture<Optional<NodeConnector>> dataFuture =
670         // newReadOnlyTransaction.read(LogicalDatastoreType.OPERATIONAL, iinc);
671         ListenableFuture<Optional<Nodes>> futureNodes;
672         /*
673          * try { NodeConnector get = dataFuture.get().get();
674          * log.info("test "+get); } catch (InterruptedException |
675          * ExecutionException ex) {
676          * //java.util.logging.Logger.getLogger(HostTracker2Impl
677          * .class.getName()).log(Level.SEVERE, null, ex);
678          * log.info("exception on get"); }
679          */
680         try (ReadOnlyTransaction readTx = dataService.newReadOnlyTransaction()) {
681             futureNodes = readTx.read(LogicalDatastoreType.OPERATIONAL, iins);
682             // futureNode = readTx.read(LogicalDatastoreType.OPERATIONAL, iin);
683             readTx.close();
684         }
685         Optional<Nodes> opNodes = null;
686         try {
687             opNodes = futureNodes.get();
688         } catch (ExecutionException | InterruptedException ex) {
689             log.warn(ex.getLocalizedMessage());
690         }
691
692         List<Addresses> addrsList = new ArrayList<Addresses>();
693         if (opNodes != null && opNodes.isPresent()) {
694             // log.info("node connector:"+opNodes.get());
695             Nodes ns = opNodes.get();
696             for (org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node n : ns
697                     .getNode()) {
698                 for (NodeConnector nc : n.getNodeConnector()) {
699                     AddressCapableNodeConnector acnc = nc
700                             .getAugmentation(AddressCapableNodeConnector.class);
701                     if (acnc != null) {
702                         for (Addresses addrs : acnc.getAddresses()) {
703                             log.info("existing address: " + addrs);
704                             addrsList.add(addrs);
705                             mergeEndpointPropertyMapForAddresses(addrs);
706                         }
707                     }
708                 }
709             }
710         }
711         mergeNetworkMapForAddressesList(addrsList, NMRESOURCEID, "pid1", "ipv4");
712         /*
713          * Futures.addCallback(dataFuture, new
714          * FutureCallback<Optional<NodeConnector>>() {
715          * @Override public void onSuccess(final Optional<NodeConnector> result)
716          * { if (result.isPresent()) { log.info("Processing NEW NODE? " +
717          * result.get().getId().getValue()); // processHost(result, dataObject,
718          * node); } }
719          * @Override public void onFailure(Throwable arg0) { } });
720          */
721
722         this.hostNodeListerRegistration = dataService
723                 .registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
724                         hostNodes, this, DataChangeScope.SUBTREE);
725
726         this.networkMapListerRegistration = dataService
727                 .registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
728                         networkMapForDelete, this, DataChangeScope.BASE);
729
730         // log.info("register data change");
731     }
732
733     @Override
734     public void onDataChanged(
735             final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change) {
736         exec.submit(new Runnable() {
737             @Override
738             public void run() {
739                 if (change == null) {
740                     log.info("In onDataChanged: No processing done as change even is null.");
741                     return;
742                 }
743                 Map<InstanceIdentifier<?>, DataObject> updatedData = change
744                         .getUpdatedData();
745                 Map<InstanceIdentifier<?>, DataObject> createdData = change
746                         .getCreatedData();
747                 Map<InstanceIdentifier<?>, DataObject> originalData = change
748                         .getOriginalData();
749                 Set<InstanceIdentifier<?>> deletedData = change
750                         .getRemovedPaths();
751
752                 for (InstanceIdentifier<?> iid : deletedData) {
753                     log.info("deletedData");
754                     if (iid.getTargetType().equals(Node.class)) {
755                         Node node = ((Node) originalData.get(iid));
756                         HostNode hostNode = node
757                                 .getAugmentation(HostNode.class);
758                         if (hostNode != null) {
759                             List<Addresses> addrsList = hostNode.getAddresses();
760                             removeAddressesList(addrsList, NMRESOURCEID,
761                                     "pid1", "ipv4");
762                         }
763                     } else if (iid.getTargetType().equals(NetworkMap.class)) {
764                         networkMap.clear();
765                         endpointPropertyMap.clear();
766                         close();
767                         log.info("delete all!");
768                     }
769                 }
770
771                 for (Map.Entry<InstanceIdentifier<?>, DataObject> entrySet : updatedData
772                         .entrySet()) {
773                     InstanceIdentifier<?> iiD = entrySet.getKey();
774                     final DataObject dataObject = entrySet.getValue();
775                     if (dataObject instanceof Addresses) {
776                         Addresses addrs = (Addresses) dataObject;
777                         log.info("updatedData addresses:" + addrs);
778                         List<Addresses> addrsList = new ArrayList();
779                         addrsList.add(addrs);
780                         mergeNetworkMapForAddressesList(addrsList,
781                                 NMRESOURCEID, "pid1", "ipv4");
782                         mergeEndpointPropertyMapForAddresses(addrs);
783
784                     } else if (dataObject instanceof Node) {
785                         log.info("updatedData node");
786                     }
787                 }
788
789                 for (Map.Entry<InstanceIdentifier<?>, DataObject> entrySet : createdData
790                         .entrySet()) {
791                     InstanceIdentifier<?> iiD = entrySet.getKey();
792                     final DataObject dataObject = entrySet.getValue();
793                     if (dataObject instanceof Addresses) {
794                         Addresses addrs = (Addresses) dataObject;
795                         log.info("createdData addresses:" + addrs);
796                         List<Addresses> addrsList = new ArrayList();
797                         addrsList.add(addrs);
798                         mergeNetworkMapForAddressesList(addrsList,
799                                 NMRESOURCEID, "pid1", "ipv4");
800                         mergeEndpointPropertyMapForAddresses(addrs);
801                     } else if (dataObject instanceof Node) {
802                         log.info("createdData node");
803                     }
804                 }
805             }
806         });
807     }
808
809     public void close() {
810         this.hostNodeListerRegistration.close();
811     }
812 }