2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
\r
4 * This program and the accompanying materials are made available under the
\r
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
\r
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
\r
9 package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;
\r
11 import java.io.Closeable;
\r
12 import java.util.ArrayList;
\r
13 import java.util.Collection;
\r
14 import java.util.LinkedHashSet;
\r
15 import java.util.List;
\r
16 import java.util.Set;
\r
17 import java.util.concurrent.ExecutionException;
\r
19 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
\r
20 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
\r
21 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
\r
22 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;
\r
23 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
\r
24 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
\r
25 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
\r
27 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId;
\r
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
\r
29 import org.opendaylight.yangtools.yang.binding.DataObject;
\r
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
\r
31 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
\r
32 import org.slf4j.Logger;
\r
33 import org.slf4j.LoggerFactory;
\r
35 import com.google.common.annotations.VisibleForTesting;
\r
36 import com.google.common.collect.Iterators;
\r
37 import com.google.common.collect.PeekingIterator;
\r
39 public class NeutronListener implements ClusteredDataTreeChangeListener<Neutron>, Closeable {
\r
41 private static final Logger LOG = LoggerFactory.getLogger(NeutronListener.class);
\r
43 private final Set<MappingProvider<? extends DataObject>> dataChangeProviders = new LinkedHashSet<>();
\r
44 protected ListenerRegistration<NeutronListener> registeredListener;
\r
46 public NeutronListener(DataBroker dataBroker, NodeId routingNode) {
\r
47 LOG.info("Routing node chosen in ODL is {}", routingNode);
\r
48 registerHandlersAndListeners(dataBroker, routingNode);
\r
49 registeredListener = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
\r
50 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), this);
\r
53 private void registerHandlersAndListeners(DataBroker dataBroker, NodeId routingNode) {
\r
54 PortHandler portHandler = new PortHandler(dataBroker, routingNode);
\r
55 dataChangeProviders.add(new PortAware(portHandler, dataBroker));
\r
56 dataChangeProviders.add(new NetworkAware(dataBroker));
\r
60 public void onDataTreeChanged(Collection<DataTreeModification<Neutron>> changes) {
\r
61 for (DataTreeModification<Neutron> change : changes) {
\r
62 DataObjectModification<Neutron> rootNode = change.getRootNode();
\r
63 for (MappingProvider<? extends DataObject> provider : dataChangeProviders) {
\r
64 for (DataObjectModification<? extends DataObject> modDto : findModifiedData(provider, rootNode)) {
\r
66 processChangedData(modDto, modDto.getModificationType(), provider);
\r
67 } catch (InterruptedException | ExecutionException e) {
\r
68 LOG.error("Failed to process {} modification of node: {}. {}", modDto.getModificationType(),
\r
69 modDto.getIdentifier(), e.getStackTrace());
\r
76 List<DataObjectModification<? extends DataObject>> findModifiedData(MappingProvider<? extends DataObject> provider,
\r
77 DataObjectModification<Neutron> rootNode) {
\r
78 List<DataObjectModification<? extends DataObject>> modDtos = new ArrayList<>();
\r
79 PeekingIterator<PathArgument> pathArgs = Iterators.peekingIterator(provider.getNeutronDtoIid()
\r
82 DataObjectModification<? extends DataObject> modifDto = rootNode;
\r
83 while (pathArgs.hasNext()) {
\r
85 for (DataObjectModification<? extends DataObject> childDto : modifDto.getModifiedChildren()) {
\r
86 if (pathArgs.hasNext() && childDto.getDataType().equals(pathArgs.peek().getType())) {
\r
87 if (childDto.getDataType().equals(provider.getNeutronDtoIid().getTargetType())) {
\r
88 modDtos.add(childDto);
\r
90 modifDto = childDto;
\r
99 @SuppressWarnings("unchecked")
\r
100 <T extends DataObject> void processChangedData(DataObjectModification<?> dto, ModificationType m,
\r
101 MappingProvider<T> processor) throws InterruptedException, ExecutionException {
\r
104 if (dto.getDataBefore() != null) {
\r
105 processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());
\r
107 processor.processCreatedNeutronDto((T) dto.getDataAfter());
\r
111 case SUBTREE_MODIFIED: {
\r
112 processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());
\r
116 processor.processDeletedNeutronDto((T) dto.getDataBefore());
\r
123 void clearDataChangeProviders() {
\r
124 dataChangeProviders.clear();
\r
128 <T extends DataObject> void addDataChangeProvider(MappingProvider<T> t) {
\r
129 dataChangeProviders.add(t);
\r
133 public void close() {
\r
134 registeredListener.close();
\r