Merge "Take advantage of MultipartTransactionAware"
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / operations / editconfig / EditConfig.java
index 709573c2414c3249917aae4e03851e0f9ada4da8..bb19dc207ed3238156fd366f3c2ca837175ab204 100644 (file)
@@ -8,10 +8,15 @@
 
 package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.JmxAttributeValidationException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+
 import org.opendaylight.controller.config.api.ValidationException;
 import org.opendaylight.controller.config.util.ConfigRegistryClient;
 import org.opendaylight.controller.config.util.ConfigTransactionClient;
@@ -33,16 +38,17 @@ import org.opendaylight.controller.netconf.confignetconfconnector.operations.edi
 import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
 import org.opendaylight.controller.netconf.util.xml.XmlElement;
 import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 
 public class EditConfig extends AbstractConfigNetconfOperation {
 
@@ -73,7 +79,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             executeSet(configRegistryClient, editConfigExecution);
         }
 
-        logger.info("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
+        logger.trace("Operation {} successful", EditConfigXmlParser.EDIT_CONFIG);
 
         return document.createElement(XmlNetconfConstants.OK);
     }
@@ -82,7 +88,11 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
         try {
             set(configRegistryClient, editConfigExecution);
-        } catch (IllegalStateException | JmxAttributeValidationException | ValidationException e) {
+
+        } catch (IllegalStateException e) {
+            //FIXME: when can IllegalStateException be thrown?
+            // JmxAttributeValidationException is wrapped in DynamicWritableWrapper with ValidationException
+            // ValidationException is not thrown until validate or commit is issued
             logger.warn("Set phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
             final Map<String, String> errorInfo = new HashMap<>();
             errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
@@ -96,7 +106,8 @@ public class EditConfig extends AbstractConfigNetconfOperation {
             EditConfigExecution editConfigExecution) throws NetconfDocumentedException {
         try {
             test(configRegistryClient, editConfigExecution, editConfigExecution.getDefaultStrategy());
-        } catch (IllegalStateException | JmxAttributeValidationException | ValidationException e) {
+        } catch (IllegalStateException | ValidationException e) {
+            //FIXME: when can IllegalStateException be thrown?
             logger.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e);
             final Map<String, String> errorInfo = new HashMap<>();
             errorInfo.put(ErrorTag.operation_failed.name(), e.getMessage());
@@ -107,7 +118,7 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     }
 
     private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
-            EditStrategyType editStrategyType) {
+            EditStrategyType editStrategyType) throws ValidationException {
         ObjectName taON = transactionProvider.getTestTransaction();
         try {
 
@@ -207,12 +218,65 @@ public class EditConfig extends AbstractConfigNetconfOperation {
         }
     }
 
-    public static Config getConfigMapping(ConfigRegistryClient configRegistryClient,
-            Map<String/* Namespace from yang file */,
-                    Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
-        Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries);
+    public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, YangStoreSnapshot yangStoreSnapshot) {
+        Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient,
+                yangStoreSnapshot.getModuleMXBeanEntryMap());
+        Map<String, Map<Date, IdentityMapping>> identitiesMap = transformIdentities(yangStoreSnapshot.getModules());
+        return new Config(factories, identitiesMap);
+    }
 
-        return new Config(factories);
+
+    public static class IdentityMapping {
+        private final Map<String, IdentitySchemaNode> identityNameToSchemaNode;
+
+        IdentityMapping() {
+            this.identityNameToSchemaNode = Maps.newHashMap();
+        }
+
+        void addIdSchemaNode(IdentitySchemaNode node) {
+            String name = node.getQName().getLocalName();
+            Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false);
+            identityNameToSchemaNode.put(name, node);
+        }
+
+        public boolean containsIdName(String idName) {
+            return identityNameToSchemaNode.containsKey(idName);
+        }
+
+        // FIXME method never used
+        public IdentitySchemaNode getIdentitySchemaNode(String idName) {
+            Preconditions.checkState(identityNameToSchemaNode.containsKey(idName), "No identity under name %s", idName);
+            return identityNameToSchemaNode.get(idName);
+        }
+    }
+
+    private static Map<String, Map<Date, IdentityMapping>> transformIdentities(Set<Module> modules) {
+        Map<String, Map<Date, IdentityMapping>> mappedIds = Maps.newHashMap();
+        for (Module module : modules) {
+            String namespace = module.getNamespace().toString();
+            Map<Date, IdentityMapping> revisionsByNamespace= mappedIds.get(namespace);
+            if(revisionsByNamespace == null) {
+                revisionsByNamespace = Maps.newHashMap();
+                mappedIds.put(namespace, revisionsByNamespace);
+            }
+
+            Date revision = module.getRevision();
+            Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false,
+                    "Duplicate revision %s for namespace %s", revision, namespace);
+
+            IdentityMapping identityMapping = revisionsByNamespace.get(revision);
+            if(identityMapping == null) {
+                identityMapping = new IdentityMapping();
+                revisionsByNamespace.put(revision, identityMapping);
+            }
+
+            for (IdentitySchemaNode identitySchemaNode : module.getIdentities()) {
+                identityMapping.addIdSchemaNode(identitySchemaNode);
+            }
+
+        }
+
+        return mappedIds;
     }
 
     public static Map<String/* Namespace from yang file */,
@@ -250,10 +314,10 @@ public class EditConfig extends AbstractConfigNetconfOperation {
     }
 
     @Override
-    protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
+    protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException {
 
         EditConfigXmlParser.EditConfigExecution editConfigExecution;
-        Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
+        Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot);
         try {
             editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient);
         } catch (IllegalStateException e) {
@@ -278,4 +342,5 @@ public class EditConfig extends AbstractConfigNetconfOperation {
 
         return getResponseInternal(document, editConfigExecution);
     }
+
 }