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.neutron.vpp.mapper.processors;
11 import java.io.Closeable;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.LinkedHashSet;
15 import java.util.List;
17 import java.util.concurrent.ExecutionException;
19 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
21 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
22 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
23 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
24 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
29 import org.opendaylight.yangtools.yang.binding.DataObject;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 import com.google.common.annotations.VisibleForTesting;
36 import com.google.common.collect.Iterators;
37 import com.google.common.collect.PeekingIterator;
39 public class NeutronListener implements ClusteredDataTreeChangeListener<Neutron>, Closeable {
41 private static final Logger LOG = LoggerFactory.getLogger(NeutronListener.class);
43 private final Set<MappingProvider<? extends DataObject>> dataChangeProviders = new LinkedHashSet<>();
44 protected ListenerRegistration<NeutronListener> registeredListener;
46 public NeutronListener(DataBroker dataBroker, NodeId routingNode) {
47 LOG.info("Routing node chosen in ODL is {}", routingNode);
48 registerHandlersAndListeners(dataBroker, routingNode);
49 registeredListener = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
50 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), this);
53 private void registerHandlersAndListeners(DataBroker dataBroker, NodeId routingNode) {
54 PortHandler portHandler = new PortHandler(dataBroker, routingNode);
55 dataChangeProviders.add(new PortAware(portHandler, dataBroker));
56 dataChangeProviders.add(new NetworkAware(dataBroker));
57 dataChangeProviders.add(new SubnetAware(dataBroker));
61 public void onDataTreeChanged(Collection<DataTreeModification<Neutron>> changes) {
62 for (DataTreeModification<Neutron> change : changes) {
63 DataObjectModification<Neutron> rootNode = change.getRootNode();
64 for (MappingProvider<? extends DataObject> provider : dataChangeProviders) {
65 for (DataObjectModification<? extends DataObject> modDto : findModifiedData(provider, rootNode)) {
67 processChangedData(modDto, modDto.getModificationType(), provider);
68 } catch (InterruptedException | ExecutionException e) {
69 LOG.error("Failed to process {} modification of node: {}. {}", modDto.getModificationType(),
70 modDto.getIdentifier(), e.getStackTrace());
77 List<DataObjectModification<? extends DataObject>> findModifiedData(MappingProvider<? extends DataObject> provider,
78 DataObjectModification<Neutron> rootNode) {
79 List<DataObjectModification<? extends DataObject>> modDtos = new ArrayList<>();
80 PeekingIterator<PathArgument> pathArgs = Iterators.peekingIterator(provider.getNeutronDtoIid()
83 DataObjectModification<? extends DataObject> modifDto = rootNode;
84 while (pathArgs.hasNext()) {
86 for (DataObjectModification<? extends DataObject> childDto : modifDto.getModifiedChildren()) {
87 if (pathArgs.hasNext() && childDto.getDataType().equals(pathArgs.peek().getType())) {
88 if (childDto.getDataType().equals(provider.getNeutronDtoIid().getTargetType())) {
89 modDtos.add(childDto);
100 @SuppressWarnings("unchecked")
101 <T extends DataObject> void processChangedData(DataObjectModification<?> dto, ModificationType m,
102 MappingProvider<T> processor) throws InterruptedException, ExecutionException {
105 if (dto.getDataBefore() != null) {
106 processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());
108 processor.processCreatedNeutronDto((T) dto.getDataAfter());
112 case SUBTREE_MODIFIED: {
113 processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());
117 processor.processDeletedNeutronDto((T) dto.getDataBefore());
124 void clearDataChangeProviders() {
125 dataChangeProviders.clear();
129 <T extends DataObject> void addDataChangeProvider(MappingProvider<T> t) {
130 dataChangeProviders.add(t);
134 public void close() {
135 registeredListener.close();