Merge "MD-SAL Statistics Provider"
authorEd Warnicke <eaw@cisco.com>
Thu, 14 Nov 2013 15:03:03 +0000 (15:03 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 14 Nov 2013 15:03:03 +0000 (15:03 +0000)
34 files changed:
opendaylight/forwardingrulesmanager/implementation/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManager.java
opendaylight/forwardingrulesmanager_mdsal/openflow/pom.xml
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/GroupConsumerImpl.java
opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/MeterConsumerImpl.java [new file with mode: 0644]
opendaylight/md-sal/compatibility/pom.xml
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FlowProgrammerAdapter.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/FromSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/MDFlowMapping.xtend
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/ToSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/main/java/org/opendaylight/controller/sal/compatibility/adsal/FlowServiceAdapter.java
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestFromSalConversionsUtils.java
opendaylight/md-sal/compatibility/sal-compatibility/src/test/java/org/opendaylight/controller/sal/compatibility/test/TestToSalConversionsUtils.java
opendaylight/md-sal/model/model-flow-base/src/main/yang/action-types.yang [new file with mode: 0644]
opendaylight/md-sal/model/model-flow-base/src/main/yang/flow-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/group-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/match-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/meter-types.yang
opendaylight/md-sal/model/model-flow-base/src/main/yang/table-types.yang
opendaylight/md-sal/model/model-flow-service/src/main/yang/flow-service.yang
opendaylight/md-sal/sal-binding-broker/pom.xml
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/RuntimeCodeGenerator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/JavassistUtils.java [deleted file]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/RuntimeCodeGenerator.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/ClassGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/FieldGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/JavassistUtils.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/MethodGenerator.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/BindingMapping.xtend
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CompositeNodeUtils.java [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/ConnectorActivator.java
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RuntimeGeneratedMappingServiceImpl.xtend [new file with mode: 0644]
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/util/ClassLoaderUtils.java
opendaylight/md-sal/sal-binding-broker/src/test/java/org/opendaylight/controller/sal/binding/test/connect/dom/BrokerIntegrationTest.java

index 34088607b11e1cf4fae079a240568319998c42f6..e639d41e8e1ea819fa4c56fb4fbbfbc3c481af28 100644 (file)
@@ -2608,6 +2608,12 @@ public class ForwardingRulesManager implements
         // Start event handler thread
         frmEventHandler.start();
 
+        // replay the installedSwView data structure to populate
+        // node flows and group flows
+        for (FlowEntryInstall fei : installedSwView.keySet()) {
+            pendingEvents.offer(new UpdateIndexDBs(fei, true));
+        }
+
         /*
          * Read startup and build database if we have not already gotten the
          * configurations synced from another node
index 29de77270bb6d63c5f791f0ad70cce2eda6d9250..dcf119930b782af8eb4004f162410932acc897c5 100644 (file)
          <groupId>org.opendaylight.controller</groupId>
                <artifactId>sal-binding-api</artifactId>
                <version>1.0-SNAPSHOT</version>
-       </dependency>   
-       <dependency>
-      <groupId>org.opendaylight.controller</groupId>
-      <artifactId>flow-management-compatibility</artifactId>
-      <version>1.0-SNAPSHOT</version>
-    </dependency>    
+       </dependency>           
        <dependency>
       <groupId>org.opendaylight.controller.model</groupId>
       <artifactId>model-flow-service</artifactId>
       <version>1.0-SNAPSHOT</version>
       <scope>provided</scope>
     </dependency>
+     <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>clustering.services</artifactId>
+      <version>0.4.1-SNAPSHOT</version>
+    </dependency>    
+     <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>sal</artifactId>
+      <version>0.5.1-SNAPSHOT</version>
+    </dependency>
   </dependencies>
 </project>
index acc0dc69cd4d059b074fc7691bc1b73d75130170..73295cc1e79a204575f6ffd72e00c2c7edf018a9 100644 (file)
@@ -62,16 +62,14 @@ public class GroupConsumerImpl {
     private ConcurrentMap<Node, List<Group>> nodeGroups;
     private ConcurrentMap<GroupKey, Group> inactiveGroups;
     
-    private IClusterContainerServices clusterGroupContainerService = null;
-    private ISwitchManager switchGroupManager;
+    private IClusterContainerServices clusterGroupContainerService = null;   
     private IContainer container;
     
     public GroupConsumerImpl() {
-           InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).toInstance();
+           InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Groups.class).node(Group.class).toInstance();
         groupService = FRMConsumerImpl.getProviderSession().getRpcService(SalGroupService.class);
         
-        clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();
-        switchGroupManager = FRMConsumerImpl.getSwitchManager();
+        clusterGroupContainerService = FRMConsumerImpl.getClusterContainerService();        
         container = FRMConsumerImpl.getContainer();
         
         if (!(cacheStartup())) {
@@ -279,7 +277,7 @@ public class GroupConsumerImpl {
      * @param dataObject
      */
     private Status updateGroup(InstanceIdentifier<?> path, Group groupUpdateDataObject) {
-        GroupKey groupKey = groupUpdateDataObject.getKey();
+        GroupKey groupKey = groupUpdateDataObject.getKey();        
         Status groupOperationStatus = validateGroup(groupUpdateDataObject, FRMUtil.operation.UPDATE);
         
         if (!groupOperationStatus.isSuccess()) {
@@ -319,7 +317,7 @@ public class GroupConsumerImpl {
             logger.error("Group data object validation failed %s" + groupAddDataObject.getGroupName());
             return groupOperationStatus;
         }
-        validateGroup(groupAddDataObject, FRMUtil.operation.ADD);
+        
         originalSwGroupView.put(groupKey, groupAddDataObject);
         
         if (groupAddDataObject.isInstall()) {
@@ -363,7 +361,7 @@ public class GroupConsumerImpl {
         @Override
          public DataCommitTransaction requestCommit(DataModification<InstanceIdentifier<?>, DataObject> modification) {
              // We should verify transaction
-             System.out.println("Coming in FlowDatacommitHandler");
+             System.out.println("Coming in GroupDatacommitHandler");
              internalTransaction transaction = new internalTransaction(modification);
              transaction.prepareUpdate();
              return transaction;
diff --git a/opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/MeterConsumerImpl.java b/opendaylight/forwardingrulesmanager_mdsal/openflow/src/main/java/org/opendaylight/controller/forwardingrulesmanager_mdsal/consumer/impl/MeterConsumerImpl.java
new file mode 100644 (file)
index 0000000..5eb971e
--- /dev/null
@@ -0,0 +1,514 @@
+package org.opendaylight.controller.forwardingrulesmanager_mdsal.consumer.impl;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.opendaylight.controller.clustering.services.CacheConfigException;
+import org.opendaylight.controller.clustering.services.CacheExistException;
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;
+import org.opendaylight.controller.clustering.services.IClusterServices;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler;
+import org.opendaylight.controller.md.sal.common.api.data.DataModification;
+import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction;
+import org.opendaylight.controller.sal.common.util.Rpcs;
+import org.opendaylight.controller.sal.core.IContainer;
+import org.opendaylight.controller.sal.core.Node;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.Meters;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.MeterKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.AddMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterAdded;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterRemoved;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.MeterUpdated;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterListener;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.SalMeterService;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.service.rev130918.UpdateMeterInputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.BandType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Drop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.DscpRemark;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.types.rev130918.band.type.band.type.Experimenter;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.meter.config.rev131024.meters.Meter;
+import org.opendaylight.yangtools.concepts.Registration;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.binding.NotificationListener;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MeterConsumerImpl {
+    protected static final Logger logger = LoggerFactory.getLogger(MeterConsumerImpl.class);
+    private MeterEventListener meterEventListener = new MeterEventListener();
+    private Registration<NotificationListener> meterListener;
+    private SalMeterService meterService;    
+    private MeterDataCommitHandler commitHandler;
+    
+    private ConcurrentMap<MeterKey, Meter> originalSwMeterView;
+    private ConcurrentMap<MeterKey, Meter> installedSwMeterView;
+    
+    private ConcurrentMap<Node, List<Meter>> nodeMeters;
+    private ConcurrentMap<MeterKey, Meter> inactiveMeters;
+    
+    private IClusterContainerServices clusterMeterContainerService = null; 
+    private IContainer container;
+    
+    public MeterConsumerImpl() {
+        InstanceIdentifier<? extends DataObject> path = InstanceIdentifier.builder().node(Meters.class).node(Meter.class).toInstance();
+        meterService = FRMConsumerImpl.getProviderSession().getRpcService(SalMeterService.class);        
+        clusterMeterContainerService = FRMConsumerImpl.getClusterContainerService();
+        
+        container = FRMConsumerImpl.getContainer();
+        
+        if (!(cacheStartup())) {
+            logger.error("Unable to allocate/retrieve meter cache");
+            System.out.println("Unable to allocate/retrieve meter cache");
+        }
+        
+        if (null == meterService) {
+            logger.error("Consumer SAL Meter Service is down or NULL. FRM may not function as intended");
+            System.out.println("Consumer SAL Meter Service is down or NULL.");
+            return;
+        } 
+        
+        // For switch/plugin events
+        meterListener = FRMConsumerImpl.getNotificationService().registerNotificationListener(meterEventListener);
+        
+        if (null == meterListener) {
+            logger.error("Listener to listen on meter data modifcation events");
+            System.out.println("Listener to listen on meter data modifcation events.");
+            return;
+        }       
+        
+        commitHandler = new MeterDataCommitHandler();
+        FRMConsumerImpl.getDataProviderService().registerCommitHandler(path, commitHandler);
+    }
+    
+    
+    
+    private boolean allocateMeterCaches() {
+        if (this.clusterMeterContainerService == null) {
+            logger.warn("Meter: Un-initialized clusterMeterContainerService, can't create cache");
+            return false;
+        }       
+
+        try {
+            clusterMeterContainerService.createCache("frm.originalSwMeterView",
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+            clusterMeterContainerService.createCache("frm.installedSwMeterView",
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+            clusterMeterContainerService.createCache("frm.inactiveMeters",
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+
+            clusterMeterContainerService.createCache("frm.nodeMeters",
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+            
+//TODO for cluster mode
+           /* clusterMeterContainerService.createCache(WORK_STATUS_CACHE,
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));
+
+            clusterMeterContainerService.createCache(WORK_ORDER_CACHE,
+                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL, IClusterServices.cacheMode.ASYNC));*/
+            
+        } catch (CacheConfigException cce) {            
+            logger.error("Meter CacheConfigException");
+            return false;
+            
+        } catch (CacheExistException cce) {
+            logger.error(" Meter CacheExistException");           
+        }
+        
+        return true;
+    }
+    
+    private void nonClusterMeterObjectCreate() {
+        originalSwMeterView = new ConcurrentHashMap<MeterKey, Meter>();
+        installedSwMeterView = new ConcurrentHashMap<MeterKey, Meter>();
+        nodeMeters = new ConcurrentHashMap<Node, List<Meter>>();        
+        inactiveMeters = new ConcurrentHashMap<MeterKey, Meter>();
+    }
+    
+    @SuppressWarnings({ "unchecked" })
+    private boolean retrieveMeterCaches() {
+        ConcurrentMap<?, ?> map;
+
+        if (this.clusterMeterContainerService == null) {
+            logger.warn("Meter: un-initialized clusterMeterContainerService, can't retrieve cache");
+            nonClusterMeterObjectCreate();
+            return false;
+        }       
+
+        map = clusterMeterContainerService.getCache("frm.originalSwMeterView");
+        if (map != null) {
+            originalSwMeterView = (ConcurrentMap<MeterKey, Meter>) map;
+        } else {
+            logger.error("Retrieval of cache(originalSwMeterView) failed");
+            return false;
+        }
+
+        map = clusterMeterContainerService.getCache("frm.installedSwMeterView");
+        if (map != null) {
+            installedSwMeterView = (ConcurrentMap<MeterKey, Meter>) map;
+        } else {
+            logger.error("Retrieval of cache(installedSwMeterView) failed");
+            return false;
+        }
+
+        map = clusterMeterContainerService.getCache("frm.inactiveMeters");
+        if (map != null) {
+            inactiveMeters = (ConcurrentMap<MeterKey, Meter>) map;
+        } else {
+            logger.error("Retrieval of cache(inactiveMeters) failed");
+            return false;
+        }
+
+        map = clusterMeterContainerService.getCache("frm.nodeMeters");
+        if (map != null) {
+            nodeMeters = (ConcurrentMap<Node, List<Meter>>) map;
+        } else {
+            logger.error("Retrieval of cache(nodeMeter) failed");
+            return false;
+        }
+        
+        return true;
+    }
+    
+    private boolean cacheStartup() {
+        if (allocateMeterCaches()) {
+            if (retrieveMeterCaches()) {
+                return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    /**
+     * Adds Meter to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private Status addMeter(InstanceIdentifier<?> path, Meter meterAddDataObject) {        
+        MeterKey meterKey = meterAddDataObject.getKey();
+        
+        if (null != meterKey && 
+                validateMeter(meterAddDataObject, FRMUtil.operation.ADD).isSuccess()) {
+            if (meterAddDataObject.isInstall()) {
+                AddMeterInputBuilder meterBuilder = new AddMeterInputBuilder();
+                
+                meterBuilder.setContainerName(meterAddDataObject.getContainerName());
+                meterBuilder.setFlags(meterAddDataObject.getFlags());
+                meterBuilder.setMeterBandHeaders(meterAddDataObject.getMeterBandHeaders());
+                meterBuilder.setMeterId(meterAddDataObject.getMeterId());
+                meterBuilder.setNode(meterAddDataObject.getNode());
+                originalSwMeterView.put(meterKey, meterAddDataObject);
+                meterService.addMeter(meterBuilder.build());
+            }
+            
+            originalSwMeterView.put(meterKey, meterAddDataObject);            
+        }
+        else {
+            return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
+        }
+      
+        return new Status(StatusCode.SUCCESS);
+    }
+    
+    /*
+     * Update Meter to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private Status updateMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
+        MeterKey meterKey = meterUpdateDataObject.getKey();
+        
+        if (null != meterKey && 
+                validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
+            if (meterUpdateDataObject.isInstall()) {
+                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();  
+                
+                originalSwMeterView.put(meterKey, meterUpdateDataObject);
+                meterService.updateMeter(updateMeterBuilder.build());
+            }
+            
+            originalSwMeterView.put(meterKey, meterUpdateDataObject);            
+        }
+        else {
+            return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
+        }
+      
+        return new Status(StatusCode.SUCCESS);
+    }
+    
+    /*
+     * Remove Meter to the southbound plugin and our internal database
+     *
+     * @param path
+     * @param dataObject
+     */
+    private Status RemoveMeter(InstanceIdentifier<?> path, Meter meterUpdateDataObject) {        
+        MeterKey meterKey = meterUpdateDataObject.getKey();
+        
+        if (null != meterKey && 
+                validateMeter(meterUpdateDataObject, FRMUtil.operation.ADD).isSuccess()) {
+            if (meterUpdateDataObject.isInstall()) {
+                UpdateMeterInputBuilder updateMeterBuilder = new UpdateMeterInputBuilder();                
+                
+                originalSwMeterView.put(meterKey, meterUpdateDataObject);
+                meterService.updateMeter(updateMeterBuilder.build());
+            }
+            
+            originalSwMeterView.put(meterKey, meterUpdateDataObject);            
+        }
+        else {
+            return new Status(StatusCode.BADREQUEST, "Meter Key or attribute validation failed");
+        }
+      
+        return new Status(StatusCode.SUCCESS);
+    }
+    
+    public Status validateMeter(Meter meter, FRMUtil.operation operation) {
+        String containerName;
+        String meterName;
+        Status returnStatus = null;
+        boolean returnResult;
+        
+        if (null != meter) {
+            containerName = meter.getContainerName();
+            
+            if (null == containerName) {
+                containerName = GlobalConstants.DEFAULT.toString();
+            }
+            else if (!FRMUtil.isNameValid(containerName)) {
+                logger.error("Container Name is invalid %s" + containerName);
+                returnStatus = new Status(StatusCode.BADREQUEST, "Container Name is invalid");
+                return returnStatus;
+            }
+            
+            meterName = meter.getMeterName();
+            if (!FRMUtil.isNameValid(meterName)) {
+                logger.error("Meter Name is invalid %s" + meterName);
+                returnStatus = new Status(StatusCode.BADREQUEST, "Meter Name is invalid");
+                return returnStatus;
+            }
+            
+            returnResult = doesMeterEntryExists(meter.getKey(), meterName, containerName);
+            
+            if (FRMUtil.operation.ADD == operation && returnResult) {
+                logger.error("Record with same Meter Name exists");
+                returnStatus = new Status(StatusCode.BADREQUEST, "Meter record exists");
+                return returnStatus;
+            }
+            else if (!returnResult) {
+                logger.error("Group record does not exist");
+                returnStatus = new Status(StatusCode.BADREQUEST, "Meter record does not exist");
+                return returnStatus;
+            }
+          
+            for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
+                if (!meter.getFlags().isMeterBurst()) {
+                    if (0 < meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBurstSize()) {
+                        logger.error("Burst size should only be associated when Burst FLAG is set");
+                        returnStatus = new Status(StatusCode.BADREQUEST, "Burst size should only be associated when Burst FLAG is set");
+                        break;
+                    }
+                }
+            }
+            
+            if (null != returnStatus && !returnStatus.isSuccess()) {
+                return returnStatus;
+            }
+            else {
+                BandType setBandType = null;
+                DscpRemark dscpRemark = null;
+                for (int i = 0; i < meter.getMeterBandHeaders().getMeterBandHeader().size(); i++) {
+                    setBandType = meter.getMeterBandHeaders().getMeterBandHeader().get(i).getBandType();
+                    if ( setBandType instanceof DscpRemark) {   
+                        dscpRemark = (DscpRemark)setBandType;
+                        if (0 > dscpRemark.getRate()) {
+                           
+                        }
+                    }
+                    else if (setBandType instanceof Drop) {
+                        if (0 < dscpRemark.getPercLevel()) {
+                            logger.error("Number of drop Precedence level");
+                        }                        
+                    }
+                    else if (setBandType instanceof Experimenter) {
+                        
+                    }
+                }                
+            }
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+    
+    private boolean doesMeterEntryExists(MeterKey key, String meterName, String containerName) {
+        if (! originalSwMeterView.containsKey(key)) {
+            return false;
+        }
+        
+        for (Entry<MeterKey, Meter> entry : originalSwMeterView.entrySet()) {
+            if (entry.getValue().getMeterName().equals(meterName)) {
+                if (entry.getValue().getContainerName().equals(containerName)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    
+    private RpcResult<Void> commitToPlugin(internalTransaction transaction) {
+        for(Entry<InstanceIdentifier<?>, Meter> entry :transaction.additions.entrySet()) {
+            
+            if (!addMeter(entry.getKey(),entry.getValue()).isSuccess()) {
+                return Rpcs.getRpcResult(false, null, null);
+            }
+        }
+        for(@SuppressWarnings("unused") Entry<InstanceIdentifier<?>, Meter> entry :transaction.updates.entrySet()) {
+           
+            if (!updateMeter(entry.getKey(),entry.getValue()).isSuccess()) {
+                return Rpcs.getRpcResult(false, null, null);
+            }
+        }
+        
+        for(InstanceIdentifier<?> removal : transaction.removals) {
+           /* if (!removeMeter(entry.getKey(),entry.getValue()).isSuccess()) {
+                return Rpcs.getRpcResult(false, null, null);
+            }*/
+        }
+        
+        return Rpcs.getRpcResult(true, null, null);
+    }
+    
+    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<?>, Meter> additions = new HashMap<>();
+        Map<InstanceIdentifier<?>, Meter> updates = new HashMap<>();
+        Set<InstanceIdentifier<?>> removals = new HashSet<>();
+
+        /**
+         * We create a plan which flows will be added, which will be updated and
+         * which will be removed based on our internal state.
+         * 
+         */
+        void prepareUpdate() {
+
+            Set<Entry<InstanceIdentifier<?>, DataObject>> puts = modification.getUpdatedConfigurationData().entrySet();
+            for (Entry<InstanceIdentifier<?>, DataObject> entry : puts) {
+                if (entry.getValue() instanceof Meter) {                    
+                    Meter Meter = (Meter) entry.getValue();                    
+                    preparePutEntry(entry.getKey(), Meter);
+                }
+
+            }
+
+            removals = modification.getRemovedConfigurationData();
+        }
+
+        private void preparePutEntry(InstanceIdentifier<?> key, Meter meter) {
+            
+            Meter original = originalSwMeterView.get(key);
+            if (original != null) {
+                // It is update for us
+                
+                updates.put(key, meter);               
+            } else {
+                // It is addition for us
+                
+                additions.put(key, meter);
+            }
+        }
+
+        /**
+         * We are OK to go with execution of plan
+         * 
+         */
+        @Override
+        public RpcResult<Void> finish() throws IllegalStateException {
+            
+            RpcResult<Void> rpcStatus = commitToPlugin(this);
+            // We return true if internal transaction is successful.
+          //  return Rpcs.getRpcResult(true, null, Collections.emptySet());
+            return rpcStatus;
+        }
+
+        /**
+         * 
+         * 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);
+            
+        }
+        
+    }
+
+    private final class MeterDataCommitHandler implements DataCommitHandler<InstanceIdentifier<?>, DataObject> {
+        @Override
+        public org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler.DataCommitTransaction<InstanceIdentifier<?>, DataObject> requestCommit(
+                DataModification<InstanceIdentifier<?>, DataObject> modification) {
+            // We should verify transaction
+            System.out.println("Coming in MeterDataCommitHandler");
+            internalTransaction transaction = new internalTransaction(modification);
+            transaction.prepareUpdate();
+            return transaction;
+        }
+    }
+    
+    final class MeterEventListener implements SalMeterListener {
+        
+        List<MeterAdded> addedMeter = new ArrayList<>();
+        List<MeterRemoved> removeMeter = new ArrayList<>();
+        List<MeterUpdated> updatedMeter = new ArrayList<>();
+
+        @Override
+        public void onMeterAdded(MeterAdded notification) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        @Override
+        public void onMeterRemoved(MeterRemoved notification) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        @Override
+        public void onMeterUpdated(MeterUpdated notification) {
+            // TODO Auto-generated method stub
+            
+        }    
+    }
+}
index a829380e68426575ca70325f5de4b5466f1ba9f4..151fdbfaaa19ffcc229338080aa65768e59d3235 100644 (file)
@@ -8,7 +8,7 @@
     </parent>
     <artifactId>compatibility-parent</artifactId>
     <packaging>pom</packaging>
-    <name>MD-SAL to AD-SAL Adaptation</name>
+    <name>MD-SAL to AD-SAL Adaptation Parent</name>
     <scm>
         <connection>scm:git:ssh://git.opendaylight.org:29418/controller.git</connection>
         <developerConnection>scm:git:ssh://git.opendaylight.org:29418/controller.git</developerConnection>
index da652e65a7a28bf3e51bc637519c2dc8d94f0a73..7d9c93908ec8484d502d6ab91d1bd26080c631cb 100644 (file)
@@ -98,7 +98,7 @@ class FlowProgrammerAdapter implements IPluginInFlowProgrammerService, SalFlowLi
         return null;
     }
 
-    public static def toStatus(RpcResult<Void> result) {
+    public static def toStatus(RpcResult<?> result) {
         if (result.isSuccessful()) {
             return new Status(StatusCode.SUCCESS);
         } else {
index a31d8e265d26557c76a583dbdd1d212c43614f71..cc86659657883ad48d01ef45609d076d6cf7e590 100644 (file)
@@ -4,13 +4,10 @@ import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
 import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
 import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
 
-import java.math.BigInteger;
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+
 
 import org.opendaylight.controller.sal.compatibility.MDFlowMapping;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -28,9 +25,9 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetNodeConnectorStatisticsInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorRef;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
index b43e8af6612c97d516373e49f5565ab51fc61b84..5dd149a99738f2b33fa9e9b024861ee56286835c 100644 (file)
@@ -41,34 +41,34 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInputBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInputBuilder
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.statistics.rev130819.GetFlowStatisticsInputBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.ControllerActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.DropActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAllActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.HwPathActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.LoopbackActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.OutputActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopVlanActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushVlanActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlDstActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlSrcActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlTypeActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNextHopActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwDstActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwSrcActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTosActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpDstActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpSrcActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanCfiActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanIdActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanPcpActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SwPathActionBuilder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.ActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathActionBuilder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp
index 5009e5dfb79f6418058db177f90078ac2db8fbff..96b69618b0db78031a3bf20e2796af99ea42bef2 100644 (file)
@@ -33,40 +33,40 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.ActionList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.ControllerAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.DropAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.FloodAllAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.HwPathAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.LoopbackAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.OutputAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopMplsAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PopVlanAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushMplsAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushPbbAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.PushVlanAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetDlTypeAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetMplsTtlAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNextHopAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTosAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetNwTtlAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetQueueAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpDstAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetTpSrcAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanCfiAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanIdAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SetVlanPcpAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.SwPathAction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.ActionList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.ControllerAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.DropAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.FloodAllAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.HwPathAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.LoopbackAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopMplsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushMplsAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushPbbAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlDstAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlSrcAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetDlTypeAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetMplsTtlAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNextHopAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwDstAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwSrcAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTosAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetNwTtlAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetQueueAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpDstAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetTpSrcAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanCfiAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanIdAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetVlanPcpAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SwPathAction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
@@ -159,7 +159,7 @@ public class ToSalConversionsUtils {
     public static List<org.opendaylight.controller.sal.action.Action> actionFrom(List<Action> actions) {
         List<org.opendaylight.controller.sal.action.Action> targetAction = new ArrayList<>();
         for (Action action : actions) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.Action sourceAction = action
+               org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action sourceAction = action
                     .getAction();
 
             if (sourceAction instanceof ControllerAction) {
index ae427455a415344b75d5db2c7d1e1e13049d37d1..fd03ea4ca5cc5ddf46df3d8fe5fa2f3c524ac4f1 100644 (file)
@@ -1,5 +1,6 @@
 package org.opendaylight.controller.sal.compatibility.adsal;
 
+import java.math.BigInteger;
 import java.util.concurrent.Future;
 
 import org.opendaylight.controller.sal.binding.api.NotificationProviderService;
@@ -14,10 +15,17 @@ import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerListener;
 import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.AddFlowOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowRemovedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.RemoveFlowOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.SalFlowService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowInput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutput;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.UpdateFlowOutputBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.transaction.rev131103.TransactionId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
@@ -46,39 +54,46 @@ public class FlowServiceAdapter implements SalFlowService, IFlowProgrammerListen
     }
 
     @Override
-    public Future<RpcResult<Void>> addFlow(AddFlowInput input) {
+    public Future<RpcResult<AddFlowOutput>> addFlow(AddFlowInput input) {
 
         Flow flow = ToSalConversionsUtils.toFlow(input);
         @SuppressWarnings("unchecked")
         org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
                 .getNode().getValue());
         Status status = delegate.addFlowAsync(node, flow);
-        Void rpcResultType = null;
+        AddFlowOutputBuilder builder = new AddFlowOutputBuilder();
+        builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
+        AddFlowOutput rpcResultType = builder.build();
         return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
     }
 
     @Override
-    public Future<RpcResult<Void>> removeFlow(RemoveFlowInput input) {
+    public Future<RpcResult<RemoveFlowOutput>> removeFlow(RemoveFlowInput input) {
 
         Flow flow = ToSalConversionsUtils.toFlow(input);
         @SuppressWarnings("unchecked")
         org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
                 .getNode().getValue());
         Status status = delegate.removeFlowAsync(node, flow);
-        Void rpcResultType = null;
+        RemoveFlowOutputBuilder builder = new RemoveFlowOutputBuilder();
+        builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
+        RemoveFlowOutput rpcResultType = builder.build();
         return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
 
     }
 
     @Override
-    public Future<RpcResult<Void>> updateFlow(UpdateFlowInput input) {
+    public Future<RpcResult<UpdateFlowOutput>> updateFlow(UpdateFlowInput input) {
         @SuppressWarnings("unchecked")
         org.opendaylight.controller.sal.core.Node node = InventoryMapping.toAdNode((InstanceIdentifier<Node>) input
                 .getNode().getValue());
         Flow originalFlow = ToSalConversionsUtils.toFlow(input.getOriginalFlow());
         Flow updatedFlow = ToSalConversionsUtils.toFlow(input.getUpdatedFlow());
         Status status = delegate.modifyFlowAsync(node, originalFlow, updatedFlow);
-        Void rpcResultType = null;
-        return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
+        UpdateFlowOutputBuilder builder = new UpdateFlowOutputBuilder();
+        builder.setTransactionId(new TransactionId(BigInteger.valueOf(status.getRequestId())));
+        UpdateFlowOutput rpcResultType = builder.build();
+        throw new UnsupportedOperationException("Need to translate AD-SAL status to MD-SAL UpdateFlowOuptut - eaw@cisco.com");
+        // return Futures.immediateFuture(Rpcs.getRpcResult(status.isSuccess(), rpcResultType, null));
     }
 }
index c37cce0837a00e6214ac8230d913bcb335781754..96b8cafdf8ca3ed512c1ab65fedf0e4d3919ba3d 100644 (file)
@@ -26,9 +26,9 @@ import org.opendaylight.controller.sal.flowprogrammer.Flow;
 import org.opendaylight.controller.sal.match.Match;
 import org.opendaylight.controller.sal.match.MatchType;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;
@@ -185,7 +185,7 @@ public class TestFromSalConversionsUtils {
     }
 
     private void checkOdActions(
-            List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action> actions) {
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions) {
         checkOdAction(actions, FloodAction.class, false);
         checkOdAction(actions, FloodAllAction.class, false);
         checkOdAction(actions, HwPathAction.class, false);
@@ -208,11 +208,11 @@ public class TestFromSalConversionsUtils {
     }
 
     private void checkOdAction(
-            List<org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action> actions, Class<?> cl,
+            List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions, Class<?> cl,
             boolean b) {
         int numOfFoundActions = 0;
-        for (org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action action : actions) {
-            org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.Action innerAction = action
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action action : actions) {
+               org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action innerAction = action
                     .getAction();
             if (cl.isInstance(innerAction)) {
                 numOfFoundActions++;
index e251dd02a0baf299e596cc9334459cd2342d70ac..e2ae7246063678bca99a9fe9fdce2186323942d1 100644 (file)
@@ -27,13 +27,13 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.NodeFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.VlanCfi;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.action.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv4Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.address.address.Ipv6Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.VlanCfi;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.*;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
diff --git a/opendaylight/md-sal/model/model-flow-base/src/main/yang/action-types.yang b/opendaylight/md-sal/model/model-flow-base/src/main/yang/action-types.yang
new file mode 100644 (file)
index 0000000..3bf7db6
--- /dev/null
@@ -0,0 +1,229 @@
+module opendaylight-action-types {
+    namespace "urn:opendaylight:action:types";
+    prefix action;
+
+    import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
+    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
+    import opendaylight-l2-types {prefix l2t; revision-date "2013-08-27";}
+    
+    revision "2013-11-12" {
+        description "Initial revision of action service";
+    }
+    
+    typedef vlan-cfi {
+        type int32;    
+    }
+
+    grouping address {
+        choice address {
+            case ipv4 {
+                leaf ipv4-address {
+                    type inet:ipv4-prefix;
+                }
+            }
+            case ipv6 {
+                leaf ipv6-address {
+                    type inet:ipv6-prefix;
+                }
+            }
+        }
+    }  
+    
+    grouping action-list {
+        list action {
+            key "order";
+            leaf order {
+                type int32;
+            }
+            uses action;
+        }
+    }
+    
+    grouping action {
+        choice action {
+            case output-action {
+                leaf-list output-node-connector {
+                    type inet:uri;
+                }
+                
+                leaf max-length {
+                    type uint16 {
+                        range "0..65294";
+                    }
+                }                
+            }
+
+            case controller-action {
+                leaf max-length {
+                    type uint16 {
+                        range "0..65294";
+                    }
+                }
+            }
+
+            case set-queue-action {
+                leaf queue {
+                    type string; 
+                }
+            }
+
+            case pop-mpls-action {
+                leaf ethernet-type {
+                    type uint16; // TODO: define ethertype type
+                }
+            }
+
+            case set-mpls-ttl-action {
+                leaf mpls-ttl {
+                    type uint8;
+                }
+            }
+
+            case set-nw-ttl-action {
+                leaf nw-ttl {
+                    type uint8;
+                }
+            }
+
+            case push-pbb-action {
+                leaf ethernet-type {
+                    type uint16; // TODO: define ethertype type
+                }
+            }
+
+            case pop-pbb-action {
+                
+            }
+            
+            case push-mpls-action {
+                leaf ethernet-type {
+                    type uint16; // TODO: define ethertype type
+                }
+            }
+            
+            case dec-mpls-ttl {
+            }
+            
+            case dec-nw-ttl {
+            }
+            
+            case drop-action {
+            }
+            
+            case flood-action {
+            }
+            
+            case flood-all-action {
+            }
+            
+            case hw-path-action {
+            }
+            
+            case loopback-action {
+            }
+            
+            case pop-vlan-action {
+            }
+            
+            case push-vlan-action {
+                leaf ethernet-type {
+                    type uint16; // TODO: define ethertype type
+                }
+                leaf tag {               // TPID - 16 bits
+                    type int32;
+                } 
+                leaf pcp {               // PCP - 3 bits
+                    type int32;
+                }
+                leaf cfi {               // CFI - 1 bit (drop eligible)
+                    type vlan-cfi;
+                }
+                leaf vlan-id {           // VID - 12 bits
+                    type l2t:vlan-id;
+                }
+//                leaf tci {               //TCI = [PCP + CFI + VID]
+//                }
+//                leaf header {            //header = [TPID + TCI] 
+//                }
+            }
+            
+            case copy-ttl-out {
+            }
+            
+            case copy-ttl-in {
+            }
+            
+            case set-dl-dst-action {
+                leaf address {
+                    type yang:mac-address;
+                }
+            }
+            
+            case set-dl-src-action {
+                leaf address {
+                    type yang:mac-address;
+                }
+            }
+            case group-action {
+                leaf group {
+                    type string;
+                }
+            }
+            
+            case set-dl-type-action {
+                leaf dl-type {
+                    type l2t:ether-type;
+                }
+            }
+            
+            case set-next-hop-action {
+                uses address;
+            }
+            
+            case set-nw-dst-action {
+                uses address;            
+            }
+            
+            case set-nw-src-action{
+                uses address;            
+            }
+            
+            case set-nw-tos-action {
+                leaf tos {
+                    type int32;
+                }
+            }
+            
+            case set-tp-dst-action {
+                leaf port {
+                    type inet:port-number;
+                }                
+            }
+            case set-tp-src-action {
+                leaf port {
+                    type inet:port-number;
+                }                
+            }
+            case set-vlan-cfi-action {
+                leaf vlan-cfi {
+                    type vlan-cfi;
+                }
+            }
+            
+            case set-vlan-id-action {
+                leaf vlan-id {
+                    type l2t:vlan-id;
+                } 
+            }
+            
+            case set-vlan-pcp-action {
+                leaf vlan-pcp {
+                    type l2t:vlan-pcp;
+                }            
+            }
+            
+            case sw-path-action {            
+            }  
+        }
+    }
+}
\ No newline at end of file
index 8e8c82293505795d7a53e5ada9275320a05ad617..4145977f635c2cb59b2d9564712d087aad6a378b 100644 (file)
@@ -3,54 +3,22 @@ module opendaylight-flow-types {
     prefix flow;
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
-    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
-    import opendaylight-l2-types {prefix l2t; revision-date "2013-08-27";}
+    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}    
     import opendaylight-match-types {prefix match; revision-date 2013-10-26";}
-    
+    import opendaylight-action-types {prefix action;}
 
     revision "2013-10-26" {
         description "Initial revision of flow service";
     }
     
-    
-    typedef vlan-cfi {
-           type int32;    
-    }
-    
-    
-    grouping action-list {
-        list action {
+    grouping instruction-list {
+        list instruction {
             key "order";
             leaf order {
                 type int32;
             }
-            uses action;
-        }
-    }
-    
-    grouping address {
-        choice address {
-            case ipv4 {
-                leaf ipv4-address {
-                    type inet:ipv4-prefix;
-                }
-            }
-            case ipv6 {
-                leaf ipv6-address {
-                    type inet:ipv6-prefix;
-                }
-            }
+            uses instruction;
         }
-    }    
-
-    grouping instruction-list {
-            list instruction {
-                key "order";
-                leaf order {
-                    type int32;
-                }
-                uses instruction;
-            }
     }
 
     grouping instruction {
@@ -72,15 +40,15 @@ module opendaylight-flow-types {
             }
             
             case write-actions {
-                uses action-list;
+                uses action:action-list;
             }
             
             case apply-actions {
-                uses action-list;
+                uses action:action-list;
             }
             
             case clear-actions {
-                uses action-list;
+                uses action:action-list;
             }
             
             case meter {
@@ -91,197 +59,13 @@ module opendaylight-flow-types {
         }
     }
     
-    grouping action {
-        choice action {
-            case output-action {
-                leaf-list output-node-connector {
-                    type inet:uri;
-                }
-                
-                leaf max-length {
-                    type uint16 {
-                        range "0..65294";
-                    }
-                }                
-            }
-
-            case controller-action {
-                leaf max-length {
-                    type uint16 {
-                        range "0..65294";
-                    }
-                }
-            }
-
-            case set-queue-action {
-                leaf queue {
-                    type string; 
-                }
-            }
-
-            case pop-mpls-action {
-                leaf ethernet-type {
-                    type uint16; // TODO: define ethertype type
-                }
-            }
-
-            case set-mpls-ttl-action {
-                leaf mpls-ttl {
-                    type uint8;
-                }
-            }
-
-            case set-nw-ttl-action {
-                leaf nw-ttl {
-                    type uint8;
-                }
-            }
-
-            case push-pbb-action {
-                leaf ethernet-type {
-                    type uint16; // TODO: define ethertype type
-                }
-            }
-
-            case pop-pbb-action {
-                
-            }
-            
-            case push-mpls-action {
-                leaf ethernet-type {
-                    type uint16; // TODO: define ethertype type
-                }
-            }
-            
-            case dec-mpls-ttl {
-            }
-            
-            case dec-nw-ttl {
-            }
-            
-            case drop-action {
-            }
-            
-            case flood-action {
-            }
-            
-            case flood-all-action {
-            }
-            
-            case hw-path-action {
-            }
-            
-            case loopback-action {
-            }
-            
-            case pop-vlan-action {
-            }
-            
-            case push-vlan-action {
-                leaf tag {               // TPID - 16 bits
-                    type int32;
-                } 
-                leaf pcp {               // PCP - 3 bits
-                    type int32;
-                }
-                leaf cfi {               // CFI - 1 bit (drop eligible)
-                    type vlan-cfi;
-                }
-                leaf vlan-id {           // VID - 12 bits
-                    type l2t:vlan-id;
-                }
-//                leaf tci {               //TCI = [PCP + CFI + VID]
-//                }
-//                leaf header {            //header = [TPID + TCI] 
-//                }
-            }
-            
-            case copy-ttl-out {
-            }
-            
-            case copy-ttl-in {
-            }
-            
-            case set-dl-dst-action {
-                leaf address {
-                    type yang:mac-address;
-                }
-            }
-            
-            case set-dl-src-action {
-                leaf address {
-                    type yang:mac-address;
-                }
-            }
-            case group-action {
-                leaf group {
-                    type string;
-                }
-            }
-            
-            case set-dl-type-action {
-                leaf dl-type {
-                    type l2t:ether-type;
-                }
-            }
-            
-            case set-next-hop-action {
-                uses address;
-            }
-            
-            case set-nw-dst-action {
-                uses address;            
-            }
-            
-            case set-nw-src-action{
-                uses address;            
-            }
-            
-            case set-nw-tos-action {
-                leaf tos {
-                    type int32;
-                }
-            }
-            
-            case set-tp-dst-action {
-                leaf port {
-                    type inet:port-number;
-                }                
-            }
-            case set-tp-src-action {
-                leaf port {
-                    type inet:port-number;
-                }                
-            }
-            case set-vlan-cfi-action {
-                leaf vlan-cfi {
-                    type vlan-cfi;
-                }
-            }
-            
-            case set-vlan-id-action {
-                leaf vlan-id {
-                    type l2t:vlan-id;
-                } 
-            }
-            
-            case set-vlan-pcp-action {
-                leaf vlan-pcp {
-                    type l2t:vlan-pcp;
-                }            
-            }
-            
-            case sw-path-action {            
-            }  
-        }
-    }
-
     typedef flow-mod-flags {
         type bits {
             bit CHECK_OVERLAP;
             bit RESET_COUNTS;
             bit NO_PKT_COUNTS;
             bit NO_BYT_COUNTS;
+            bit SEND_FLOW_REM;
         }
     }
     
@@ -341,6 +125,20 @@ module opendaylight-flow-types {
         leaf flow-name{
             type string;
         }
+        
+        leaf installHw {
+            type boolean;
+        }
+
+        leaf barrier {
+            type boolean;
+        }
+
+        leaf strict {
+            type boolean;
+            default "false";
+        }
+
     }
 
     grouping flow-statistics {
index 03e36924e77968ab2815f9b391055945a62dc69b..685728a88709cac4396294e375f22943113de17c 100644 (file)
@@ -3,8 +3,8 @@ module opendaylight-group-types {
     prefix group;
 
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
-    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
-    import opendaylight-flow-types {prefix flow-types;revision-date 2013-10-26";}
+    import ietf-yang-types {prefix yang; revision-date "2010-09-24";}   
+    import opendaylight-action-types {prefix action;}
 
     revision "2013-10-18" {
         description "Initial revision of group service";
@@ -41,6 +41,10 @@ module opendaylight-group-types {
             type string; 
         }
         
+        leaf install {
+            type boolean; 
+        } 
+        
         leaf barrier {
             type boolean; 
         }       
@@ -64,16 +68,7 @@ module opendaylight-group-types {
                     type uint32;
                 }
                 
-                container actions {
-                    list action {
-                        key "action-order";
-                        leaf action-order {
-                            type int32;
-                        }
-            
-                        uses flow-types:action;
-                    }
-                }
+                uses action:action-list;
             }
         }
     }
@@ -164,6 +159,7 @@ module opendaylight-group-types {
             }
             
             uses group-types;
+            
             leaf capabilities { 
                 type enumeration {
                     enum select-weight;
index a2aca362e20a30662ebfd42d92b13b259409cf9f..f58f6a459741e569578c5133b8e6d118e953d2a6 100644 (file)
@@ -19,6 +19,16 @@ module opendaylight-match-types {
             type binary;
         }
     }
+    
+    grouping "of-metadata" {
+        leaf metadata {
+            type uint64;
+        }
+        
+        leaf metadata-mask {
+            type binary;
+        }
+    }
 
      /** Match Groupings **/
     grouping "ethernet-match-fields" {
@@ -40,6 +50,7 @@ module opendaylight-match-types {
                 mandatory true;
                 type l2t:ether-type; // Needs to define that as general model
             }
+
             leaf mask {
                 type binary;
             }
@@ -85,25 +96,27 @@ module opendaylight-match-types {
             description "IP Proto (IPv4 or IPv6 Protocol Number).";
             type inet:ip-version; 
         }
-    }
-
+    } 
+    
     grouping "ipv4-match-fields" {
         leaf ipv4-source {
             description "IPv4 source address.";
             type inet:ipv4-prefix;
         }
+        
         leaf ipv4-destination {
             description "IPv4 destination address.";
             type inet:ipv4-prefix;
         }
+        
     }
-
+    
     grouping "ipv6-match-fields" {
         leaf ipv6-source {
             description "IPv6 source address.";
             type inet:ipv6-prefix;
         }
-        
+    
         leaf ipv6-destination {
             description "IPv6 destination address.";
             type inet:ipv6-prefix;
@@ -111,11 +124,17 @@ module opendaylight-match-types {
         
         leaf ipv6-nd-target {
             description "IPv6 target address for neighbour discovery message";
-            type inet:ipv6-prefix;
+            type inet:ipv6-address;
         }
         
-        leaf ipv6-flabel {
-            type inet:ipv6-flow-label;
+        container "ipv6-label" {
+            leaf ipv6-flabel {
+                type inet:ipv6-flow-label;
+            }
+            
+            leaf flabel-mask {
+                type binary;
+            }
         }
         
         leaf ipv6-nd-sll {
@@ -161,11 +180,16 @@ module opendaylight-match-types {
             type uint8;
         }
         
-        leaf pbb-isid {
-            description "I-SID in the first PBB service instance tag";
-            type uint32;
-        }   
-        
+        container "pbb" {
+            leaf pbb-isid {
+                description "I-SID in the first PBB service instance tag";
+                type uint32;
+            }  
+
+            leaf pbb-mask {
+                type binary;
+            }
+        }
     }
     
     grouping "tcp-match-fields" {
@@ -247,13 +271,19 @@ module opendaylight-match-types {
             type uint32;
         }
         
-        leaf metadata {
-            type uint64;
+        container "metadata" {
+            uses of-metadata;
         }
         
-        leaf tunnel-id {
-            description "Metadata associated in the logical port";
-            type uint64;
+        container "tunnel" {
+            leaf tunnel-id {
+                description "Metadata associated in the logical port";
+                type uint64;
+            }
+            
+            leaf tunnel-mask {
+                type binary;
+            }
         }
         
         container "ethernet-match" {
index 20353af7852bd0b46834e7ad61364b222ec89640..148ac9687f5baa8d66fa0fbfb143d91b6fdafb6f 100644 (file)
@@ -107,6 +107,10 @@ module opendaylight-meter-types {
                     uses meter-band-type;
                 }
             
+                leaf rate {
+                    type uint32;
+                }
+        
                 leaf burst-size {
                     type uint32;
                 }
index 98cf93d4b3825acd320b7dead11b183840eb0e08..2a16bfcf503e41369912ea646c0cc974737528a3 100644 (file)
@@ -5,7 +5,7 @@ module opendaylight-table-types {
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import ietf-yang-types {prefix yang; revision-date "2010-09-24";}
     import opendaylight-flow-types {prefix flow;revision-date 2013-10-26";}
-
+    import opendaylight-action-types {prefix action;}
 
     revision "2013-10-26" {
         description "Initial revision of table service";
@@ -61,25 +61,25 @@ module opendaylight-table-types {
             
             case write-actions {   
                 container write-actions {
-                    uses flow:action-list;
+                    uses action:action-list;
                 } 
             }
             
             case write-actions-miss {   
                 container write-actions-miss {
-                    uses flow:action-list;
+                    uses action:action-list;
                 } 
             }
             
             case apply-actions {   
                 container apply-actions {
-                    uses flow:action-list;
+                    uses action:action-list;
                 } 
             }
             
             case apply-actions-miss {   
                 container apply-actions-miss {
-                    uses flow:action-list;
+                    uses action:action-list;
                 } 
             }
             
index 7501d8a579293d9bfdcd23e875614c2a0b72667c..5a1b0070777d6afbe672c14ec27209d454761a8f 100644 (file)
@@ -6,13 +6,12 @@ module sal-flow {
     import opendaylight-inventory {prefix inv;revision-date "2013-08-19";}
     import ietf-inet-types {prefix inet; revision-date "2010-09-24";}
     import opendaylight-flow-types {prefix types;revision-date "2013-10-26";}
-
+    import flow-capable-transaction {prefix tr;}
 
     revision "2013-08-19" {
         description "Initial revision of flow service";
     }
 
-
     typedef flow-table-ref {
         type instance-identifier;
     }
@@ -41,18 +40,30 @@ module sal-flow {
     rpc add-flow {
         input {
             uses node-flow;
+            uses tr:transaction-aware;            
+        }
+        output {
+            uses tr:transaction-aware;
         }
     }
 
     rpc remove-flow {
         input {
             uses node-flow;
+            uses tr:transaction-aware;            
+        }
+        output {
+            uses tr:transaction-aware;
         }
     }
 
     rpc update-flow {
         input {
             uses flow-update;
+            uses tr:transaction-aware;            
+        }
+        output {
+            uses tr:transaction-aware;
         }
     }
 
index 35264e74e6bd22bf1a69db6f97c3884270d3a5a5..9e4d3a580c79888da155bd9a5808971862ffed84 100644 (file)
@@ -88,6 +88,7 @@
                             org.opendaylight.controller.sal.binding.impl.*,
                             org.opendaylight.controller.sal.binding.codegen,
                             org.opendaylight.controller.sal.binding.codegen.*,
+                            org.opendaylight.controller.sal.binding.dom.*,
                         </Private-Package>
                     </instructions>
                 </configuration>
index 1d828077b848bcd264589fb05225ff62aceb3ac2..6672d953a2c29243d525de87f07c4c014c6bdf97 100644 (file)
@@ -7,11 +7,9 @@
  */
 package org.opendaylight.controller.sal.binding.codegen;
 
-import org.opendaylight.controller.sal.binding.spi.DelegateProxy;
 import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory;
 import org.opendaylight.controller.sal.binding.spi.RpcRouter;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.binding.RpcImplementation;
 import org.opendaylight.yangtools.yang.binding.RpcService;
 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/JavassistUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/JavassistUtils.java
deleted file mode 100644 (file)
index c6be284..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-package org.opendaylight.controller.sal.binding.codegen.impl;
-
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-
-public class JavassistUtils {
-
-    public static interface ClassGenerator {
-        void process(CtClass cls);
-    }
-
-    public static interface MethodGenerator {
-        void process(CtMethod method);
-    }
-
-    public static interface FieldGenerator {
-        void process(CtField field);
-    }
-}
index ea6dc131c6583b3587b23cc172e61f62c3ad68af..93c192c0af54222533da37727f4575520dea9259 100644 (file)
@@ -12,9 +12,6 @@ import org.opendaylight.yangtools.yang.binding.RpcService
 
 import javassist.CtClass
 import static com.google.common.base.Preconditions.*
-
-import javassist.CtField
-import javassist.Modifier
 import javassist.CtMethod
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext
@@ -22,13 +19,11 @@ import org.opendaylight.yangtools.yang.binding.BaseIdentity
 
 import java.util.Map
 import java.util.HashMap
-import javassist.NotFoundException
-import javassist.LoaderClassPath
-import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.MethodGenerator
-import org.opendaylight.controller.sal.binding.codegen.impl.JavassistUtils.ClassGenerator
+
+
 import org.opendaylight.yangtools.yang.binding.NotificationListener
 import org.opendaylight.yangtools.yang.binding.Notification
-import java.util.Arrays
+
 
 import static extension org.opendaylight.controller.sal.binding.codegen.YangtoolsMappingHelper.*
 import static extension org.opendaylight.controller.sal.binding.codegen.RuntimeCodeSpecification.*
@@ -39,19 +34,21 @@ import org.opendaylight.controller.sal.binding.spi.NotificationInvokerFactory.No
 import java.util.Set
 import org.opendaylight.controller.sal.binding.codegen.RuntimeCodeHelper
 import java.util.WeakHashMap
-import javassist.ClassClassPath
 import org.opendaylight.yangtools.yang.binding.annotations.QName
 import org.opendaylight.yangtools.yang.binding.DataContainer
 import org.opendaylight.yangtools.yang.binding.RpcImplementation
+import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
 
 class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.codegen.RuntimeCodeGenerator, NotificationInvokerFactory {
 
     val CtClass BROKER_NOTIFICATION_LISTENER;
     val ClassPool classPool;
+    val extension JavassistUtils utils;
     val Map<Class<? extends NotificationListener>, RuntimeGeneratedInvokerPrototype> invokerClasses;
 
     public new(ClassPool pool) {
         classPool = pool;
+        utils = new JavassistUtils(pool);
         invokerClasses = new WeakHashMap();
         BROKER_NOTIFICATION_LISTENER = org.opendaylight.controller.sal.binding.api.NotificationListener.asCtClass;
     }
@@ -216,65 +213,9 @@ class RuntimeCodeGenerator implements org.opendaylight.controller.sal.binding.co
             finalClass as Class<? extends org.opendaylight.controller.sal.binding.api.NotificationListener>);
     }
 
-    private def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
-        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
-        function1.process(method);
-        it.addMethod(method);
-    }
-
-    private def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
-        for (method : source.methods) {
-            if (method.declaringClass == source) {
-                val redeclaredMethod = new CtMethod(method, target, null);
-                function1.process(redeclaredMethod);
-                target.addMethod(redeclaredMethod);
-            }
-        }
-    }
-
-    private def CtClass createClass(String fqn, ClassGenerator cls) {
-        val target = classPool.makeClass(fqn);
-        cls.process(target);
-        return target;
-    }
-
-    private def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
-        val target = classPool.makeClass(fqn);
-        target.implementsType(superInterface);
-        cls.process(target);
-        return target;
-    }
-
-    private def void implementsType(CtClass it, CtClass supertype) {
-        checkArgument(supertype.interface, "Supertype must be interface");
-        addInterface(supertype);
-    }
-
-    private def asCtClass(Class<?> class1) {
-        classPool.get(class1);
-    }
+    
 
-    private def CtField field(CtClass it, String name, Class<?> returnValue) {
-        val field = new CtField(returnValue.asCtClass, name, it);
-        field.modifiers = Modifier.PUBLIC
-        addField(field);
-        return field;
-    }
 
-    def get(ClassPool pool, Class<?> cls) {
-        try {
-            return pool.get(cls.name)
-        } catch (NotFoundException e) {
-            pool.appendClassPath(new LoaderClassPath(cls.classLoader));
-            try {
-                return pool.get(cls.name)
-
-            } catch (NotFoundException ef) {
-                pool.appendClassPath(new ClassClassPath(cls));
-                return pool.get(cls.name)
-            }
-        }
-    }
 
     protected def resolveInvokerClass(Class<? extends NotificationListener> class1) {
         val invoker = invokerClasses.get(class1);
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/ClassGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/ClassGenerator.java
new file mode 100644 (file)
index 0000000..c4abc32
--- /dev/null
@@ -0,0 +1,7 @@
+package org.opendaylight.controller.sal.binding.codegen.util;
+
+import javassist.CtClass;
+
+public interface ClassGenerator {
+    void process(CtClass cls);
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/FieldGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/FieldGenerator.java
new file mode 100644 (file)
index 0000000..2e053f0
--- /dev/null
@@ -0,0 +1,7 @@
+package org.opendaylight.controller.sal.binding.codegen.util;
+
+import javassist.CtField;
+
+public interface FieldGenerator {
+    void process(CtField field);
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/JavassistUtils.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/JavassistUtils.xtend
new file mode 100644 (file)
index 0000000..19737b8
--- /dev/null
@@ -0,0 +1,94 @@
+package org.opendaylight.controller.sal.binding.codegen.util
+
+import javassist.CtClass
+import javassist.CtMethod
+import javassist.ClassPool
+import java.util.Arrays
+import static com.google.common.base.Preconditions.*;
+import javassist.CtField
+import javassist.Modifier
+import javassist.NotFoundException
+import javassist.LoaderClassPath
+import javassist.ClassClassPath
+
+class JavassistUtils {
+
+    ClassPool classPool
+
+    new(ClassPool pool) {
+        classPool = pool;
+    }
+
+    def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
+        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
+        function1.process(method);
+        it.addMethod(method);
+    }
+    
+        def void method(CtClass it, Class<?> returnType, String name, Class<?> parameter1, Class<?> parameter2,  MethodGenerator function1) {
+        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter1.asCtClass,parameter2.asCtClass), it);
+        function1.process(method);
+        it.addMethod(method);
+    }
+    
+    
+    def void staticMethod(CtClass it, Class<?> returnType, String name, Class<?> parameter, MethodGenerator function1) {
+        val method = new CtMethod(returnType.asCtClass, name, Arrays.asList(parameter.asCtClass), it);
+        function1.process(method);
+        it.addMethod(method);
+    }
+
+    def void implementMethodsFrom(CtClass target, CtClass source, MethodGenerator function1) {
+        for (method : source.methods) {
+            if (method.declaringClass == source) {
+                val redeclaredMethod = new CtMethod(method, target, null);
+                function1.process(redeclaredMethod);
+                target.addMethod(redeclaredMethod);
+            }
+        }
+    }
+
+    def CtClass createClass(String fqn, ClassGenerator cls) {
+        val target = classPool.makeClass(fqn);
+        cls.process(target);
+        return target;
+    }
+
+    def CtClass createClass(String fqn, CtClass superInterface, ClassGenerator cls) {
+        val target = classPool.makeClass(fqn);
+        target.implementsType(superInterface);
+        cls.process(target);
+        return target;
+    }
+
+    def void implementsType(CtClass it, CtClass supertype) {
+        checkArgument(supertype.interface, "Supertype must be interface");
+        addInterface(supertype);
+    }
+
+    def asCtClass(Class<?> class1) {
+        classPool.get(class1);
+    }
+
+    def CtField field(CtClass it, String name, Class<?> returnValue) {
+        val field = new CtField(returnValue.asCtClass, name, it);
+        field.modifiers = Modifier.PUBLIC
+        addField(field);
+        return field;
+    }
+
+    def get(ClassPool pool, Class<?> cls) {
+        try {
+            return pool.get(cls.name)
+        } catch (NotFoundException e) {
+            pool.appendClassPath(new LoaderClassPath(cls.classLoader));
+            try {
+                return pool.get(cls.name)
+
+            } catch (NotFoundException ef) {
+                pool.appendClassPath(new ClassClassPath(cls));
+                return pool.get(cls.name)
+            }
+        }
+    }
+}
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/MethodGenerator.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/util/MethodGenerator.java
new file mode 100644 (file)
index 0000000..0eddbd6
--- /dev/null
@@ -0,0 +1,7 @@
+package org.opendaylight.controller.sal.binding.codegen.util;
+
+import javassist.CtMethod;
+
+public interface MethodGenerator {
+    void process(CtMethod method);
+}
\ No newline at end of file
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/dom/serializer/impl/TransformerGenerator.xtend
new file mode 100644 (file)
index 0000000..2d67f11
--- /dev/null
@@ -0,0 +1,776 @@
+package org.opendaylight.controller.sal.binding.dom.serializer.impl
+
+import javassist.ClassPool
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import org.opendaylight.controller.sal.binding.codegen.util.JavassistUtils
+import javassist.CtClass
+import java.util.Map
+import org.opendaylight.yangtools.yang.common.QName
+import javassist.CtField
+import static javassist.Modifier.*
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.binding.generator.util.Types
+import org.opendaylight.yangtools.sal.binding.model.api.ParameterizedType
+import java.util.HashMap
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode
+import java.util.WeakHashMap
+import java.util.List
+import java.util.TreeSet
+import com.google.common.base.Joiner
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
+import org.opendaylight.yangtools.sal.binding.model.api.Enumeration
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode
+import static org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils.*;
+import org.opendaylight.yangtools.yang.binding.BindingDeserializer
+import org.opendaylight.yangtools.yang.binding.BindingSerializer
+import org.opendaylight.yangtools.yang.binding.BindingCodec
+import org.slf4j.LoggerFactory
+
+class TransformerGenerator {
+
+    private static val log = LoggerFactory.getLogger(TransformerGenerator)
+
+    public static val STRING = Types.typeForClass(String);
+    public static val BOOLEAN = Types.typeForClass(Boolean);
+    public static val INTEGER = Types.typeForClass(Integer);
+
+    //public static val DECIMAL = Types.typeForClass(Decimal);
+    public static val LONG = Types.typeForClass(Long);
+
+    val ClassPool classPool
+    val extension JavassistUtils utils;
+
+    CtClass ctTransformator
+
+    CtClass ctQName
+
+    @Property
+    var Map<Type, Type> typeDefinitions;
+
+    @Property
+    var Map<Type, GeneratedTypeBuilder> typeToDefinition
+
+    @Property
+    var Map<Type, SchemaNode> typeToSchemaNode
+
+    val Map<Class<?>, Class<?>> generatedClasses = new WeakHashMap();
+
+    public new(ClassPool pool) {
+        classPool = pool;
+        utils = new JavassistUtils(pool)
+
+        ctTransformator = BindingCodec.asCtClass;
+        ctQName = QName.asCtClass
+    }
+
+    def Class<? extends BindingCodec<Map<QName, Object>, Object>> transformerFor(Class<?> inputType) {
+        return withClassLoader(inputType.classLoader) [ |
+            val ret = generatedClasses.get(inputType);
+            if (ret !== null) {
+                return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+            }
+            val ref = Types.typeForClass(inputType)
+            val node = typeToSchemaNode.get(ref)
+            val typeSpecBuilder = typeToDefinition.get(ref)
+            val typeSpec = typeSpecBuilder.toInstance();
+            val newret = generateTransformerFor(inputType, typeSpec, node)
+            generatedClasses.put(inputType, newret);
+            return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+        ]
+    }
+
+    def Class<?> keyTransformerFor(Class<?> inputType, GeneratedType type, ListSchemaNode schema) {
+        return withClassLoader(inputType.classLoader) [ |
+            val transformer = generatedClasses.get(inputType);
+            if (transformer != null) {
+                return transformer;
+            }
+            val newret = generateKeyTransformerFor(inputType, type, schema);
+            generatedClasses.put(inputType, newret);
+            return newret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+        ]
+    }
+
+    def Class<?> keyTransformer(GeneratedType type, ListSchemaNode node) {
+        val cls = loadClassWithTCCL(type.resolvedName + "Key");
+        keyTransformerFor(cls, type, node);
+    }
+
+    private def serializer(Type type) {
+        val cls = loadClassWithTCCL(type.resolvedName);
+        transformerFor(cls);
+
+    }
+
+    def Class<?> getValueSerializer(GeneratedTransferObject type) {
+        val cls = loadClassWithTCCL(type.resolvedName);
+        val transformer = generatedClasses.get(cls);
+        if (transformer !== null) {
+            return transformer;
+        }
+        val valueTransformer = generateValueTransformer(cls, type);
+        generatedClasses.put(cls, valueTransformer);
+        return valueTransformer;
+    }
+
+    private def generateKeyTransformerFor(Class<? extends Object> inputType, GeneratedType typeSpec, ListSchemaNode node) {
+        try {
+            log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+            val properties = typeSpec.allProperties;
+            val ctCls = createClass(inputType.transformatorFqn) [
+                //staticField(Map,"AUGMENTATION_SERIALIZERS");
+                staticQNameField(node.QName);
+                implementsType(ctTransformator)
+                method(Object, "toDomStatic", QName, Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        {
+                        
+                            return null;
+                        }
+                    '''
+                ]
+                method(Object, "fromDomStatic", QName, Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        {
+                            if($2 == null){
+                                return  null;
+                            }
+                            «QName.name» _localQName = $1;
+                            java.util.Map _compositeNode = (java.util.Map) $2;
+                            «FOR key : node.keyDefinition»
+                                «val propertyName = key.getterName»
+                                «val keyDef = node.getDataChildByName(key)»
+                                «val property = properties.get(propertyName)»
+                                «deserializeProperty(keyDef, property.returnType, property)»;
+                            «ENDFOR»
+                            «inputType.name» _value = new «inputType.name»(«node.keyDefinition.keyConstructorList»);
+                            return _value;
+                        }
+                    '''
+                ]
+                method(Object, "serialize", Object) [
+                    body = '''
+                        return toDomStatic(QNAME,$1);
+                    '''
+                ]
+                method(Object, "deserialize", Object) [
+                    body = '''
+                        return fromDomStatic(QNAME,$1);
+                    '''
+                ]
+            ]
+            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            log.info("DOM Codec for {} was generated {}",inputType,ret)
+            return ret as Class<? extends BindingCodec<Map<QName,Object>, ?>>;
+        } catch (Exception e) {
+            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+            exception.addSuppressed(e);
+            throw exception;
+        }
+    }
+
+    private def <D> Class<? extends BindingCodec<Map<QName, Object>, D>> generateTransformerFor(Class<D> inputType,
+        GeneratedType typeSpec, SchemaNode node) {
+        try {
+            log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+            val ctCls = createClass(typeSpec.transformatorFqn) [
+                //staticField(Map,"AUGMENTATION_SERIALIZERS");
+                staticQNameField(inputType);
+                implementsType(ctTransformator)
+                method(Object, "toDomStatic", QName, Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = serializeBodyFacade(typeSpec, node)
+                ]
+                method(Object, "serialize", Object) [
+                    body = '''
+                        return toDomStatic(QNAME,$1);
+                    '''
+                ]
+                method(Object, "fromDomStatic", QName, Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = deserializeBody(typeSpec, node)
+                ]
+                method(Object, "deserialize", Object) [
+                    body = '''
+                        return fromDomStatic(QNAME,$1);
+                    '''
+                ]
+            ]
+
+            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            return ret as Class<? extends BindingCodec<Map<QName,Object>, D>>;
+        } catch (Exception e) {
+            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+            exception.addSuppressed(e);
+            throw exception;
+        }
+    }
+
+    private def keyConstructorList(List<QName> qnames) {
+        val names = new TreeSet<String>()
+        for (name : qnames) {
+            val fieldName = name.getterName;
+            names.add(fieldName);
+        }
+        return Joiner.on(",").join(names);
+    }
+
+    private def serializeBodyFacade(GeneratedType type, SchemaNode node) {
+        val ret = serializeBody(type, node);
+        return ret;
+    }
+
+    private def String deserializeBody(GeneratedType type, SchemaNode node) {
+        val ret = deserializeBodyImpl(type, node);
+        return ret;
+    }
+
+    private def deserializeKey(GeneratedType type, ListSchemaNode node) {
+        if (node.keyDefinition != null && !node.keyDefinition.empty) {
+            return '''
+                «type.resolvedName»Key getKey = («type.resolvedName»Key) «keyTransformer(type, node).canonicalName».fromDomStatic(_localQName,_compositeNode);
+                _builder.setKey(getKey);
+            ''';
+        }
+    }
+
+    private def dispatch String deserializeBodyImpl(GeneratedType type, SchemaNode node) '''
+        {
+            «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+            
+            if($2 == null) {
+                return null;
+            }
+            java.util.Map _compositeNode = (java.util.Map) $2;
+            «type.builderName» _builder = new «type.builderName»();
+            
+            return _builder.build();
+        }
+    '''
+
+    private def dispatch String deserializeBodyImpl(GeneratedType type, ListSchemaNode node) '''
+        {
+            «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+            if($2 == null) {
+                return null;
+            }
+            java.util.Map _compositeNode = (java.util.Map) $2;
+            «type.builderName» _builder = new «type.builderName»();
+            «deserializeKey(type, node)»
+            «deserializeDataNodeContainerBody(type, node)»
+            return _builder.build();
+        }
+    '''
+
+    private def dispatch String deserializeBodyImpl(GeneratedType type, ContainerSchemaNode node) '''
+        {
+            «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+            if($2 == null) {
+                return null;
+            }
+            java.util.Map _compositeNode = (java.util.Map) $2;
+            «type.builderName» _builder = new «type.builderName»();
+            «deserializeDataNodeContainerBody(type, node)»
+            return _builder.build();
+        }
+    '''
+
+    private def dispatch String deserializeBodyImpl(GeneratedType type, ChoiceCaseNode node) '''
+        {
+            «QName.name» _localQName = «QName.name».create($1,QNAME.getLocalName());
+            if($2 == null) {
+                return null;
+            }
+            java.util.Map _compositeNode = (java.util.Map) $2;
+            «type.builderName» _builder = new «type.builderName»();
+            «deserializeDataNodeContainerBody(type, node)»
+            return _builder.build();
+        }
+    '''
+
+    private def deserializeDataNodeContainerBody(GeneratedType type, DataNodeContainer node) {
+        deserializeNodeContainerBodyImpl(type, type.allProperties, node);
+    }
+
+    private def deserializeNodeContainerBodyImpl(GeneratedType type, HashMap<String, MethodSignature> properties,
+        DataNodeContainer node) {
+        val ret = '''
+            «FOR child : node.childNodes.filter[!augmenting]»
+                «val signature = properties.get(child.getterName)»
+                «deserializeProperty(child, signature.returnType, signature)»
+                _builder.«signature.name.toSetter»(«signature.name»);
+            «ENDFOR»
+        '''
+        return ret;
+    }
+
+    private def dispatch CharSequence deserializeProperty(ListSchemaNode schema, ParameterizedType type,
+        MethodSignature property) '''
+        java.util.List _dom_«property.name» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
+            localName»"));
+        //System.out.println("«property.name»#deCode"+_dom_«property.name»);
+        java.util.List «property.name» = new java.util.ArrayList();
+        if(_dom_«property.name» != null) {
+            java.util.List _serialized = new java.util.ArrayList();
+            java.util.Iterator _iterator = _dom_«property.name».iterator();
+            boolean _hasNext = _iterator.hasNext();
+            while(_hasNext) {
+                Object _listItem = _iterator.next();
+                //System.out.println("  item" + _listItem);
+                Object _value = «type.actualTypeArguments.get(0).serializer.name».fromDomStatic(_localQName,_listItem);
+                //System.out.println("  value" + _value);
+                «property.name».add(_value);
+                _hasNext = _iterator.hasNext();
+            }
+        }
+        
+        //System.out.println(" list" + «property.name»);
+    '''
+
+    private def dispatch CharSequence deserializeProperty(LeafListSchemaNode schema, ParameterizedType type,
+        MethodSignature property) '''
+        java.util.List _dom_«property.name» = _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.
+            localName»"));
+        java.util.List «property.name» = new java.util.ArrayList();
+        if(_dom_«property.name» != null) {
+            java.util.List _serialized = new java.util.ArrayList();
+            java.util.Iterator _iterator = _dom_«property.name».iterator();
+            boolean _hasNext = _iterator.hasNext();
+            while(_hasNext) {
+                Object _listItem = _iterator.next();
+                if(_listItem instanceof java.util.Map.Entry) {
+                    Object _innerValue = ((java.util.Map.Entry) _listItem).getValue();
+                    Object _value = «deserializeValue(type.actualTypeArguments.get(0), "_innerValue")»;
+                    «property.name».add(_value);
+                }
+                _hasNext = _iterator.hasNext();
+            }
+        }
+    '''
+
+    private def dispatch CharSequence deserializeProperty(LeafSchemaNode schema, Type type, MethodSignature property) '''
+        java.util.List _dom_«property.name»_list = 
+            _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
+        «type.resolvedName» «property.name» = null;
+        if(_dom_«property.name»_list != null && _dom_«property.name»_list.size() > 0) {
+            java.util.Map.Entry _dom_«property.name» = (java.util.Map.Entry) _dom_«property.name»_list.get(0);
+            Object _inner_value = _dom_«property.name».getValue();
+            «property.name» = «deserializeValue(type, "_inner_value")»;
+        }
+    '''
+
+    private def dispatch CharSequence deserializeProperty(ContainerSchemaNode schema, Type type,
+        MethodSignature property) '''
+        java.util.List _dom_«property.name»_list = 
+            _compositeNode.get(«QName.name».create(_localQName,"«schema.QName.localName»"));
+        «type.resolvedName» «property.name» = null;
+        if(_dom_«property.name»_list != null && _dom_«property.name»_list.size() > 0) {
+            
+            java.util.Map _dom_«property.name» = (java.util.Map) _dom_«property.name»_list.get(0);
+            «type.resolvedName» «property.name» =  «type.serializer.name».fromDomStatic(_localQName,_dom_«property.name»);
+        }
+    '''
+
+    private def dispatch String deserializeValue(GeneratedTransferObject type, String domParameter) '''
+        («type.resolvedName») «type.valueSerializer.name».fromDomValue(«domParameter»);
+    '''
+
+    private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+        Class<?> inputType, GeneratedTransferObject typeSpec) {
+        try {
+
+            val returnType = typeSpec.valueReturnType;
+            if (returnType == null) {
+
+                val ctCls = createDummyImplementation(inputType, typeSpec);
+                val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+                return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+            }
+            val ctCls = createClass(typeSpec.transformatorFqn) [
+                //staticField(Map,"AUGMENTATION_SERIALIZERS");
+                implementsType(ctTransformator)
+                implementsType(BindingDeserializer.asCtClass)
+                method(Object, "toDomValue", Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        {
+                            ////System.out.println("«inputType.simpleName»#toDomValue: "+$1);
+                            
+                            if($1 == null) {
+                                return null;
+                            }
+                            «typeSpec.resolvedName» _encapsulatedValue = («typeSpec.resolvedName») $1;
+                            //System.out.println("«inputType.simpleName»#toDomValue:Enc: "+_encapsulatedValue);
+                            «returnType.resolvedName» _value =  _encapsulatedValue.getValue();
+                            //System.out.println("«inputType.simpleName»#toDomValue:DeEnc: "+_value);
+                            return _value;
+                        }
+                    '''
+                ]
+                method(Object, "serialize", Object) [
+                    body = '''
+                        {
+                            return toDomValue($1);
+                        }
+                    '''
+                ]
+                method(Object, "fromDomValue", Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        {
+                            //System.out.println("«inputType.simpleName»#fromDomValue: "+$1);
+                            
+                            if($1 == null) {
+                                return null;
+                            }
+                            «returnType.name» _simpleValue = «deserializeValue(returnType, "$1")»;
+                            «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(_simpleValue);
+                            return _value;
+                        }
+                    '''
+                ]
+                method(Object, "deserialize", Object) [
+                    body = '''{
+                            return fromDomValue($1);
+                    }
+                    '''
+                ]
+            ]
+
+            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            log.info("DOM Codec for {} was generated {}",inputType,ret)
+            return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+        } catch (Exception e) {
+            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+            exception.addSuppressed(e);
+            throw exception;
+        }
+
+    }
+
+    private def createDummyImplementation(Class<?> object, GeneratedTransferObject typeSpec) {
+        log.info("Generating Dummy DOM Codec for {} with {}",object,object.classLoader)
+        return createClass(typeSpec.transformatorFqn) [
+            //staticField(Map,"AUGMENTATION_SERIALIZERS");
+            implementsType(ctTransformator)
+            implementsType(BindingDeserializer.asCtClass)
+            method(Object, "toDomValue", Object) [
+                modifiers = PUBLIC + FINAL + STATIC
+                body = '''return null;'''
+            ]
+            method(Object, "serialize", Object) [
+                body = '''
+                    {
+                        return toDomValue($1);
+                    }
+                '''
+            ]
+            method(Object, "fromDomValue", Object) [
+                modifiers = PUBLIC + FINAL + STATIC
+                body = '''return null;'''
+            ]
+            method(Object, "deserialize", Object) [
+                body = '''{
+                        return fromDomValue($1);
+                    }
+                    '''
+            ]
+        ]
+    }
+
+    def Type getValueReturnType(GeneratedTransferObject object) {
+        for (prop : object.properties) {
+            if (prop.name == "value") {
+                return prop.returnType;
+            }
+        }
+        if (object.superType != null) {
+            return getValueReturnType(object.superType);
+        }
+        return null;
+    }
+
+    private def dispatch Class<? extends BindingCodec<Map<QName, Object>, Object>> generateValueTransformer(
+        Class<?> inputType, Enumeration typeSpec) {
+        try {
+            log.info("Generating DOM Codec for {} with {}",inputType,inputType.classLoader)
+            val ctCls = createClass(typeSpec.transformatorFqn) [
+                //staticField(Map,"AUGMENTATION_SERIALIZERS");
+                implementsType(ctTransformator)
+                method(Object, "toDomValue", Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        if($1 == null) {
+                            return null;
+                        }
+                        «typeSpec.resolvedName» _value = («typeSpec.resolvedName») $1;
+                        return _value.getValue();
+                    '''
+                ]
+                method(Object, "serialize", Object) [
+                    body = '''
+                        return toDomValue($1);
+                    '''
+                ]
+                method(Object, "fromDomValue", Object) [
+                    modifiers = PUBLIC + FINAL + STATIC
+                    body = '''
+                        if($1 == null) {
+                            return null;
+                        }
+                        _simpleValue = null;
+                        «typeSpec.resolvedName» _value = new «typeSpec.resolvedName»(null);
+                        return _value;
+                    '''
+                ]
+                method(Object, "deserialize", Object) [
+                    body = '''
+                        return fromDomValue($1);
+                    '''
+                ]
+            ]
+
+            val ret = ctCls.toClass(inputType.classLoader, inputType.protectionDomain)
+            log.info("DOM Codec for {} was generated {}",inputType,ret)
+            return ret as Class<? extends BindingCodec<Map<QName,Object>, Object>>;
+        } catch (Exception e) {
+            log.error("Cannot compile DOM Codec for {}. Exception {}",inputType,e);
+            val exception = new IllegalStateException("Cannot compile Transformator for " + inputType);
+            exception.addSuppressed(e);
+            throw exception;
+        }
+
+    }
+
+    private def dispatch String deserializeValue(Type type, String domParameter) '''(«type.resolvedName») «domParameter»'''
+
+    /** 
+     * Default catch all
+     * 
+     **/
+    private def dispatch CharSequence deserializeProperty(DataSchemaNode container, Type type, MethodSignature property) '''
+        «type.resolvedName» «property.name» = null;
+    '''
+
+    private def dispatch CharSequence deserializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
+        MethodSignature property) {
+        _deserializeProperty(container, type.toInstance, property)
+    }
+
+    public static def toSetter(String it) {
+
+        if (startsWith("is")) {
+            return "set" + substring(2);
+        } else if (startsWith("get")) {
+            return "set" + substring(3);
+        }
+        return "set" + it;
+    }
+
+    /* 
+    private def dispatch CharSequence deserializeProperty(DataSchemaNode container,GeneratedType type, MethodSignature property) '''
+        «property.returnType.resolvedName» «property.name» = value.«property.name»();
+        if(«property.name» != null) {
+            Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
+            childNodes.add(domValue);
+        }
+    '''
+    */
+    private def getBuilderName(GeneratedType type) '''«type.resolvedName»Builder'''
+
+    private def staticQNameField(CtClass it, Class node) {
+        val field = new CtField(ctQName, "QNAME", it);
+        field.modifiers = PUBLIC + FINAL + STATIC;
+        addField(field, '''«node.name».QNAME''')
+    }
+    
+    private def staticQNameField(CtClass it, QName node) {
+        val field = new CtField(ctQName, "QNAME", it);
+        field.modifiers = PUBLIC + FINAL + STATIC;
+        addField(field, '''«QName.asCtClass.name».create("«node.namespace»","«node.formattedRevision»","«node.localName»")''')
+    }
+
+    private def dispatch String serializeBody(GeneratedType type, ListSchemaNode node) '''
+        {
+            «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
+            java.util.List childNodes = new java.util.ArrayList();
+            «type.resolvedName» value = («type.resolvedName») $2;
+            «transformDataContainerBody(type.allProperties, node)»
+            return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+        }
+    '''
+
+    private def dispatch String serializeBody(GeneratedType type, ContainerSchemaNode node) '''
+        {
+            «QName.name» resultName = «QName.name».create($1,QNAME.getLocalName());
+            java.util.List childNodes = new java.util.ArrayList();
+            «type.resolvedName» value = («type.resolvedName») $2;
+            «transformDataContainerBody(type.allProperties, node)»
+            return ($r) java.util.Collections.singletonMap(resultName,childNodes);
+        }
+    '''
+
+    private def transformDataContainerBody(Map<String, MethodSignature> properties, DataNodeContainer node) {
+        val ret = '''
+            «FOR child : node.childNodes.filter[!augmenting]»
+                «val signature = properties.get(child.getterName)»
+                «serializeProperty(child, signature.returnType, signature)»
+            «ENDFOR»
+        '''
+        return ret;
+    }
+
+    private static def String getGetterName(DataSchemaNode node) {
+        return "get" + BindingGeneratorUtil.parseToClassName(node.QName.localName);
+    }
+
+    private static def String getGetterName(QName node) {
+        return "get" + BindingGeneratorUtil.parseToClassName(node.localName);
+    }
+
+    private def dispatch CharSequence serializeProperty(ListSchemaNode schema, ParameterizedType type,
+        MethodSignature property) '''
+        «property.returnType.resolvedName» «property.name» = value.«property.name»();
+        if(«property.name» != null) {
+            java.util.Iterator _iterator = «property.name».iterator();
+            boolean _hasNext = _iterator.hasNext();
+            while(_hasNext) {
+                Object _listItem = _iterator.next();
+                Object _domValue = «type.actualTypeArguments.get(0).serializer.name».toDomStatic(QNAME,_listItem);
+                childNodes.add(_domValue);
+                _hasNext = _iterator.hasNext();
+            }
+        }
+    '''
+
+    private def dispatch CharSequence serializeProperty(LeafSchemaNode schema, Type type, MethodSignature property) '''
+        «property.returnType.resolvedName» «property.name» = value.«property.name»();
+        
+        if(«property.name» != null) {
+            «QName.name» _qname = «QName.name».create(resultName,"«schema.QName.localName»");
+            Object _propValue = «serializeValue(type, property.name)»;
+            if(_propValue != null) {
+                Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
+                childNodes.add(_domValue);
+            }
+        }
+    '''
+
+    private def dispatch serializeValue(GeneratedTransferObject type, String parameter) '''«type.valueSerializer.name».toDomValue(«parameter»)'''
+
+    private def dispatch serializeValue(Type signature, String property) '''«property»'''
+
+    private def dispatch CharSequence serializeProperty(LeafListSchemaNode schema, Type type, MethodSignature property) '''
+        «property.returnType.resolvedName» «property.name» = value.«property.name»();
+        if(«property.name» != null) {
+            «QName.name» _qname = «QName.name».create(resultName,"«schema.QName.localName»");
+            java.util.Iterator _iterator = «property.name».iterator();
+            boolean _hasNext = _iterator.hasNext();
+            while(_hasNext) {
+                Object _listItem = _iterator.next();
+                Object _propValue = «property.name»;
+                Object _domValue = java.util.Collections.singletonMap(_qname,_propValue);
+                childNodes.add(_domValue);
+                _hasNext = _iterator.hasNext();
+            }
+        }
+    '''
+
+    /** 
+     * Default catch all
+     * 
+     **/
+    private def dispatch CharSequence serializeProperty(DataSchemaNode container, Type type, MethodSignature property) '''
+        «property.returnType.resolvedName» «property.name» = value.«property.name»();
+        if(«property.name» != null) {
+            Object domValue = «property.name»;
+            childNodes.add(domValue);
+        }
+    '''
+
+    private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedTypeBuilder type,
+        MethodSignature property) {
+        serializeProperty(container, type.toInstance, property)
+    }
+
+    private def dispatch CharSequence serializeProperty(DataSchemaNode container, GeneratedType type,
+        MethodSignature property) '''
+        «property.returnType.resolvedName» «property.name» = value.«property.name»();
+        if(«property.name» != null) {
+            Object domValue = «type.serializer».toDomStatic(QNAME,«property.name»);
+            childNodes.add(domValue);
+        }
+    '''
+
+    private def dispatch String serializeBody(GeneratedType type, SchemaNode node) '''
+        {
+            return ($r) java.util.Collections.singletonMap(this.QNAME,null);
+        }
+    '''
+
+    private def transformatorFqn(GeneratedType typeSpec) {
+        return '''«typeSpec.resolvedName»$Broker$Codec$DOM'''
+    }
+
+    private def transformatorFqn(Class typeSpec) {
+        return '''«typeSpec.name»$Broker$Codec$DOM'''
+    }
+
+    private def HashMap<String, MethodSignature> getAllProperties(GeneratedType type) {
+        val ret = new HashMap<String, MethodSignature>();
+        type.collectAllProperties(ret);
+        return ret;
+    }
+
+    private def dispatch void collectAllProperties(GeneratedType type, Map<String, MethodSignature> set) {
+        for (definition : type.methodDefinitions) {
+            set.put(definition.name, definition);
+        }
+
+        for (parent : type.implements) {
+            parent.collectAllProperties(set);
+        }
+    }
+
+    private def dispatch void collectAllProperties(Type type, Map<String, MethodSignature> set) {
+        // NOOP for generic type.
+    }
+
+    def String getResolvedName(Type type) {
+        return type.asCtClass.name;
+    }
+
+    def CtClass asCtClass(Type type) {
+        val name = type.fullyQualifiedName
+        val cls = loadClassWithTCCL(type.fullyQualifiedName)
+        return cls.asCtClass;
+    }
+
+}
+
+@Data
+class PropertyPair {
+
+    String getterName;
+
+    Type type;
+
+    @Property
+    MethodSignature signature;
+    @Property
+    SchemaNode schemaNode;
+}
index 0a8a7df41ccd320d43083006e9d2bd3833443f88..e2b79203c94dd6db2bb33026dd2ba804b08857a1 100644 (file)
@@ -47,10 +47,20 @@ import org.opendaylight.yangtools.yang.data.api.SimpleNode
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil
 import org.opendaylight.controller.sal.binding.impl.util.ClassLoaderUtils
 import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
+import com.google.common.collect.HashMultimap
+import com.google.common.collect.ArrayListMultimap
+import com.google.common.collect.Multimap
+import java.util.Collection
+import org.opendaylight.yangtools.sal.binding.model.api.MethodSignature
 
 class BindingMapping {
 
+
+
+    @Property
     val Map<Type, GeneratedTypeBuilder> typeToDefinition = new HashMap();
+    
+    @Property
     val Map<Type, SchemaNode> typeToSchemaNode = new HashMap();
 
     def QName getSchemaNode(Class<?> cls) {
@@ -91,7 +101,7 @@ class BindingMapping {
 
     }
 
-    def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
+    private def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument, Class<? extends DataObject> parent) {
         val Class rawType = argument.type;
         val ref = Types.typeForClass(rawType);
         val schemaType = typeToSchemaNode.get(ref);
@@ -103,13 +113,13 @@ class BindingMapping {
         return new NodeIdentifierWithPredicates(qname, predicates);
     }
     
-    def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+    private def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
         val ref = Types.typeForClass(argument.type);
         val qname = typeToSchemaNode.get(ref).QName
         return new NodeIdentifier(qname);
     }
 
-    def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+    private def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
         val keyDefinitions = node.keyDefinition;
         val map = new HashMap<QName, Object>();
         for (keydef : keyDefinitions) {
@@ -192,7 +202,7 @@ class BindingMapping {
         return Collections.emptyList();
     }
 
-    def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
+    private def getSimpleValues(DataContainer container, LeafListSchemaNode node) {
         return Collections.emptyList();
     }
 
@@ -226,35 +236,35 @@ class BindingMapping {
         return it;
     }
 
-    private def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
+    public static def dispatch Node<?> getSimpleValue(Object container, QName name, ExtendedType type) {
         getSimpleValue(container, name, type.baseType);
     }
 
-    private def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
+    public static def dispatch Node<?> getSimpleValue(Object container, QName name, StringTypeDefinition type) {
         val value = container.getValue(name, String);
         if(value === null) return null;
         return new SimpleNodeTOImpl(name, null, value);
     }
 
-    private def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
+    public static def dispatch Node<?> getSimpleValue(Object container, QName name, TypeDefinition<?> type) {
         val value = container.getValue(name, Object);
         if(value === null) return null;
         return new SimpleNodeTOImpl(name, null, value);
     }
 
-    private def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
+    public static def dispatch Node<?> getSimpleValue(Object container, QName name, BooleanTypeDefinition type) {
         val value = container.getValue(name, Boolean);
         if(value === null) return null;
         return new SimpleNodeTOImpl(name, null, value);
     }
 
-    private def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
+    public static def dispatch Node<?> getSimpleValue(Object container, QName name, BinaryTypeDefinition type) {
         val Object value = container.getValue(name, Object); //Constants.BYTES_CLASS);
         if(value === null) return null;
         return new SimpleNodeTOImpl(name, null, value);
     }
 
-    private def <T> T getValue(Object object, QName node, Class<T> type) {
+    public static def <T> T getValue(Object object, QName node, Class<T> type) {
         val methodName = BindingGeneratorImpl.getterMethodName(node.localName, Types.typeForClass(type));
         var clz = object.class;
         if (object instanceof DataContainer) {
@@ -274,7 +284,7 @@ class BindingMapping {
         return value.getEncapsulatedValue(type);
     }
 
-    private def <T> T getEncapsulatedValue(Object value, Class<T> type) {
+    public static def <T> T getEncapsulatedValue(Object value, Class<T> type) {
         val method = value.class.getMethod("getValue");
         if (method !== null && type.isAssignableFrom(method.returnType)) {
             return method.invoke(value) as T;
@@ -303,7 +313,7 @@ class BindingMapping {
         return buildMethod.invoke(builder) as DataObject;
     }
 
-    def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+    private def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
         ListSchemaNode schema) {
 
         if (schema.keyDefinition !== null && !schema.keyDefinition.empty) {
@@ -311,14 +321,56 @@ class BindingMapping {
             val value = node.keyToBindingKey(loader, type, schema);
             builder.setProperty("key", value);
         }
+        node.fillBuilderFromContainer(builder,loader,type,schema);
     }
+    
+    
 
-    def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
+    private def dispatch void fillDataObject(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type,
         ContainerSchemaNode schema) {
+        node.fillBuilderFromContainer(builder,loader,type,schema);
     }
 
     
-    def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
+    private def void fillBuilderFromContainer(CompositeNode node, Object builder, ClassLoader loader, GeneratedType type, DataNodeContainer schema) {
+        val Multimap<QName,Node<?>> dataMap = ArrayListMultimap.create();
+        for(child :node.children) {
+            dataMap.put(child.nodeType,node);
+        }
+        for(entry : dataMap.asMap.entrySet) {
+            val entrySchema = schema.getDataChildByName(entry.key);
+            val entryType = type.methodDefinitions.byQName(entry.key);
+            entry.value.addValueToBuilder(builder,loader,entryType,entrySchema);
+        }
+    }
+    
+    private def Type byQName(List<MethodSignature> signatures, QName name) {
+      
+    }
+    
+    private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, LeafSchemaNode container) {
+        
+    }
+    
+    
+    
+    private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, ContainerSchemaNode container) {
+        
+    }
+    
+    
+    private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, ListSchemaNode container) {
+        
+    }
+    
+    private def dispatch addValueToBuilder(Collection<Node<? extends Object>> nodes, Object object, ClassLoader loader, Object object2, LeafListSchemaNode container) {
+        
+    }
+    
+    
+    
+    
+    private def Object keyToBindingKey(CompositeNode node, ClassLoader loader, GeneratedType type, ListSchemaNode schema) {
         val keyClass = loader.loadClass(type.keyFQN);
         val constructor = keyClass.constructors.get(0);
         val keyType = type.keyTypeProperties;
@@ -336,22 +388,22 @@ class BindingMapping {
         return ClassLoaderUtils.construct(constructor, args);
     }
 
-    def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+    private def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
         LeafSchemaNode node2) {
         deserializeSimpleValueImpl(node, loader, type, node2.type);
     }
 
-    def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+    private def dispatch Object deserializeSimpleValue(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
         LeafListSchemaNode node2) {
         deserializeSimpleValueImpl(node, loader, type, node2.type);
     }
 
-    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+    private def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
         ExtendedType definition) {
         deserializeSimpleValueImpl(node, loader, type, definition.baseType);
     }
 
-    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+    private def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
         StringTypeDefinition definition) {
         if (type instanceof GeneratedTransferObject) {
             val cls = loader.getClassForType(type);
@@ -362,16 +414,16 @@ class BindingMapping {
         return node.value;
     }
 
-    def Class<?> getClassForType(ClassLoader loader, Type type) {
+    private def Class<?> getClassForType(ClassLoader loader, Type type) {
         loader.loadClass(type.fullyQualifiedName);
     }
 
-    def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
+    private def dispatch Object deserializeSimpleValueImpl(SimpleNode<? extends Object> node, ClassLoader loader, Type type,
         TypeDefinition definition) {
         throw new UnsupportedOperationException("TODO: auto-generated method stub")
     }
 
-    def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
+    private def Map<String, GeneratedProperty> getKeyTypeProperties(GeneratedType type) {
         val method = FluentIterable.from(type.methodDefinitions).findFirst[name == "getKey"]
         val key = method.returnType as GeneratedTransferObject;
         val ret = new HashMap<String, GeneratedProperty>();
@@ -381,16 +433,16 @@ class BindingMapping {
         return ret;
     }
 
-    def void setProperty(Object object, String property, Object value) {
+    private def void setProperty(Object object, String property, Object value) {
         val cls = object.class;
         val valMethod = cls.getMethod("set" + property.toFirstUpper, value.class);
         if (valMethod != null)
             valMethod.invoke(object, value);
     }
 
-    def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
+    private def String getBuilderFQN(Type type) '''«type.fullyQualifiedName»Builder'''
 
-    def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
+    private def String getKeyFQN(Type type) '''«type.fullyQualifiedName»Key'''
 
 }
 
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CompositeNodeUtils.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/CompositeNodeUtils.java
new file mode 100644 (file)
index 0000000..5d17d92
--- /dev/null
@@ -0,0 +1,5 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom;
+
+public class CompositeNodeUtils {
+
+}
index c96835bd9422c30688235f3d8ae400458a158792..af18e9c0cb184a7d7060fd34e37c674fce1d28c9 100644 (file)
@@ -3,7 +3,10 @@ package org.opendaylight.controller.sal.binding.impl.connect.dom;
 import java.util.Collection;
 import java.util.Collections;
 
+import javassist.ClassPool;
+
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
+import org.opendaylight.controller.sal.binding.dom.serializer.impl.TransformerGenerator;
 import org.opendaylight.controller.sal.core.api.Broker;
 import org.opendaylight.controller.sal.core.api.Provider;
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
@@ -38,10 +41,12 @@ public class ConnectorActivator implements Provider, ServiceTrackerCustomizer<Br
     @Override
     public void onSessionInitiated(ProviderSession session) {
 
-        MappingServiceImpl mappingImpl = new MappingServiceImpl();
-        mappingImpl.setSchemaService(session.getService(SchemaService.class));
+        RuntimeGeneratedMappingServiceImpl mappingImpl = new RuntimeGeneratedMappingServiceImpl();
+        SchemaService schemaService = (session.getService(SchemaService.class));
+        ClassPool pool = new ClassPool();
+        mappingImpl.setBinding(new TransformerGenerator(pool));
         mappingImpl.start();
-
+        schemaService.registerSchemaServiceListener(mappingImpl);
         mappingService = mappingImpl;
         dataConnector = new BindingIndependentDataServiceConnector();
         dataConnector.setBaDataService(baDataService);
diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RuntimeGeneratedMappingServiceImpl.xtend b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/impl/connect/dom/RuntimeGeneratedMappingServiceImpl.xtend
new file mode 100644 (file)
index 0000000..c1efd11
--- /dev/null
@@ -0,0 +1,235 @@
+package org.opendaylight.controller.sal.binding.impl.connect.dom
+
+import org.opendaylight.controller.sal.binding.dom.serializer.impl.TransformerGenerator
+import javassist.ClassPool
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.opendaylight.controller.sal.core.api.model.SchemaServiceListener
+import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl
+import java.util.Map
+import org.opendaylight.yangtools.sal.binding.model.api.Type
+import org.opendaylight.yangtools.sal.binding.model.api.type.builder.GeneratedTypeBuilder
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import java.util.HashMap
+import java.util.concurrent.ConcurrentHashMap
+import org.opendaylight.yangtools.yang.data.api.CompositeNode
+import org.opendaylight.yangtools.yang.binding.DataObject
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier
+import java.util.Map.Entry
+import java.util.AbstractMap.SimpleEntry
+import org.opendaylight.yangtools.yang.model.api.SchemaPath
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil
+import java.util.ArrayList
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.IdentifiableItem
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.binding.generator.util.Types
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.Item
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier
+import org.opendaylight.yangtools.yang.binding.DataContainer
+import static com.google.common.base.Preconditions.*;
+import java.util.List
+import org.opendaylight.yangtools.yang.data.api.Node
+import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
+import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
+import org.opendaylight.yangtools.concepts.Delegator
+import java.util.concurrent.ConcurrentMap
+import org.opendaylight.yangtools.sal.binding.model.api.GeneratedType
+import org.opendaylight.yangtools.yang.binding.BindingCodec
+
+class RuntimeGeneratedMappingServiceImpl implements BindingIndependentMappingService, SchemaServiceListener {
+
+    ClassPool pool;
+
+    @Property
+    extension TransformerGenerator binding;
+    
+    val ConcurrentMap<Type, Type> typeDefinitions = new ConcurrentHashMap();
+
+    val ConcurrentMap<Class<? extends DataContainer>, TransformerWrapper> domSerializers = new ConcurrentHashMap();
+
+    @Property
+    val ConcurrentMap<Type, GeneratedTypeBuilder> typeToDefinition = new ConcurrentHashMap();
+
+    @Property
+    val ConcurrentMap<Type, SchemaNode> typeToSchemaNode = new ConcurrentHashMap();
+
+    override onGlobalContextUpdated(SchemaContext arg0) {
+        recreateBindingContext(arg0);
+    }
+
+    def recreateBindingContext(SchemaContext schemaContext) {
+        val newBinding = new BindingGeneratorImpl();
+        newBinding.generateTypes(schemaContext);
+
+        for (entry : newBinding.moduleContexts.entrySet) {
+
+            //val module = entry.key;
+            val context = entry.value;
+            updateBindingFor(context.childNodes, schemaContext);
+            
+            val typedefs = context.typedefs;
+            for(typedef : typedefs.values) {
+                binding.typeDefinitions.put(typedef,typedef as GeneratedType);
+            }
+        }
+    }
+
+    override CompositeNode toDataDom(DataObject data) {
+        toCompositeNodeImpl(data);
+    }
+
+    override Entry<org.opendaylight.yangtools.yang.data.api.InstanceIdentifier, CompositeNode> toDataDom(
+        Entry<InstanceIdentifier<? extends DataObject>, DataObject> entry) {
+        val key = toDataDomImpl(entry.key);
+        val data = toCompositeNodeImpl(entry.value);
+        return new SimpleEntry(key, data);
+    }
+
+    private def CompositeNode toCompositeNodeImpl(DataObject object) {
+        val cls = object.implementedInterface;
+        val transformator = resolveTransformator(cls);
+        val ret = transformator.transform(object);
+        return ret;
+    }
+
+    private def resolveTransformator(Class<? extends DataContainer> cls) {
+        val serializer = domSerializers.get(cls);
+        if (serializer !== null) {
+            return serializer;
+        }
+        val transformerClass = binding.transformerFor(cls).newInstance;
+        val wrapper = new TransformerWrapper(transformerClass);
+        domSerializers.putIfAbsent(cls, wrapper);
+        return wrapper;
+    }
+
+    private def org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDomImpl(
+        InstanceIdentifier<? extends DataObject> object) {
+        val pathArguments = object.path;
+        var Class<? extends DataObject> parent;
+        val dataDomArgs = new ArrayList<PathArgument>();
+        for (pathArgument : pathArguments) {
+            dataDomArgs.add(pathArgument.toDataDomPathArgument(parent));
+            parent = pathArgument.type;
+        }
+
+        return new org.opendaylight.yangtools.yang.data.api.InstanceIdentifier(dataDomArgs);
+    }
+
+    override org.opendaylight.yangtools.yang.data.api.InstanceIdentifier toDataDom(
+        InstanceIdentifier<? extends DataObject> path) {
+        return toDataDomImpl(path);
+    }
+
+    override dataObjectFromDataDom(InstanceIdentifier<? extends DataObject> path, CompositeNode result) {
+        return dataObjectFromDataDomImpl(path, result);
+    }
+
+    def DataObject dataObjectFromDataDomImpl(InstanceIdentifier<? extends DataObject> identifier, CompositeNode node) {
+        val targetType = identifier.targetType
+        val transformer = resolveTransformator(targetType);
+        val ret = transformer.deserialize(node) as DataObject;
+        return ret;
+    }
+
+    def void updateBindingFor(Map<SchemaPath, GeneratedTypeBuilder> map, SchemaContext module) {
+        for (entry : map.entrySet) {
+            val schemaNode = SchemaContextUtil.findDataSchemaNode(module, entry.key);
+            typeToDefinition.put(entry.value, entry.value);
+            typeToSchemaNode.put(entry.value, schemaNode)
+        }
+    }
+
+    private def dispatch PathArgument toDataDomPathArgument(IdentifiableItem argument,
+        Class<? extends DataObject> parent) {
+        val Class<?> rawType = argument.type;
+        val ref = Types.typeForClass(rawType);
+        val schemaType = typeToSchemaNode.get(ref);
+        val qname = schemaType.QName
+
+        val Object key = argument.key;
+        val predicates = key.toPredicates(schemaType as ListSchemaNode);
+
+        return new NodeIdentifierWithPredicates(qname, predicates);
+    }
+
+    private def Map<QName, Object> toPredicates(Object identifier, ListSchemaNode node) {
+        val keyDefinitions = node.keyDefinition;
+        val map = new HashMap<QName, Object>();
+        for (keydef : keyDefinitions) {
+            val keyNode = node.getDataChildByName(keydef) as LeafSchemaNode;
+            val value = BindingMapping.getSimpleValue(identifier, keydef, keyNode.type);
+            map.put(keydef, value.value);
+        }
+        return map;
+    }
+
+    private def dispatch PathArgument toDataDomPathArgument(Item<?> argument, Class<? extends DataObject> parent) {
+        val ref = Types.typeForClass(argument.type);
+        val qname = typeToSchemaNode.get(ref).QName
+        return new NodeIdentifier(qname);
+    }
+
+    public def void start() {
+        pool = new ClassPool()
+        binding = new TransformerGenerator(pool);
+
+        binding.typeToDefinition = typeToDefinition
+        binding.typeToSchemaNode = typeToSchemaNode
+        binding.typeDefinitions = typeDefinitions
+
+    }
+}
+
+class TransformerWrapper implements // //
+Delegator<BindingCodec<Map<QName, Object>, Object>> {
+
+    @Property
+    val BindingCodec<Map<QName, Object>, Object> delegate;
+
+    new(BindingCodec<Map<QName, Object>, Object> delegate) {
+        _delegate = delegate;
+    }
+
+    def CompositeNode transform(DataObject input) {
+        val ret = delegate.serialize(input);
+        val node = toNode(ret)
+        return node as CompositeNode;
+    }
+
+    def deserialize(CompositeNode node) {
+        if (node === null) {
+            return null;
+        }
+        val Map mapCapture = node
+        return delegate.deserialize(mapCapture as Map<QName,Object>);
+    }
+
+    static def Node<?> toNode(Map map) {
+        val nodeMap = map as Map<QName,Object>;
+        checkArgument(map.size == 1);
+        val elem = nodeMap.entrySet.iterator.next;
+        val qname = elem.key;
+        val value = elem.value;
+        toNodeImpl(qname, value);
+    }
+
+    static def dispatch Node<?> toNodeImpl(QName name, List objects) {
+        val values = new ArrayList<Node<?>>(objects.size);
+        for (obj : objects) {
+            values.add(toNode(obj as Map));
+        }
+        return new CompositeNodeTOImpl(name, null, values);
+    }
+
+    static def dispatch Node<?> toNodeImpl(QName name, Map<QName, Object> object) {
+        throw new UnsupportedOperationException("Unsupported node hierarchy.");
+    }
+
+    static def dispatch Node<?> toNodeImpl(QName name, Object object) {
+        return new SimpleNodeTOImpl(name, null, object);
+    }
+}
index ccf99dfe379681b85e613214bfe996d309a318ad..0b91658a187399758e5e8dac99f884749c0d048e 100644 (file)
@@ -10,8 +10,6 @@ import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 
-import org.opendaylight.yangtools.yang.binding.Identifier;
-
 public class ClassLoaderUtils {
     
     public static <V> V withClassLoader(ClassLoader cls,Callable<V> function) throws Exception {
@@ -33,4 +31,9 @@ public class ClassLoaderUtils {
     Object[] initargs = objects.toArray(new Object[]{});
     return constructor.newInstance(initargs);
     }
+    
+    
+    public static Class<?> loadClassWithTCCL(String name) throws ClassNotFoundException {
+        return Thread.currentThread().getContextClassLoader().loadClass(name);
+    }
 }
\ No newline at end of file
index 0448238665dc0cbb7ea9f31d3f69ee3353b05f9f..0e35ee650e91041a592d6526a186bb9d4580fab3 100644 (file)
@@ -14,7 +14,9 @@ import org.opendaylight.controller.sal.binding.api.data.DataModificationTransact
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.controller.sal.binding.impl.DataBrokerImpl;
 import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentDataServiceConnector;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentMappingService;
 import org.opendaylight.controller.sal.binding.impl.connect.dom.MappingServiceImpl;
+import org.opendaylight.controller.sal.binding.impl.connect.dom.RuntimeGeneratedMappingServiceImpl;
 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
 import org.opendaylight.controller.sal.dom.broker.impl.HashMapDataStore;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
@@ -34,8 +36,8 @@ public class BrokerIntegrationTest {
 
     DataBrokerService biDataService;
     DataProviderService baDataService;
-    private MappingServiceImpl mappingServiceImpl;
-    private MappingServiceImpl mappingService;
+    private RuntimeGeneratedMappingServiceImpl mappingServiceImpl;
+    private BindingIndependentMappingService mappingService;
     private DataBrokerImpl baDataImpl;
     private org.opendaylight.controller.sal.dom.broker.DataBrokerImpl biDataImpl;
     private ListeningExecutorService executor;
@@ -60,9 +62,9 @@ public class BrokerIntegrationTest {
         biDataImpl.registerOperationalReader(treeRoot, dataStore);
         biDataImpl.registerCommitHandler(treeRoot, dataStore);
         
-        mappingServiceImpl = new MappingServiceImpl();
+        mappingServiceImpl = new RuntimeGeneratedMappingServiceImpl();
         mappingService = mappingServiceImpl;
-        
+        mappingServiceImpl.start();
         
         connectorServiceImpl = new BindingIndependentDataServiceConnector();
         connectorServiceImpl.setBaDataService(baDataService);
@@ -73,20 +75,21 @@ public class BrokerIntegrationTest {
         String[] yangFiles = new String[] { "yang-ext.yang", "ietf-inet-types.yang", "ietf-yang-types.yang",
         "node-inventory.yang" };
         
-        mappingService.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+        mappingServiceImpl.onGlobalContextUpdated(MappingServiceTest.getContext(yangFiles));
+        
     }
     
     @Test
     public void simpleModifyOperation() throws Exception {
         
-        DataModificationTransaction transaction = baDataService.beginTransaction();
-        assertNotNull(transaction);
         
         NodeRef node1 = createNodeRef("0");
         DataObject  node = baDataService.readConfigurationData(node1.getValue());
         assertNull(node);
         Node nodeData1 = createNode("0");
         
+        
+        DataModificationTransaction transaction = baDataService.beginTransaction();
         transaction.putConfigurationData(node1.getValue(), nodeData1);
         Future<RpcResult<TransactionStatus>> commitResult = transaction.commit();
         assertNotNull(commitResult);
@@ -102,18 +105,50 @@ public class BrokerIntegrationTest {
         assertEquals(nodeData1.getKey(), readedData.getKey());
         
         
-        DataModificationTransaction transaction2 = baDataService.beginTransaction();
+        NodeRef nodeFoo = createNodeRef("foo");
+        NodeRef nodeBar = createNodeRef("bar");
+        Node nodeFooData = createNode("foo");
+        Node nodeBarData = createNode("bar");
+        
+        
+        DataModificationTransaction insertMoreTr = baDataService.beginTransaction();
+        insertMoreTr.putConfigurationData(nodeFoo.getValue(), nodeFooData);
+        insertMoreTr.putConfigurationData(nodeBar.getValue(), nodeBarData);
+        RpcResult<TransactionStatus> result2 = insertMoreTr.commit().get();
+        
+        assertNotNull(result2);
+        assertNotNull(result2.getResult());
+        assertEquals(TransactionStatus.COMMITED, result.getResult());
+        
+        Nodes allNodes = (Nodes) baDataService.readConfigurationData(InstanceIdentifier.builder().node(Nodes.class).toInstance());
+        assertNotNull(allNodes);
+        assertNotNull(allNodes.getNode());
+        assertEquals(3, allNodes.getNode().size());
+        
+        
+        /**
+         * We create transaction no 2
+         * 
+         */
+        DataModificationTransaction removalTransaction = baDataService.beginTransaction();
         assertNotNull(transaction);
         
-        transaction2.removeConfigurationData(node1.getValue());
+        /**
+         * We remove node 1
+         * 
+         */
+        removalTransaction.removeConfigurationData(node1.getValue());
         
-        Future<RpcResult<TransactionStatus>> commitResult2 = transaction2.commit();
+        /**
+         * We commit transaction
+         */
+        Future<RpcResult<TransactionStatus>> commitResult2 = removalTransaction.commit();
         assertNotNull(commitResult2);
         
-        RpcResult<TransactionStatus> result2 = commitResult2.get();
+        RpcResult<TransactionStatus> result3 = commitResult2.get();
         
-        assertNotNull(result2);
-        assertNotNull(result2.getResult());
+        assertNotNull(result3);
+        assertNotNull(result3.getResult());
         assertEquals(TransactionStatus.COMMITED, result2.getResult());
     
         DataObject readedData2 = baDataService.readConfigurationData(node1.getValue());