From: Ed Warnicke Date: Mon, 25 Nov 2013 09:42:21 +0000 (+0000) Subject: Merge changes Ia09a1107,I2c30f3b6 X-Git-Tag: jenkins-controller-bulk-release-prepare-only-2-1~352 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=dfe4a744e9b2ebbbd06e3e91b6100258c2744983;hp=585bee2f6dd169168e3fba2d357534d4fd3bfdd5 Merge changes Ia09a1107,I2c30f3b6 * changes: Change type of service-ref grouping to service-type-ref from leafref. Fix config-netconf-connector needed for interacting with yuma's yangcli. --- diff --git a/opendaylight/config/config-api/src/main/resources/META-INF/yang/config.yang b/opendaylight/config/config-api/src/main/resources/META-INF/yang/config.yang index 5d6c11fbee..a0a4292adf 100644 --- a/opendaylight/config/config-api/src/main/resources/META-INF/yang/config.yang +++ b/opendaylight/config/config-api/src/main/resources/META-INF/yang/config.yang @@ -122,9 +122,7 @@ module config { the actual service-type which is actually required."; mandatory true; - type leafref { - path "/config:services/config:service/config:type"; - } + type service-type-ref; } leaf name { 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..115fc2ccb6 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; @@ -22,23 +15,41 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Multimap; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; 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 +75,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,18 +163,19 @@ 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, + EditStrategyType defaultEditStrategyType) { 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); for (XmlElement moduleElement : moduleElements) { - resolveModule(retVal, serviceTracker, moduleElement); + resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType); } return retVal; @@ -184,7 +196,7 @@ public class Config { } private void resolveModule(Map> retVal, Services serviceTracker, - XmlElement moduleElement) { + XmlElement moduleElement, EditStrategyType defaultStrategy) { XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY); Entry prefixToNamespace = typeElement.findNamespaceOfTextContent(); String moduleNamespace = prefixToNamespace.getValue(); @@ -203,12 +215,12 @@ public class Config { } ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker, - instanceName, moduleNamespace); + instanceName, moduleNamespace, defaultStrategy); 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 +231,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..33858746cb 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 @@ -24,6 +24,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attrib import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.AttributeWritingStrategy; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.slf4j.Logger; @@ -109,22 +110,25 @@ 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); } } } - public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace) { + public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace, + EditStrategyType defaultStrategy) { Map retVal = Maps.newHashMap(); Map strats = new ObjectXmlReader().prepareReading(yangToAttrConfig); @@ -149,7 +153,7 @@ public final class InstanceConfig { XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); InstanceConfigElementResolved instanceConfigElementResolved = perInstanceEditStrategy.equals("") ? new InstanceConfigElementResolved( - retVal) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal); + retVal, defaultStrategy) : new InstanceConfigElementResolved(perInstanceEditStrategy, retVal, defaultStrategy); resolveConfiguration(instanceConfigElementResolved, services); return instanceConfigElementResolved; diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java index 6624fc182e..e4bd9212e9 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/InstanceConfigElementResolved.java @@ -25,20 +25,26 @@ public class InstanceConfigElementResolved { private final EditStrategyType editStrategy; private final Map configuration; - public InstanceConfigElementResolved(String strat, Map configuration) { - EditStrategyType valueOf = checkStrategy(strat); + public InstanceConfigElementResolved(String currentStrategy, Map configuration, EditStrategyType defaultStrategy) { + EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy); this.editStrategy = valueOf; this.configuration = configuration; } - EditStrategyType checkStrategy(String strat) { - EditStrategyType valueOf = EditStrategyType.valueOf(strat); - if (EditStrategyType.defaultStrategy().isEnforcing()) { + public InstanceConfigElementResolved(Map configuration, EditStrategyType defaultStrategy) { + editStrategy = defaultStrategy; + this.configuration = configuration; + } + + + EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) { + EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy); + if (defaultStrategy.isEnforcing()) { Preconditions .checkArgument( - valueOf == EditStrategyType.defaultStrategy(), + valueOf == defaultStrategy, "With " - + EditStrategyType.defaultStrategy() + + defaultStrategy + " as " + EditConfigXmlParser.DEFAULT_OPERATION_KEY + " operations on module elements are not permitted since the default option is restrictive"); @@ -46,10 +52,6 @@ public class InstanceConfigElementResolved { return valueOf; } - public InstanceConfigElementResolved(Map configuration) { - editStrategy = EditStrategyType.defaultStrategy(); - this.configuration = configuration; - } public EditConfigStrategy getEditStrategy() { return editStrategy.getFittingStrategy(); 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..991a5637e1 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 @@ -9,6 +9,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config; import org.opendaylight.controller.config.api.jmx.ObjectNameUtil; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; import org.opendaylight.controller.netconf.util.xml.XmlUtil; @@ -17,7 +18,6 @@ import org.w3c.dom.Element; import javax.management.ObjectName; import java.util.Collection; -import java.util.Collections; public class ModuleConfig { @@ -31,10 +31,6 @@ public class ModuleConfig { this.providedServices = providedServices; } - public ModuleConfig(String key, InstanceConfig instanceConfig) { - this(key, instanceConfig, Collections. emptyList()); - } - public InstanceConfig getMbeanMapping() { return instanceConfig; } @@ -75,9 +71,9 @@ public class ModuleConfig { } public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName, - String moduleNamespace) { + String moduleNamespace, EditStrategyType defaultStrategy) { - InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace); + InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy); return new ModuleElementResolved(instanceName, ice); } 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..362f023283 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 @@ -27,6 +27,7 @@ import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig; import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; +import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution; import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider; import org.opendaylight.controller.netconf.util.xml.XmlElement; import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants; @@ -88,9 +89,9 @@ public class EditConfig extends AbstractConfigNetconfOperation { } private void executeTests(ConfigRegistryClient configRegistryClient, - EditConfigXmlParser.EditConfigExecution editConfigExecution) throws NetconfDocumentedException { + EditConfigExecution editConfigExecution) throws NetconfDocumentedException { try { - test(configRegistryClient, editConfigExecution.resolvedXmlElements); + test(configRegistryClient, editConfigExecution.getResolvedXmlElements(), editConfigExecution.getDefaultStrategy()); } catch (IllegalStateException | JmxAttributeValidationException | ValidationException e) { logger.warn("Test phase for {} failed", EditConfigXmlParser.EDIT_CONFIG, e); final Map errorInfo = new HashMap<>(); @@ -102,12 +103,12 @@ public class EditConfig extends AbstractConfigNetconfOperation { } private void test(ConfigRegistryClient configRegistryClient, - Map> resolvedModules) { + Map> resolvedModules, EditStrategyType editStrategyType) { ObjectName taON = transactionProvider.getTestTransaction(); try { // default strategy = replace wipes config - if (EditStrategyType.defaultStrategy() == EditStrategyType.replace) { + if (editStrategyType == EditStrategyType.replace) { transactionProvider.wipeTestTransaction(taON); } setOnTransaction(configRegistryClient, resolvedModules, taON); @@ -122,10 +123,10 @@ public class EditConfig extends AbstractConfigNetconfOperation { ObjectName taON = transactionProvider.getOrCreateTransaction(); // default strategy = replace wipes config - if (EditStrategyType.defaultStrategy() == EditStrategyType.replace) { + if (editConfigExecution.getDefaultStrategy() == EditStrategyType.replace) { transactionProvider.wipeTransaction(); } - setOnTransaction(configRegistryClient, editConfigExecution.resolvedXmlElements, taON); + setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(), taON); } private void setOnTransaction(ConfigRegistryClient configRegistryClient, @@ -147,14 +148,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 +168,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 +188,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..3d4e5b6d0c 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,10 +43,11 @@ 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(); + EditStrategyType editStrategyType = EditStrategyType.getDefaultStrategy(); xml.checkName(EditConfigXmlParser.EDIT_CONFIG); xml.checkNamespace(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0); @@ -81,12 +87,22 @@ 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.valueOf(mergeStrategyString); + } + Set instancesForFillingServiceRefMapping = Collections.emptySet(); + if (editStrategyType == 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, editStrategyType); } private void removeMountpointsFromConfig(XmlElement configElement, XmlElement mountpointsElement) { @@ -119,14 +135,17 @@ public class EditConfigXmlParser { @VisibleForTesting static class EditConfigExecution { - XmlElement editConfigXml; - Map> resolvedXmlElements; - TestOption testOption; + private final XmlElement editConfigXml; + private final Map> resolvedXmlElements; + private final TestOption testOption; + private final EditStrategyType defaultEditStrategyType; - EditConfigExecution(XmlElement xml, Config configResolver, XmlElement configElement, TestOption testOption) { + EditConfigExecution(XmlElement xml, Config configResolver, XmlElement configElement, TestOption testOption, Set instancesForFillingServiceRefMapping, + EditStrategyType defaultStrategy) { this.editConfigXml = xml; - this.resolvedXmlElements = configResolver.fromXml(configElement); + this.resolvedXmlElements = configResolver.fromXml(configElement, instancesForFillingServiceRefMapping, defaultStrategy); this.testOption = testOption; + this.defaultEditStrategyType = defaultStrategy; } boolean shouldTest() { @@ -136,5 +155,13 @@ public class EditConfigXmlParser { boolean shouldSet() { return testOption == TestOption.set || testOption == TestOption.testThenSet; } + + Map> getResolvedXmlElements() { + return resolvedXmlElements; + } + + EditStrategyType getDefaultStrategy() { + return defaultEditStrategyType; + } } } 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..cb03342a1e 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 @@ -11,8 +11,7 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ed import java.util.EnumSet; import java.util.Set; -import com.google.common.base.Preconditions; - +//FIXME: make thread safe public enum EditStrategyType { // can be default merge, replace, none, @@ -21,20 +20,8 @@ public enum EditStrategyType { private static final Set defaultStrats = EnumSet.of(merge, replace, none); - private static EditStrategyType defaultStrat = merge; - - public static EditStrategyType defaultStrategy() { - return defaultStrat; - } - - public static void setDefaultStrategy(EditStrategyType strat) { - Preconditions.checkArgument(strat.canBeDefault(), "Default edit strategy can be only of value " + defaultStrats - + ", but was " + strat); - defaultStrat = strat; - } - - public static void resetDefaultStrategy() { - setDefaultStrategy(EditStrategyType.merge); + public static EditStrategyType getDefaultStrategy() { + return merge; } public boolean isEnforcing() { @@ -53,16 +40,6 @@ public enum EditStrategyType { } } - private static final EnumSet defaults; - - static { - defaults = EnumSet.of(merge, replace, none); - } - - private boolean canBeDefault() { - return defaults.contains(this); - } - public EditConfigStrategy getFittingStrategy() { switch (this) { case merge: 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..1b8e24702a 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,12 @@ public class EditConfigTest { Config cfg = mock(Config.class); XmlElement xmlElement = mock(XmlElement.class); - doReturn(resolvedXmlElements).when(cfg).fromXml(xmlElement); + Set instancesForFillingServiceRefMapping = Collections.emptySet(); + EditStrategyType defaultStrategy = EditStrategyType.getDefaultStrategy(); + doReturn(resolvedXmlElements).when(cfg).fromXml(xmlElement, instancesForFillingServiceRefMapping, defaultStrategy); EditConfigExecution editConfigExecution = new EditConfigExecution(null, cfg, xmlElement, - EditConfigXmlParser.TestOption.testThenSet); + EditConfigXmlParser.TestOption.testThenSet, instancesForFillingServiceRefMapping, defaultStrategy); edit.getResponseInternal(XmlUtil.newDocument(), editConfigExecution);