Baseline for neutron-vpp mapping
[groupbasedpolicy.git] / neutron-vpp-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / vpp / mapper / processors / NeutronListener.java
diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListener.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/NeutronListener.java
new file mode 100644 (file)
index 0000000..d8b5073
--- /dev/null
@@ -0,0 +1,122 @@
+/*\r
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
+ *\r
+ * This program and the accompanying materials are made available under the\r
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
+ * and is available at http://www.eclipse.org/legal/epl-v10.html\r
+ */\r
+\r
+package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors;\r
+\r
+import java.io.Closeable;\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.LinkedHashSet;\r
+import java.util.List;\r
+import java.util.Set;\r
+import java.util.concurrent.ExecutionException;\r
+\r
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;\r
+import org.opendaylight.controller.md.sal.binding.api.DataObjectModification.ModificationType;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeChangeListener;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;\r
+import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;\r
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;\r
+import org.opendaylight.yangtools.concepts.ListenerRegistration;\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;\r
+import org.slf4j.Logger;\r
+import org.slf4j.LoggerFactory;\r
+\r
+import com.google.common.collect.Iterators;\r
+import com.google.common.collect.PeekingIterator;\r
+\r
+public class NeutronListener implements DataTreeChangeListener<Neutron>, Closeable {\r
+\r
+    private static final Logger LOG = LoggerFactory.getLogger(NeutronListener.class);\r
+\r
+    private final Set<MappingProvider<? extends DataObject>> dataChangeProviders = new LinkedHashSet<>();\r
+    protected ListenerRegistration<NeutronListener> registeredListener;\r
+\r
+    public NeutronListener(DataBroker dataBroker) {\r
+        registerHandlersAndListeners(dataBroker);\r
+        registeredListener = dataBroker.registerDataTreeChangeListener(new DataTreeIdentifier<>(\r
+                LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.builder(Neutron.class).build()), this);\r
+    }\r
+\r
+    private void registerHandlersAndListeners(DataBroker dataBroker) {\r
+        PortHandler portHandler = new PortHandler(dataBroker);\r
+        dataChangeProviders.add(new BaseEndpointByPortListener(portHandler, dataBroker));\r
+    }\r
+\r
+    @Override\r
+    public void onDataTreeChanged(Collection<DataTreeModification<Neutron>> changes) {\r
+        for (DataTreeModification<Neutron> change : changes) {\r
+            DataObjectModification<Neutron> rootNode = change.getRootNode();\r
+            for (MappingProvider<? extends DataObject> provider : dataChangeProviders) {\r
+                for (DataObjectModification<? extends DataObject> modDto : findModifiedData(provider, rootNode)) {\r
+                    try {\r
+                        processChangedData(modDto, modDto.getModificationType(), provider);\r
+                    } catch (InterruptedException | ExecutionException e) {\r
+                        LOG.error("Failed to process {} modification of node: {}. {}", modDto.getModificationType(),\r
+                                modDto.getIdentifier(), e.getStackTrace());\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    List<DataObjectModification<? extends DataObject>> findModifiedData(MappingProvider<? extends DataObject> provider,\r
+            DataObjectModification<Neutron> rootNode) {\r
+        List<DataObjectModification<? extends DataObject>> modDtos = new ArrayList<>();\r
+        PeekingIterator<PathArgument> pathArgs = Iterators.peekingIterator(provider.getNeutronDtoIid()\r
+            .getPathArguments()\r
+            .iterator());\r
+        DataObjectModification<? extends DataObject> modifDto = rootNode;\r
+        while (pathArgs.hasNext()) {\r
+            pathArgs.next();\r
+            for (DataObjectModification<? extends DataObject> childDto : modifDto.getModifiedChildren()) {\r
+                if (pathArgs.hasNext() && childDto.getDataType().equals(pathArgs.peek().getType())) {\r
+                    if (childDto.getDataType().equals(provider.getNeutronDtoIid().getTargetType())) {\r
+                        modDtos.add(childDto);\r
+                    } else {\r
+                        modifDto = childDto;\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return modDtos;\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    <T extends DataObject> void processChangedData(DataObjectModification<?> dto, ModificationType m,\r
+            MappingProvider<T> processor) throws InterruptedException, ExecutionException {\r
+        switch (m) {\r
+            case WRITE: {\r
+                if (dto.getDataBefore() != null) {\r
+                    processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());\r
+                } else {\r
+                    processor.processCreatedNeutronDto((T) dto.getDataAfter());\r
+                }\r
+                break;\r
+            }\r
+            case SUBTREE_MODIFIED: {\r
+                processor.processUpdatedNeutronDto((T) dto.getDataBefore(), (T) dto.getDataAfter());\r
+                break;\r
+            }\r
+            case DELETE: {\r
+                processor.processDeletedNeutronDto((T) dto.getDataBefore());\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void close() {\r
+        registeredListener.close();\r
+    }\r
+}\r