2 * Copyright (c) 2016 Cisco Systems, Inc. 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
9 package org.opendaylight.groupbasedpolicy.location.resolver;
11 import java.util.Collection;
12 import java.util.Collections;
13 import java.util.HashMap;
14 import java.util.List;
17 import javax.annotation.Nullable;
19 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
20 import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;
21 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
22 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
23 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
24 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
25 import org.opendaylight.groupbasedpolicy.util.IidFactory;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocation;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.AddressEndpointLocationKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocation;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoint.locations.ContainmentEndpointLocationKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocation;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.InternalLocation;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.LocationProviders;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocation;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderContainmentEndpointLocation;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderContainmentEndpointLocationKey;
41 import org.opendaylight.yangtools.concepts.ListenerRegistration;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 public class LocationResolver implements DataTreeChangeListener<LocationProvider>, AutoCloseable {
48 private static final Logger LOG = LoggerFactory.getLogger(LocationResolver.class);
49 private Map<AddressEndpointLocationKey, Map<Long, AbsoluteLocation>> realLocations;
50 private DataBroker dataBroker;
51 private ListenerRegistration<LocationResolver> listenerRegistation;
53 public LocationResolver(DataBroker dataBroker) {
54 this.dataBroker = dataBroker;
55 this.realLocations = new HashMap<>();
56 this.listenerRegistation = dataBroker.registerDataTreeChangeListener(
57 new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL,
58 InstanceIdentifier.builder(LocationProviders.class).child(LocationProvider.class).build()),
63 public synchronized void onDataTreeChanged(Collection<DataTreeModification<LocationProvider>> changes) {
64 for (DataTreeModification<LocationProvider> change : changes) {
65 WriteTransaction wtx = dataBroker.newWriteOnlyTransaction();
66 switch (change.getRootNode().getModificationType()) {
68 processRemovedLocationProviderData(change.getRootNode().getDataBefore(), wtx);
69 LOG.debug("Data from location provider {} has been removed",
70 change.getRootNode().getDataBefore().getProvider().getValue());
74 if (change.getRootNode().getDataBefore() != null) {
75 processRemovedLocationProviderData(change.getRootNode().getDataBefore(), wtx);
77 processCreatedLocationProviderData(change.getRootNode().getDataAfter(), wtx);
78 LOG.debug("Data from location provider {} has been created",
79 change.getRootNode().getDataAfter().getProvider().getValue());
82 case SUBTREE_MODIFIED: {
83 processRemovedLocationProviderData(change.getRootNode().getDataBefore(), wtx);
84 processCreatedLocationProviderData(change.getRootNode().getDataAfter(), wtx);
85 LOG.debug("Data from location provider {} has been changed",
86 change.getRootNode().getDataAfter().getProvider().getValue());
94 private void processRemovedLocationProviderData(LocationProvider provider, WriteTransaction wtx) {
95 for (ProviderAddressEndpointLocation addressEndpointLocation : nullToEmpty(
96 provider.getProviderAddressEndpointLocation())) {
97 AddressEndpointLocationKey epKey = createAddressEndpointLocationKey(addressEndpointLocation.getKey());
99 if (provider.getPriority() == null) {
101 LOG.debug("{} provider doesn't provide priority. Using 0 as priority instead.",
102 provider.getProvider().getValue());
104 priority = provider.getPriority();
106 realLocations.get(epKey).remove(priority);
107 AbsoluteLocation newAbsoluteLocation = getBestAbsoluteLocation(epKey);
108 if (newAbsoluteLocation == null) {
109 InstanceIdentifier<AbsoluteLocation> iid = IidFactory.absoluteLocationIid(epKey);
110 wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
112 AddressEndpointLocationBuilder newEP =
113 new AddressEndpointLocationBuilder().setKey(epKey).setAbsoluteLocation(newAbsoluteLocation);
114 InstanceIdentifier<AddressEndpointLocation> iid = IidFactory.addressEndpointLocationIid(newEP.getKey());
115 wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, newEP.build(), true);
117 if (addressEndpointLocation.getRelativeLocations() != null) {
118 for (InternalLocation location : nullToEmpty(
119 addressEndpointLocation.getRelativeLocations().getInternalLocation())) {
120 InstanceIdentifier<InternalLocation> iid = IidFactory.internalLocationIid(epKey, location.getKey());
121 wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
123 for (ExternalLocation location : nullToEmpty(
124 addressEndpointLocation.getRelativeLocations().getExternalLocation())) {
125 InstanceIdentifier<ExternalLocation> iid = IidFactory.externalLocationIid(epKey, location.getKey());
126 wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
130 for (ProviderContainmentEndpointLocation containmentEndpoint : nullToEmpty(
131 provider.getProviderContainmentEndpointLocation())) {
132 ContainmentEndpointLocationKey epKey = createContainmentEndpointLocationKey(containmentEndpoint.getKey());
133 if (containmentEndpoint.getRelativeLocations() != null) {
134 for (InternalLocation location : nullToEmpty(
135 containmentEndpoint.getRelativeLocations().getInternalLocation())) {
136 InstanceIdentifier<InternalLocation> iid = IidFactory.internalLocationIid(epKey, location.getKey());
137 wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
139 for (ExternalLocation location : nullToEmpty(
140 containmentEndpoint.getRelativeLocations().getExternalLocation())) {
141 InstanceIdentifier<ExternalLocation> iid = IidFactory.externalLocationIid(epKey, location.getKey());
142 wtx.delete(LogicalDatastoreType.OPERATIONAL, iid);
148 private void processCreatedLocationProviderData(LocationProvider provider, WriteTransaction wtx) {
149 for (ProviderAddressEndpointLocation addressEndpointLocation : nullToEmpty(
150 provider.getProviderAddressEndpointLocation())) {
151 AddressEndpointLocationKey epKey = createAddressEndpointLocationKey(addressEndpointLocation.getKey());
152 AddressEndpointLocationBuilder newEP = new AddressEndpointLocationBuilder().setKey(epKey);
153 if (addressEndpointLocation.getAbsoluteLocation() != null) {
154 if (realLocations.get(epKey) == null) {
155 realLocations.put(epKey, new HashMap<>());
158 if (provider.getPriority() == null) {
160 LOG.debug("{} provider doesnt provide priority. Using 0 as priority instead.",
161 provider.getProvider().getValue());
163 priority = provider.getPriority();
165 realLocations.get(epKey).put(priority, addressEndpointLocation.getAbsoluteLocation());
167 AbsoluteLocation bestLocation = getBestAbsoluteLocation(epKey);
168 if (bestLocation != null) {
169 newEP.setAbsoluteLocation(bestLocation);
171 if (addressEndpointLocation.getRelativeLocations() != null) {
172 newEP.setRelativeLocations(addressEndpointLocation.getRelativeLocations());
174 InstanceIdentifier<AddressEndpointLocation> iid = IidFactory.addressEndpointLocationIid(newEP.getKey());
175 wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, newEP.build(), true);
177 for (ProviderContainmentEndpointLocation containmentEndpointLocation : nullToEmpty(
178 provider.getProviderContainmentEndpointLocation())) {
179 if (containmentEndpointLocation.getRelativeLocations() != null) {
180 ContainmentEndpointLocationKey key =
181 createContainmentEndpointLocationKey(containmentEndpointLocation.getKey());
182 ContainmentEndpointLocationBuilder newEP = new ContainmentEndpointLocationBuilder().setKey(key);
183 newEP.setRelativeLocations(containmentEndpointLocation.getRelativeLocations());
184 InstanceIdentifier<ContainmentEndpointLocation> iid =
185 IidFactory.containmentEndpointLocationIid(newEP.getKey());
186 wtx.merge(LogicalDatastoreType.OPERATIONAL, iid, newEP.build(), true);
191 private AbsoluteLocation getBestAbsoluteLocation(AddressEndpointLocationKey epKey) {
192 if (realLocations.get(epKey) == null) {
195 long bestPriority = -1;
196 for (long priority : realLocations.get(epKey).keySet()) {
197 bestPriority = bestPriority > priority ? bestPriority : priority;
199 if (bestPriority == -1) {
202 return (realLocations.get(epKey).get(new Long(bestPriority)));
205 private AddressEndpointLocationKey createAddressEndpointLocationKey(ProviderAddressEndpointLocationKey key) {
206 return new AddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(),
207 key.getContextType());
210 private ContainmentEndpointLocationKey createContainmentEndpointLocationKey(
211 ProviderContainmentEndpointLocationKey key) {
212 return new ContainmentEndpointLocationKey(key.getContextId(), key.getContextType());
215 private <T> List<T> nullToEmpty(@Nullable List<T> list) {
216 return list == null ? Collections.emptyList() : list;
220 public void close() throws Exception {
221 listenerRegistation.close();