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.groupbasedpolicy.neutron.vpp.mapper.SocketInfo;
\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
\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, SocketInfo socketInfo) {
\r
47 registerHandlersAndListeners(dataBroker, socketInfo);
\r
48 registeredListener = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(
\r
49 LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), this);
\r
52 private void registerHandlersAndListeners(DataBroker dataBroker, SocketInfo socketInfo) {
\r
53 PortHandler portHandler = new PortHandler(dataBroker, socketInfo);
\r
54 dataChangeProviders.add(new PortAware(portHandler, dataBroker));
\r
55 dataChangeProviders.add(new NetworkAware(dataBroker));
\r
59 public void onDataTreeChanged(Collection<DataTreeModification<Neutron>> changes) {
\r
60 for (DataTreeModification<Neutron> change : changes) {
\r
61 DataObjectModification<Neutron> rootNode = change.getRootNode();
\r
62 for (MappingProvider<? extends DataObject> provider : dataChangeProviders) {
\r
63 for (DataObjectModification<? extends DataObject> modDto : findModifiedData(provider, rootNode)) {
\r
65 processChangedData(modDto, modDto.getModificationType(), provider);
\r
66 } catch (InterruptedException | ExecutionException e) {
\r
67 LOG.error("Failed to process {} modification of node: {}. {}", modDto.getModificationType(),
\r
68 modDto.getIdentifier(), e.getStackTrace());
\r
75 List<DataObjectModification<? extends DataObject>> findModifiedData(MappingProvider<? extends DataObject> provider,
\r
76 DataObjectModification<Neutron> rootNode) {
\r
77 List<DataObjectModification<? extends DataObject>> modDtos = new ArrayList<>();
\r
78 PeekingIterator<PathArgument> pathArgs = Iterators.peekingIterator(provider.getNeutronDtoIid()
\r
81 DataObjectModification<? extends DataObject> modifDto = rootNode;
\r
82 while (pathArgs.hasNext()) {
\r
84 for (DataObjectModification<? extends DataObject> childDto : modifDto.getModifiedChildren()) {
\r
85 if (pathArgs.hasNext() && childDto.getDataType().equals(pathArgs.peek().getType())) {
\r
86 if (childDto.getDataType().equals(provider.getNeutronDtoIid().getTargetType())) {
\r
87 modDtos.add(childDto);
\r
89 modifDto = childDto;
\r
98 @SuppressWarnings("unchecked")
\r
99 <T extends DataObject> void processChangedData(DataObjectModification<?> dto, ModificationType m,
\r
100 MappingProvider<T> processor) throws InterruptedException, ExecutionException {
\r
103 if (dto.getDataBefore() != null) {
\r
104 processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());
\r
106 processor.processCreatedNeutronDto((T) dto.getDataAfter());
\r
110 case SUBTREE_MODIFIED: {
\r
111 processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());
\r
115 processor.processDeletedNeutronDto((T) dto.getDataBefore());
\r
122 void clearDataChangeProviders() {
\r
123 dataChangeProviders.clear();
\r
127 <T extends DataObject> void addDataChangeProvider(MappingProvider<T> t) {
\r
128 dataChangeProviders.add(t);
\r
132 public void close() {
\r
133 registeredListener.close();
\r