From 0ecc684421b03f8eb53cdd042fb3adc40f6732c7 Mon Sep 17 00:00:00 2001 From: Tomas Olvecky Date: Thu, 21 Nov 2013 13:29:09 +0100 Subject: [PATCH] Fix config-netconf-connector needed for interacting with yuma's yangcli. Mitigate issue when yuma is sending services/service/type with a prefix that is not referenced anywhere - it will be ignored. When issuing edit-config with merge strategy, populate services as they appear in get-config. Change-Id: I2c30f3b626fc25cfd3b46225d5f1c24109d655b7 Signed-off-by: Tomas Olvecky --- .../yangjmxgenerator/ModuleMXBeanEntry.java | 6 ++- .../yang/store/api/YangStoreSnapshot.java | 3 +- .../yang/store/impl/ExtenderYangTracker.java | 23 ++++++--- .../store/impl/YangStoreSnapshotImpl.java | 4 ++ .../ObjectNameAttributeResolvingStrategy.java | 10 +++- .../mapping/config/Config.java | 51 ++++++++++++++----- .../mapping/config/InstanceConfig.java | 16 +++--- .../mapping/config/ModuleConfig.java | 5 -- .../mapping/config/Services.java | 10 +++- .../operations/editconfig/EditConfig.java | 17 ++++--- .../editconfig/EditConfigXmlParser.java | 30 ++++++++--- .../editconfig/EditStrategyType.java | 1 + .../operations/editconfig/EditConfigTest.java | 7 ++- 13 files changed, 132 insertions(+), 51 deletions(-) diff --git a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java index 590081072b..fdc573f975 100644 --- a/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java +++ b/opendaylight/config/yang-jmx-generator/src/main/java/org/opendaylight/controller/config/yangjmxgenerator/ModuleMXBeanEntry.java @@ -129,7 +129,7 @@ public class ModuleMXBeanEntry extends AbstractEntry { private final String nullableDescription, packageName, javaNamePrefix, namespace; - private final Map providedServices; + private final Map providedServices; private Collection runtimeBeans; @@ -180,6 +180,10 @@ public class ModuleMXBeanEntry extends AbstractEntry { return packageName; } + /** + * @return services implemented by this module. Keys are fully qualified java names of generated + * ServiceInterface classes, values are identity local names. + */ public Map getProvidedServices() { return providedServices; } diff --git a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java index 40daf4018a..da8b5e4ed1 100644 --- a/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java +++ b/opendaylight/config/yang-store-api/src/main/java/org/opendaylight/controller/config/yang/store/api/YangStoreSnapshot.java @@ -15,7 +15,8 @@ import org.opendaylight.yangtools.yang.model.api.Module; public interface YangStoreSnapshot extends AutoCloseable { - Map> getModuleMXBeanEntryMap(); + Map> getModuleMXBeanEntryMap(); Map> getModuleMap(); diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java index 90b94ef120..fcdc10f109 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/ExtenderYangTracker.java @@ -78,7 +78,7 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt } @Override - public Object addingBundle(Bundle bundle, BundleEvent event) { + public synchronized Object addingBundle(Bundle bundle, BundleEvent event) { // Ignore system bundle: // system bundle might have config-api on classpath && @@ -121,7 +121,7 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt return bundle; } - private void onSnapshotFailure(Bundle bundle, List addedURLs, Exception failureReason) { + private synchronized void onSnapshotFailure(Bundle bundle, List addedURLs, Exception failureReason) { // inconsistent state inconsistentBundlesToYangURLs.putAll(bundle, addedURLs); @@ -129,9 +129,10 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt consistentBundlesToYangURLs, inconsistentBundlesToYangURLs, failureReason); logger.warn("Yang store is falling back on last consistent state containing {} files, inconsistent yang files size is {}, reason {}", consistentBundlesToYangURLs.size(), inconsistentBundlesToYangURLs.size(), failureReason.toString()); + cache.setInconsistentURLsForReporting(inconsistentBundlesToYangURLs.values()); } - private void onSnapshotSuccess(Multimap proposedNewState, YangStoreSnapshotImpl snapshot) { + private synchronized void onSnapshotSuccess(Multimap proposedNewState, YangStoreSnapshotImpl snapshot) { // consistent state // merge into consistentBundlesToYangURLs.clear(); @@ -139,12 +140,12 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt inconsistentBundlesToYangURLs.clear(); updateCache(snapshot); - + cache.setInconsistentURLsForReporting(Collections. emptySet()); logger.info("Yang store updated to new consistent state containing {} yang files", consistentBundlesToYangURLs.size()); logger.debug("Yang store updated to new consistent state containing {}", consistentBundlesToYangURLs); } - private void updateCache(YangStoreSnapshotImpl snapshot) { + private synchronized void updateCache(YangStoreSnapshotImpl snapshot) { cache.cacheYangStore(consistentBundlesToYangURLs, snapshot); } @@ -213,11 +214,14 @@ public class ExtenderYangTracker extends BundleTracker implements YangSt } class YangStoreCache { + private static final Logger logger = LoggerFactory.getLogger(YangStoreCache.class); @GuardedBy("this") private Set cachedUrls = null; @GuardedBy("this") private Optional cachedYangStoreSnapshot = getInitialSnapshot(); + @GuardedBy("this") + private Collection inconsistentURLsForReporting = Collections.emptySet(); synchronized Optional getSnapshotIfPossible(Multimap bundlesToYangURLs) { Set urls = setFromMultimapValues(bundlesToYangURLs); @@ -225,6 +229,9 @@ class YangStoreCache { if (cachedUrls==null || cachedUrls.equals(urls)) { Preconditions.checkState(cachedYangStoreSnapshot.isPresent()); YangStoreSnapshot freshSnapshot = new YangStoreSnapshotImpl(cachedYangStoreSnapshot.get()); + if (inconsistentURLsForReporting.size() > 0){ + logger.warn("Some yang URLs are ignored: {}", inconsistentURLsForReporting); + } return Optional.of(freshSnapshot); } @@ -239,7 +246,7 @@ class YangStoreCache { } synchronized void cacheYangStore(Multimap urls, - YangStoreSnapshot yangStoreSnapshot) { + YangStoreSnapshot yangStoreSnapshot) { this.cachedUrls = setFromMultimapValues(urls); this.cachedYangStoreSnapshot = Optional.of(yangStoreSnapshot); } @@ -252,6 +259,10 @@ class YangStoreCache { } } + public synchronized void setInconsistentURLsForReporting(Collection urls){ + inconsistentURLsForReporting = urls; + } + private Optional getInitialSnapshot() { YangStoreSnapshot initialSnapshot = new YangStoreSnapshot() { @Override diff --git a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java index d5936c28ae..ea709e1a45 100644 --- a/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java +++ b/opendaylight/config/yang-store-impl/src/main/java/org/opendaylight/controller/config/yang/store/impl/YangStoreSnapshotImpl.java @@ -34,6 +34,10 @@ public class YangStoreSnapshotImpl implements YangStoreSnapshot { this.moduleMap = yangStoreSnapshot.getModuleMap(); } + /** + * @return all loaded config modules. Key of outer map is namespace of yang file. + * Key of inner map is name of module entry. Value is module entry. + */ @Override public Map> getModuleMXBeanEntryMap() { return moduleMXBeanEntryMap; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java index 5469015a23..af6e3db8e9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/resolving/ObjectNameAttributeResolvingStrategy.java @@ -39,8 +39,14 @@ public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResol Util.checkType(value, ObjectNameAttributeMappingStrategy.MappedDependency.class); ObjectNameAttributeMappingStrategy.MappedDependency mappedDep = (ObjectNameAttributeMappingStrategy.MappedDependency) value; - ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(mappedDep.getServiceName(), - mappedDep.getRefName()); + String serviceName = mappedDep.getServiceName(); + if (serviceName.contains(":")) { + // hack for yuma + serviceName = serviceName.substring(serviceName.indexOf(":") + 1); + } + String refName = mappedDep.getRefName(); + logger.trace("Getting service instance by service name {} and ref name {}", serviceName, refName); + ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(serviceName, refName); ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName()); logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType()); return Optional.of(on); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java index 8c7621a24b..ca849c71cf 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Config.java @@ -8,13 +8,6 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.HashMultimap; @@ -25,20 +18,37 @@ import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import javax.management.ObjectName; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; import static com.google.common.base.Preconditions.checkState; import static java.lang.String.format; public class Config { + private final Logger logger = LoggerFactory.getLogger(Config.class); - private final Map> moduleConfigs; + private final Map> moduleConfigs; + private final Map moduleNamesToConfigs; public Config(Map> moduleConfigs) { this.moduleConfigs = moduleConfigs; + Map moduleNamesToConfigs = new HashMap<>(); + for (Entry> entry : moduleConfigs.entrySet()) { + moduleNamesToConfigs.putAll(entry.getValue()); + } + this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs); } private Map>> getMappedInstances(Set instancesToMap, @@ -64,7 +74,7 @@ public class Config { // All found instances add to service tracker in advance // This way all instances will be serialized as all available // services when get-config is triggered - // (even if they are not used as services by other onstances) + // (even if they are not used as services by other instances) // = more user friendly addServices(serviceTracker, instances, mbeEntry.getValue().getProvidedServices()); @@ -152,12 +162,12 @@ public class Config { // TODO refactor, replace string representing namespace with namespace class // TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved // class - public Map> fromXml(XmlElement xml) { + public Map> fromXml(XmlElement xml, Set instancesForFillingServiceRefMapping) { Map> retVal = Maps.newHashMap(); List recognisedChildren = Lists.newArrayList(); - Services serviceTracker = fromXmlServices(xml, recognisedChildren); + Services serviceTracker = fromXmlServices(xml, recognisedChildren, instancesForFillingServiceRefMapping); List moduleElements = fromXmlModules(xml, recognisedChildren); xml.checkUnrecognisedElements(recognisedChildren); @@ -208,7 +218,7 @@ public class Config { innerMap.put(factoryName, moduleElementResolved); } - private Services fromXmlServices(XmlElement xml, List recognisedChildren) { + private Services fromXmlServices(XmlElement xml, List recognisedChildren, Set instancesForFillingServiceRefMapping) { Optional servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); @@ -219,8 +229,23 @@ public class Config { } else { mappedServices = new HashMap<>(); } + Services services = Services.resolveServices(mappedServices); + // merge with what candidate db contains by default - ref_ + + for(ObjectName existingON: instancesForFillingServiceRefMapping) { + logger.trace("Filling services from {}", existingON); + // get all its services + String factoryName = ObjectNameUtil.getFactoryName(existingON); + ModuleConfig moduleConfig = moduleNamesToConfigs.get(factoryName); + + checkState(moduleConfig != null, "Cannot find ModuleConfig with name " + factoryName + " in " + moduleNamesToConfigs); + // Set services = ; + for (String serviceName : moduleConfig.getProvidedServices()) { + services.addServiceEntry(serviceName, existingON); + } + } - return Services.resolveServices(mappedServices); + return services; } private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java index d1ba0b0206..549d94bdf2 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfig.java @@ -109,17 +109,19 @@ public final class InstanceConfig { depTracker).prepareResolving(yangToAttrConfig); for (Entry configDefEntry : mappedConfig.getConfiguration().entrySet()) { + AttributeConfigElement value = configDefEntry.getValue(); + String attributeName = configDefEntry.getKey(); try { - AttributeResolvingStrategy> attributeResolvingStrategy = resolvingStrategies - .get(configDefEntry.getKey()); + .get(attributeName); + logger.trace("Trying to set value {} of attribute {} with {}", value, attributeName, attributeResolvingStrategy); - configDefEntry.getValue().resolveValue(attributeResolvingStrategy, configDefEntry.getKey()); - configDefEntry.getValue().setJmxName( - yangToAttrConfig.get(configDefEntry.getKey()).getUpperCaseCammelCase()); + value.resolveValue(attributeResolvingStrategy, attributeName); + value.setJmxName( + yangToAttrConfig.get(attributeName).getUpperCaseCammelCase()); } catch (Exception e) { - throw new IllegalStateException("Unable to resolve value " + configDefEntry.getValue() - + " to attribute " + configDefEntry.getKey(), e); + throw new IllegalStateException("Unable to resolve value " + value + + " to attribute " + attributeName, e); } } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index 3a0c54754b..264c9c11da 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -17,7 +17,6 @@ import org.w3c.dom.Element; import javax.management.ObjectName; import java.util.Collection; -import java.util.Collections; public class ModuleConfig { @@ -31,10 +30,6 @@ public class ModuleConfig { this.providedServices = providedServices; } - public ModuleConfig(String key, InstanceConfig instanceConfig) { - this(key, instanceConfig, Collections. emptyList()); - } - public InstanceConfig getMbeanMapping() { return instanceConfig; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index 7e4b6c2c06..883dde7564 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -8,6 +8,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; +import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Function; import com.google.common.base.Preconditions; import com.google.common.collect.Maps; @@ -15,6 +16,8 @@ import com.google.common.collect.Sets; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -29,6 +32,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public final class Services { + private static final Logger logger = LoggerFactory.getLogger(Services.class); private static final String PROVIDER_KEY = "provider"; private static final String NAME_KEY = "name"; @@ -46,9 +50,13 @@ public final class Services { String moduleName = on.getKeyProperty("moduleFactoryName"); String instanceName = on.getKeyProperty("instanceName"); - return addServiceEntry(serviceName, moduleName, instanceName); + String refName = addServiceEntry(serviceName, moduleName, instanceName); + logger.trace("Added service entry to tracker. Service name {}, ref name {}, module name {}, instance name {}", + serviceName, refName, moduleName, instanceName); + return refName; } + @VisibleForTesting public String addServiceEntry(String serviceName, String moduleName, String instanceName) { ServiceInstance serviceInstance = new ServiceInstance(moduleName, instanceName); serviceInstance.setServiceName(serviceName); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java index be3b01db5d..d04fdbcc43 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfig.java @@ -147,14 +147,17 @@ public class EditConfig extends AbstractConfigNetconfOperation { } public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { + Map> mBeanEntries) { Map> factories = transform(configRegistryClient, mBeanEntries); return new Config(factories); } // TODO refactor - private static Map> transform(final ConfigRegistryClient configRegistryClient, - Map> mBeanEntries) { + private static Map> transform + (final ConfigRegistryClient configRegistryClient, Map> mBeanEntries) { return Maps.transformEntries(mBeanEntries, new Maps.EntryTransformer, Map>() { @@ -164,9 +167,9 @@ public class EditConfig extends AbstractConfigNetconfOperation { new Maps.EntryTransformer() { @Override - public ModuleConfig transformEntry(String key, ModuleMXBeanEntry value) { - return new ModuleConfig(key, new InstanceConfig(configRegistryClient, value - .getAttributes())); + public ModuleConfig transformEntry(String key, ModuleMXBeanEntry moduleMXBeanEntry) { + return new ModuleConfig(key, new InstanceConfig(configRegistryClient, moduleMXBeanEntry + .getAttributes()), moduleMXBeanEntry.getProvidedServices().values()); } }); } @@ -184,7 +187,7 @@ public class EditConfig extends AbstractConfigNetconfOperation { EditConfigXmlParser.EditConfigExecution editConfigExecution; Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap()); try { - editConfigExecution = editConfigXmlParser.fromXml(xml, cfg); + editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient); } catch (IllegalStateException e) { logger.warn("Error parsing xml", e); final Map errorInfo = new HashMap<>(); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java index d835dfd30f..db82aa66fc 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigXmlParser.java @@ -12,17 +12,22 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; +import org.opendaylight.controller.config.util.ConfigRegistryClient; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore; +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.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.management.ObjectName; import java.util.Arrays; +import java.util.Collections; import java.util.Map; +import java.util.Set; public class EditConfigXmlParser { @@ -38,7 +43,8 @@ public class EditConfigXmlParser { public EditConfigXmlParser() { } - EditConfigXmlParser.EditConfigExecution fromXml(final XmlElement xml, final Config cfgMapping) + EditConfigXmlParser.EditConfigExecution fromXml(final XmlElement xml, final Config cfgMapping, + TransactionProvider transactionProvider, ConfigRegistryClient configRegistryClient) throws NetconfDocumentedException { EditStrategyType.resetDefaultStrategy(); @@ -81,12 +87,24 @@ public class EditConfigXmlParser { // Default op Optional defaultContent = xml .getOnlyChildElementWithSameNamespaceOptionally(EditConfigXmlParser.DEFAULT_OPERATION_KEY); - if (defaultContent.isPresent()) - EditStrategyType.setDefaultStrategy(EditStrategyType.valueOf(defaultContent.get().getTextContent())); + if (defaultContent.isPresent()) { + String mergeStrategyString = defaultContent.get().getTextContent(); + logger.trace("Setting merge strategy to {}", mergeStrategyString); + EditStrategyType editStrategyType = EditStrategyType.valueOf(mergeStrategyString); + // FIXME: thread safety, remove global state + EditStrategyType.setDefaultStrategy(editStrategyType); + } + // FIXME: thread safety, remove global state + Set instancesForFillingServiceRefMapping = Collections.emptySet(); + if (EditStrategyType.defaultStrategy() == EditStrategyType.merge) { + instancesForFillingServiceRefMapping = Datastore.getInstanceQueryStrategy(targetDatastore, transactionProvider) + .queryInstances(configRegistryClient); + logger.trace("Pre-filling services from following instances: {}", instancesForFillingServiceRefMapping); + } XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY); - return new EditConfigXmlParser.EditConfigExecution(xml, cfgMapping, configElement, testOption); + return new EditConfigXmlParser.EditConfigExecution(xml, cfgMapping, configElement, testOption, instancesForFillingServiceRefMapping); } private void removeMountpointsFromConfig(XmlElement configElement, XmlElement mountpointsElement) { @@ -123,9 +141,9 @@ public class EditConfigXmlParser { Map> resolvedXmlElements; TestOption testOption; - EditConfigExecution(XmlElement xml, Config configResolver, XmlElement configElement, TestOption testOption) { + EditConfigExecution(XmlElement xml, Config configResolver, XmlElement configElement, TestOption testOption, Set instancesForFillingServiceRefMapping) { this.editConfigXml = xml; - this.resolvedXmlElements = configResolver.fromXml(configElement); + this.resolvedXmlElements = configResolver.fromXml(configElement, instancesForFillingServiceRefMapping); this.testOption = testOption; } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java index a7a0518cc5..707baab93b 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditStrategyType.java @@ -13,6 +13,7 @@ import java.util.Set; import com.google.common.base.Preconditions; +//FIXME: make thread safe public enum EditStrategyType { // can be default merge, replace, none, diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java index 123c03e9a1..c8f83c8876 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/editconfig/EditConfigTest.java @@ -31,7 +31,9 @@ import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlUtil; import javax.management.ObjectName; +import java.util.Collections; import java.util.Map; +import java.util.Set; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyMap; @@ -86,10 +88,11 @@ public class EditConfigTest { Config cfg = mock(Config.class); XmlElement xmlElement = mock(XmlElement.class); - doReturn(resolvedXmlElements).when(cfg).fromXml(xmlElement); + Set instancesForFillingServiceRefMapping = Collections.emptySet(); + doReturn(resolvedXmlElements).when(cfg).fromXml(xmlElement, instancesForFillingServiceRefMapping); EditConfigExecution editConfigExecution = new EditConfigExecution(null, cfg, xmlElement, - EditConfigXmlParser.TestOption.testThenSet); + EditConfigXmlParser.TestOption.testThenSet, instancesForFillingServiceRefMapping); edit.getResponseInternal(XmlUtil.newDocument(), editConfigExecution); -- 2.36.6