TableFeatures Update,correcting InstanceIdentifier 99/2999/1
authorGaurav Bhagwani <gaurav.bhagwani@ericsson.com>
Fri, 22 Nov 2013 12:39:43 +0000 (18:09 +0530)
committerGaurav Bhagwani <gaurav.bhagwani@ericsson.com>
Fri, 22 Nov 2013 12:45:17 +0000 (18:15 +0530)
Signed-off-by: Gaurav Bhagwani <gaurav.bhagwani@ericsson.com>
Change-Id: I3722482a52a8b26cd48474838d21bf3ecc22a580

opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/FlowConsumerImpl.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/GroupConsumerImpl.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/MeterConsumerImpl.java
opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java [new file with mode: 0644]

index 9edb690a015dfb0edb98896e50cfc51602ac6b79..2ffe0ecd87eee775b08f6e5b51c1e0febcb66baf 100644 (file)
@@ -86,7 +86,8 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
     private boolean inContainerMode; // being used by global instance only
 
     public FlowConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Flows.class).toInstance();
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Flows.class).child(Flow.class)
+                .toInstance();
         flowService = FRMConsumerImpl.getProviderSession().getRpcService(SalFlowService.class);
 
         if (null == flowService) {
@@ -503,8 +504,7 @@ public class FlowConsumerImpl implements IForwardingRulesManager {
         }
 
         @Override
-        public void onNodeExperimenterErrorNotification(
-                NodeExperimenterErrorNotification notification) {
+        public void onNodeExperimenterErrorNotification(NodeExperimenterErrorNotification notification) {
             // TODO Auto-generated method stub
 
         };
index 85954910167730d4949f2422706a5d9579e81458..851e7d9b2685420b5093d8771770a64a3fe52250 100644 (file)
@@ -68,8 +68,8 @@ public class GroupConsumerImpl implements IForwardingRulesManager {
 
     public GroupConsumerImpl() {
 
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class)
-                .node(Group.class).toInstance();
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Groups.class).child(Group.class)
+                .toInstance();
         groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
 
         clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
index 7f7db3ba58ccb8d142c91a5b2c679f56213a70c6..bd0ceb3fea8011aaa575dea0e71e4cbb8a1032c9 100644 (file)
@@ -66,8 +66,8 @@ public class MeterConsumerImpl implements IForwardingRulesManager {
     private IContainer container;
 
     public MeterConsumerImpl() {
-        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class)
-                .node(Meter.class).toInstance();
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Meters.class).child(Meter.class)
+                .toInstance();
         meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);
         clusterMeterContainerService = FRMConsumerImpl.getClusterContainerService();
 
diff --git a/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java b/opendaylight/md-sal/forwardingrules-manager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/consumer/impl/TableFeaturesConsumerImpl.java
new file mode 100644 (file)
index 0000000..30556e4
--- /dev/null
@@ -0,0 +1,192 @@
+package org.opendaylight.controller.forwardingrulesmanager.consumer.impl;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.IContainer;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.config.rev131024.tables.Table;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.SalTableService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.UpdateTableInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.service.rev131026.table.update.UpdatedTableBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.features.TableFeatures;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class TableFeaturesConsumerImpl {
+    protected static final Logger logger = LoggerFactory.getLogger(TableFeaturesConsumerImpl.class);
+    private SalTableService tableService;
+    private TableDataCommitHandler commitHandler;
+    private final IClusterContainerServices clusterContainerService = null;
+    private IContainer container;
+    private static final String NAMEREGEX = "^[a-zA-Z0-9]+$";
+    private boolean inContainerMode; // being used by global instance only
+
+    public TableFeaturesConsumerImpl() {
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder(Tables.class).child(Table.class)
+                .toInstance();
+        tableService = FRMConsumerImpl.getProviderSession().getRpcService(SalTableService.class);
+
+        if (null == tableService) {
+            logger.error("Consumer SAL Service is down or NULL. FRM may not function as intended");
+            System.out.println("Consumer SAL Service is down or NULL.");
+            return;
+        }
+
+        System.out.println("-------------------------------------------------------------------");
+        commitHandler = new TableDataCommitHandler();
+        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
+        container = (IContainer) ServiceHelper.getGlobalInstance(IContainer.class, this);
+    }
+
+    /**
+     * Updates TableFeatures to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private void updateTableFeatures(InstanceIdentifier<?> path, TableFeatures dataObject) {
+
+        UpdateTableInputBuilder input = new UpdateTableInputBuilder();
+        UpdatedTableBuilder updatedtablebuilder = new UpdatedTableBuilder();
+        updatedtablebuilder.fieldsFrom(dataObject);
+        List<TableFeatures> features = updatedtablebuilder.build().getTableFeatures();
+        for (TableFeatures feature : features) {
+            if (feature != null && feature.getMaxEntries() != null) {
+                logger.error("Max Entries field is read-only, cannot be changed");
+                return;
+            }
+        }
+        input.setUpdatedTable(updatedtablebuilder.build());
+
+        // We send table feature update request to the sounthbound plugin
+        tableService.updateTable(input.build());
+    }
+
+    @SuppressWarnings("unchecked")
+    private void commitToPlugin(internalTransaction transaction) {
+
+        for (@SuppressWarnings("unused")
+        Entry<InstanceIdentifier<?>, TableFeatures> entry : transaction.updates.entrySet()) {
+            System.out.println("Coming update cc in TableDatacommitHandler");
+            updateTableFeatures(entry.getKey(), entry.getValue());
+        }
+
+    }
+
+    private final class TableDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+            // We should verify transaction
+            System.out.println("Coming in TableFeaturesDatacommitHandler");
+            internalTransaction transaction = new internalTransaction(modification);
+            transaction.prepareUpdate();
+            return transaction;
+        }
+    }
+
+    private final class internalTransaction implements DataCommitTransaction<InstanceIdentifier<?>, DataObject> {
+
+        private final DataModification<InstanceIdentifier<?>, DataObject> modification;
+
+        @Override
+        public DataModification<InstanceIdentifier<?>, DataObject> getModification() {
+            return modification;
+        }
+
+        public internalTransaction(DataModification<InstanceIdentifier<?>, DataObject> modification) {
+            this.modification = modification;
+        }
+
+        Map<InstanceIdentifier<?>, TableFeatures> updates = new HashMap<>();
+
+        /**
+         * We create a plan which table features will be updated.
+         *
+         */
+        void prepareUpdate() {
+
+            Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
+            for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
+
+                // validating the DataObject
+
+                Status status = validate(container, (TableFeatures) entry);
+                if (!status.isSuccess()) {
+                    logger.warn("Invalid Configuration for table features The failure is {}", entry,
+                            status.getDescription());
+                    String error = "Invalid Configuration (" + status.getDescription() + ")";
+                    logger.error(error);
+                    return;
+                }
+                if (entry.getValue() instanceof TableFeatures) {
+                    TableFeatures tablefeatures = (TableFeatures) entry.getValue();
+                    preparePutEntry(entry.getKey(), tablefeatures);
+                }
+
+            }
+        }
+
+        private void preparePutEntry(InstanceIdentifier<?> key, TableFeatures tablefeatures) {
+            if (tablefeatures != null) {
+                // Updating the Map
+                System.out.println("Coming update  in TableFeaturesDatacommitHandler");
+                updates.put(key, tablefeatures);
+            }
+        }
+
+        /**
+         * We are OK to go with execution of plan
+         *
+         */
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+
+            commitToPlugin(this);
+            // We return true if internal transaction is successful.
+            // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+            return Rpcs.getRpcResult(true, null, null);
+        }
+
+        /**
+         *
+         * We should rollback our preparation
+         *
+         */
+        @Override
+        public RpcResult<Void> rollback() throws IllegalStateException {
+            // NOOP - we did not modified any internal state during
+            // requestCommit phase
+            // return Rpcs.getRpcResult(true, null, Collections.emptySet());
+            return Rpcs.getRpcResult(true, null, null);
+
+        }
+
+        public Status validate(IContainer container, TableFeatures dataObject) {
+
+            String tablename = dataObject.getName();
+            if (tablename == null || tablename.trim().isEmpty() || !tablename.matches(NAMEREGEX)
+                    || tablename.length() != 32) {
+                return new Status(StatusCode.BADREQUEST, "Invalid table name");
+            }
+
+            return new Status(StatusCode.SUCCESS);
+        }
+    }
+}