Utilize new proxy service mbeans that store reference name for dependency attributes.
Change-Id: Ia6652643eefc545bc546902de6f3786fe91d63a5
Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
+++ /dev/null
-/*
- * 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.netconf.confignetconfconnector.mapping.attributes;
-
-public class AttributesConstants {
-
- /**
- * Property placed into object names for dependencies to preserve reference name
- */
- public static final String REF_NAME_ON_PROPERTY_KEY = "X-refName";
-}
resolvedValue = attributeResolvingStrategy.parseAttribute(attrName, value);
Optional<?> resolvedDefault = attributeResolvingStrategy.parseAttribute(attrName, dafaultValue);
resolvedDefaultValue = resolvedDefault.isPresent() ? resolvedDefault.get() : null;
-
}
public static AttributeConfigElement create(Object nullableDefault, Object value) {
import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeType;
public class ObjectMapper extends AttributeIfcSwitchStatement<AttributeMappingStrategy<?, ? extends OpenType<?>>> {
- private final Services dependencyTracker;
+ private final ServiceRegistryWrapper dependencyTracker;
- public ObjectMapper(Services depTracker) {
+ public ObjectMapper(ServiceRegistryWrapper depTracker) {
this.dependencyTracker = depTracker;
}
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import javax.management.ObjectName;
public class ObjectNameAttributeMappingStrategy extends
AbstractAttributeMappingStrategy<ObjectNameAttributeMappingStrategy.MappedDependency, SimpleType<?>> {
- private final Services tracker;
+ private final ServiceRegistryWrapper tracker;
private final String serviceName;
private final String namespace;
- public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, Services dependencyTracker, String serviceName, String namespace) {
+ public ObjectNameAttributeMappingStrategy(SimpleType<?> openType, ServiceRegistryWrapper dependencyTracker, String serviceName, String namespace) {
super(openType);
this.tracker = dependencyTracker;
this.serviceName = serviceName;
ObjectName on = (ObjectName) value;
- String expectedRefName = on.getKeyProperty(AttributesConstants.REF_NAME_ON_PROPERTY_KEY);
-
- String refName = expectedRefName == null ? tracker.getRefName(namespace, serviceName, on, Optional.<String> absent())
- : tracker.getRefName(namespace, serviceName, on, Optional.of(expectedRefName));
+ String refName = ObjectNameUtil.getReferenceName(on);
return Optional.of(new MappedDependency(namespace, serviceName, refName));
}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving;
import com.google.common.base.Optional;
-import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributesConstants;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectNameAttributeMappingStrategy;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services.ServiceInstance;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ObjectNameAttributeResolvingStrategy extends AbstractAttributeResolvingStrategy<ObjectName, SimpleType<?>> {
- private final Services serviceTracker;
+ private final ServiceRegistryWrapper serviceTracker;
private static final Logger logger = LoggerFactory.getLogger(ObjectNameAttributeResolvingStrategy.class);
- ObjectNameAttributeResolvingStrategy(Services serviceTracker) {
+ ObjectNameAttributeResolvingStrategy(ServiceRegistryWrapper serviceTracker) {
super(SimpleType.OBJECTNAME);
this.serviceTracker = serviceTracker;
}
String namespace = mappedDep.getNamespace();
logger.trace("Getting service instance by service name {} : {} and ref name {}", namespace, serviceName, refName);
- ServiceInstance byRefName = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
- ObjectName on = ObjectNameUtil.createReadOnlyModuleON(byRefName.getModuleName(), byRefName.getInstanceName());
- on = ObjectNameUtil.createON(on.toString() + "," + AttributesConstants.REF_NAME_ON_PROPERTY_KEY + "=" + refName);
+ ObjectName on = serviceTracker.getByServiceAndRefName(namespace, serviceName, refName);
logger.debug("Attribute {} : {} parsed to type {}", attrName, value, getOpenType());
return Optional.of(on);
import org.opendaylight.controller.config.yangjmxgenerator.attribute.ListDependenciesAttribute;
import org.opendaylight.controller.config.yangjmxgenerator.attribute.TOAttribute;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.AttributeIfcSwitchStatement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeType;
public class ObjectResolver extends AttributeIfcSwitchStatement<AttributeResolvingStrategy<?, ? extends OpenType<?>>> {
- private final Services serviceTracker;
+ private final ServiceRegistryWrapper serviceTracker;
- public ObjectResolver(Services serviceTracker) {
+ public ObjectResolver(ServiceRegistryWrapper serviceTracker) {
this.serviceTracker = serviceTracker;
}
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
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;
// }
public Element toXml(Set<ObjectName> instancesToMap, Optional<String> maybeNamespace, Document document,
- Element dataElement, Services serviceTracker) {
+ Element dataElement, ServiceRegistryWrapper serviceTracker) {
Map<String, Map<String, Collection<ObjectName>>> moduleToInstances = getMappedInstances(instancesToMap,
moduleConfigs);
}
}
- root.appendChild(serviceTracker.toXml(serviceTracker.getMappedServices(), document));
+ root.appendChild(Services.toXml(serviceTracker, document));
return root;
}
// TODO refactor, replace string representing namespace with namespace class
// TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
// class
- public ConfigElementResolved fromXml(XmlElement xml,
- EditStrategyType defaultEditStrategyType, ServiceReferenceReadableRegistry taClient) {
- Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
-
- List<XmlElement> recognisedChildren = Lists.newArrayList();
- Services serviceTracker = fromXmlServices(xml, recognisedChildren, taClient);
- List<XmlElement> moduleElements = fromXmlModules(xml, recognisedChildren);
+ public Map<String, Multimap<String, ModuleElementResolved>> fromXmlModulesResolved(XmlElement xml, EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+ Optional<XmlElement> modulesElement = getModulesElement(xml);
+ List<XmlElement> moduleElements = getModulesElementList(modulesElement);
- xml.checkUnrecognisedElements(recognisedChildren);
+ Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
for (XmlElement moduleElement : moduleElements) {
- resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
- }
+ ResolvingStrategy<ModuleElementResolved> resolvingStrategy = new ResolvingStrategy<ModuleElementResolved>() {
+ @Override
+ public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) {
+ return moduleMapping.fromXml(moduleElement, serviceTracker,
+ instanceName, moduleNamespace, defaultStrategy);
+ }
+ };
- return new ConfigElementResolved(retVal, serviceTracker);
+ resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
+ }
+ return retVal;
}
- public static class ConfigElementResolved {
+ /**
+ * return a map containing namespace -> moduleName -> instanceName map. Attribute parsing is omitted.
+ */
+ public Map<String, Multimap<String, ModuleElementDefinition>> fromXmlModulesMap(XmlElement xml,
+ EditStrategyType defaultEditStrategyType, ServiceRegistryWrapper serviceTracker) {
+ Optional<XmlElement> modulesElement = getModulesElement(xml);
+ List<XmlElement> moduleElements = getModulesElementList(modulesElement);
- private final Map<String, Multimap<String, ModuleElementResolved>> resolvedModules;
- private final Services services;
+ Map<String, Multimap<String, ModuleElementDefinition>> retVal = Maps.newHashMap();
- public ConfigElementResolved(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker) {
- this.resolvedModules = retVal;
- this.services = serviceTracker;
- }
+ for (XmlElement moduleElement : moduleElements) {
+ ResolvingStrategy<ModuleElementDefinition> resolvingStrategy = new ResolvingStrategy<ModuleElementDefinition>() {
+ @Override
+ public ModuleElementDefinition resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement,
+ ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace,
+ EditStrategyType defaultStrategy) {
+ // TODO: add check for conflicts between global and local
+ // edit strategy
+ String perInstanceEditStrategy = moduleElement.getAttribute(XmlNetconfConstants.OPERATION_ATTR_KEY,
+ XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0);
+ return new ModuleElementDefinition(instanceName, perInstanceEditStrategy, defaultStrategy);
+ }
+ };
- public Map<String, Multimap<String, ModuleElementResolved>> getResolvedModules() {
- return resolvedModules;
+ resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType, resolvingStrategy);
}
+ return retVal;
+ }
- public Services getServices() {
- return services;
- }
+ private static Optional<XmlElement> getModulesElement(XmlElement xml) {
+ return xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
+ XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
}
- private List<XmlElement> fromXmlModules(XmlElement xml, List<XmlElement> recognisedChildren) {
- Optional<XmlElement> modulesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.MODULES_KEY,
- XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ private List<XmlElement> getModulesElementList(Optional<XmlElement> modulesElement) {
List<XmlElement> moduleElements;
+
if (modulesElement.isPresent()) {
moduleElements = modulesElement.get().getChildElementsWithSameNamespace(XmlNetconfConstants.MODULE_KEY);
- recognisedChildren.add(modulesElement.get());
modulesElement.get().checkUnrecognisedElements(moduleElements);
} else {
moduleElements = Lists.newArrayList();
return moduleElements;
}
- private void resolveModule(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
- XmlElement moduleElement, EditStrategyType defaultStrategy) {
+ private <T> void resolveModule(Map<String, Multimap<String, T>> retVal, ServiceRegistryWrapper serviceTracker,
+ XmlElement moduleElement, EditStrategyType defaultStrategy, ResolvingStrategy<T> resolvingStrategy) {
XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
String moduleNamespace = prefixToNamespace.getValue();
ModuleConfig moduleMapping = getModuleMapping(moduleNamespace, instanceName, factoryName);
- Multimap<String, ModuleElementResolved> innerMap = retVal.get(moduleNamespace);
+ Multimap<String, T> innerMap = retVal.get(moduleNamespace);
if (innerMap == null) {
innerMap = HashMultimap.create();
retVal.put(moduleNamespace, innerMap);
}
- ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker,
+ T resolvedElement = resolvingStrategy.resolveElement(moduleMapping, moduleElement, serviceTracker,
instanceName, moduleNamespace, defaultStrategy);
- innerMap.put(factoryName, moduleElementResolved);
+ innerMap.put(factoryName, resolvedElement);
}
- private Services fromXmlServices(XmlElement xml, List<XmlElement> recognisedChildren,
- ServiceReferenceReadableRegistry taClient) {
- Optional<XmlElement> servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
- XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ public Services fromXmlServices(XmlElement xml) {
+ Optional<XmlElement> servicesElement = getServicesElement(xml);
- Map<String, Map<String, Map<String, String>>> mappedServices;
+ Services services;
if (servicesElement.isPresent()) {
- mappedServices = Services.fromXml(servicesElement.get());
- recognisedChildren.add(servicesElement.get());
+ services = Services.fromXml(servicesElement.get());
} else {
- mappedServices = new HashMap<>();
+ services = new Services();
}
- Services services = Services.resolveServices(mappedServices, taClient);
return services;
}
+ private static Optional<XmlElement> getServicesElement(XmlElement xml) {
+ return xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
+ XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ }
+
+ public static void checkUnrecognisedChildren(XmlElement parent) {
+ Optional<XmlElement> servicesOpt = getServicesElement(parent);
+ Optional<XmlElement> modulesOpt = getModulesElement(parent);
+
+ List<XmlElement> recognised = Lists.newArrayList();
+ if(servicesOpt.isPresent())
+ recognised.add(servicesOpt.get());
+ if(modulesOpt.isPresent())
+ recognised.add(modulesOpt.get());
+
+ parent.checkUnrecognisedElements(recognised);
+ }
+
private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {
checkState(
factoryNameWithPrefix.startsWith(prefixOrEmptyString),
return moduleMapping;
}
+ private interface ResolvingStrategy<T> {
+ public T resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker,
+ String instanceName, String moduleNamespace, EditStrategyType defaultStrategy);
+ }
}
this.configRegistryClient = configRegistryClient;
}
- private Map<String, Object> getMappedConfiguration(ObjectName on, Services depTracker) {
+ private Map<String, Object> getMappedConfiguration(ObjectName on, ServiceRegistryWrapper depTracker) {
// TODO make field, mappingStrategies can be instantiated only once
Map<String, AttributeMappingStrategy<?, ? extends OpenType<?>>> mappingStrategies = new ObjectMapper(depTracker)
return toXml;
}
- public Element toXml(ObjectName on, Services depTracker, String namespace, Document document, Element rootElement) {
+ public Element toXml(ObjectName on, ServiceRegistryWrapper depTracker, String namespace, Document document, Element rootElement) {
Element cfgElement = rootElement;
return cfgElement;
}
- private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, Services depTracker) {
+ private void resolveConfiguration(InstanceConfigElementResolved mappedConfig, ServiceRegistryWrapper depTracker) {
// TODO make field, resolvingStrategies can be instantiated only once
Map<String, AttributeResolvingStrategy<?, ? extends OpenType<?>>> resolvingStrategies = new ObjectResolver(
}
}
- public InstanceConfigElementResolved fromXml(XmlElement moduleElement, Services services, String moduleNamespace,
+ public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
private final Multimap<String, String> providedServices;
public InstanceConfigElementResolved(String currentStrategy, Map<String, AttributeConfigElement> configuration, EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
- EditStrategyType valueOf = checkStrategy(currentStrategy, defaultStrategy);
+ EditStrategyType valueOf = parseStrategy(currentStrategy, defaultStrategy);
this.editStrategy = valueOf;
this.configuration = configuration;
this.providedServices = providedServices;
}
- EditStrategyType checkStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
- EditStrategyType valueOf = EditStrategyType.valueOf(currentStrategy);
+ static EditStrategyType parseStrategy(String currentStrategy, EditStrategyType defaultStrategy) {
+ EditStrategyType parsedStrategy = EditStrategyType.valueOf(currentStrategy);
if (defaultStrategy.isEnforcing()) {
Preconditions
.checkArgument(
- valueOf == defaultStrategy,
+ parsedStrategy == defaultStrategy,
"With "
+ defaultStrategy
+ " as "
+ EditConfigXmlParser.DEFAULT_OPERATION_KEY
+ " operations on module elements are not permitted since the default option is restrictive");
}
- return valueOf;
+ return parsedStrategy;
}
return providedServices;
}
- public Element toXml(ObjectName instanceON, Services depTracker, Document document, String namespace) {
+ public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) {
Element root = document.createElement(XmlNetconfConstants.MODULE_KEY);
// Xml.addNamespaceAttr(document, root, namespace);
}
- public ModuleElementResolved fromXml(XmlElement moduleElement, Services depTracker, String instanceName,
+ public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
String moduleNamespace, EditStrategyType defaultStrategy) {
InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices);
--- /dev/null
+/*
+ * 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.netconf.confignetconfconnector.mapping.config;
+
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditStrategyType;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.MissingInstanceHandlingStrategy;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.NoneEditConfigStrategy;
+
+public class ModuleElementDefinition {
+
+ public static final NoneEditConfigStrategy NONE_EDIT_CONFIG_STRATEGY = new NoneEditConfigStrategy();
+ public static final MissingInstanceHandlingStrategy MISSING_INSTANCE_HANDLING_STRATEGY = new MissingInstanceHandlingStrategy();
+
+ private final String instanceName;
+ private final EditStrategyType editStrategy;
+
+ public ModuleElementDefinition(String instanceName, String currentStrategy, EditStrategyType defaultStrategy) {
+ this.instanceName = instanceName;
+ if (currentStrategy == null || currentStrategy.isEmpty())
+ this.editStrategy = defaultStrategy;
+ else
+ this.editStrategy = InstanceConfigElementResolved.parseStrategy(currentStrategy, defaultStrategy);
+ }
+
+ public String getInstanceName() {
+ return instanceName;
+ }
+
+ public EditStrategyType getEditStrategyType() {
+ return editStrategy;
+ }
+
+ public EditConfigStrategy getEditStrategy() {
+ switch (editStrategy) {
+ case delete :
+ case remove :
+ case none : return NONE_EDIT_CONFIG_STRATEGY;
+ default : return MISSING_INSTANCE_HANDLING_STRATEGY;
+ }
+ }
+}
--- /dev/null
+/*
+ * 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.netconf.confignetconfconnector.mapping.config;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ServiceRegistryWrapper {
+
+ private ServiceReferenceReadableRegistry configServiceRefRegistry;
+
+ private long suffix = 1;
+
+ public ServiceRegistryWrapper(ServiceReferenceReadableRegistry configServiceRefRegistry) {
+ this.configServiceRefRegistry = configServiceRefRegistry;
+ }
+
+
+ public boolean hasRefName(String namespace, String serviceName, ObjectName on) {
+ String qname = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+ Map<String, ObjectName> forQName = configServiceRefRegistry.getServiceMapping().get(qname);
+ if(forQName==null) return false;
+ return forQName.values().contains(on);
+ }
+
+ public ObjectName getByServiceAndRefName(String namespace, String serviceName, String refName) {
+ Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+ Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
+
+ Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+ Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
+ + serviceNameToRefNameToInstance.keySet());
+
+ String instanceId = refNameToInstance.get(refName);
+ Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
+ + refName + ", " + serviceNameToRefNameToInstance.keySet());
+
+ Services.ServiceInstance serviceInstance = Services.ServiceInstance.fromString(instanceId);
+ Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
+ + " under service name " + serviceName + " , " + refNameToInstance.keySet());
+
+ String qNameOfService = configServiceRefRegistry.getServiceInterfaceName(namespace, serviceName);
+ try {
+ return configServiceRefRegistry.getServiceReference(qNameOfService, refName);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalArgumentException("No serviceInstance mapped to " + refName
+ + " under service name " + serviceName + " , " + refNameToInstance.keySet(), e);
+
+ }
+ }
+
+ public Map<String, Map<String, Map<String, String>>> getMappedServices() {
+ Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
+
+ Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
+ for (String serviceQName : serviceMapping.keySet())
+ for (String refName : serviceMapping.get(serviceQName).keySet()) {
+
+ ObjectName on = serviceMapping.get(serviceQName).get(refName);
+ Services.ServiceInstance si = Services.ServiceInstance.fromObjectName(on);
+
+ // FIXME use QName's new String constructor, after it is fixed
+// QName qname;
+// try {
+// qname = new QName(serviceQName);
+// } catch (ParseException e) {
+// throw new IllegalStateException("Unable to parse qname of a service " + serviceQName, e);
+// }
+ Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
+ Matcher matcher = p.matcher(serviceQName);
+ Preconditions.checkArgument(matcher.matches());
+ String namespace = matcher.group(1);
+ String localName = matcher.group(2);
+
+// String namespace = qname.getNamespace().toString();
+ Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
+ if(serviceToRefs==null) {
+ serviceToRefs = Maps.newHashMap();
+ retVal.put(namespace, serviceToRefs);
+ }
+
+// String localName = qname.getLocalName();
+ Map<String, String> refsToSis = serviceToRefs.get(localName);
+ if(refsToSis==null) {
+ refsToSis = Maps.newHashMap();
+ serviceToRefs.put(localName, refsToSis);
+ }
+
+ Preconditions.checkState(refsToSis.containsKey(refName) == false,
+ "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
+ localName, on);
+ refsToSis.put(refName, si.toString());
+ }
+
+ return retVal;
+ }
+
+ @VisibleForTesting
+ public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
+ String refName;
+ refName = "ref_" + instanceName;
+
+ Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
+
+ Map<String, String> refNameToInstance;
+ if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
+ refNameToInstance = Collections.emptyMap();
+ } else
+ refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
+
+ final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
+ if (refNamesAsSet.contains(refName)) {
+ refName = findAvailableRefName(refName, refNamesAsSet);
+ }
+
+ return refName;
+ }
+
+
+ private Set<String> toSet(Collection<String> values) {
+ Set<String> refNamesAsSet = Sets.newHashSet();
+
+ for (String refName : values) {
+ boolean resultAdd = refNamesAsSet.add(refName);
+ Preconditions.checkState(resultAdd,
+ "Error occurred building services element, reference name {} was present twice", refName);
+ }
+
+ return refNamesAsSet;
+ }
+
+ private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
+ String intitialRefName = refName;
+
+ while (true) {
+ refName = intitialRefName + "_" + suffix++;
+ if (refNamesAsSet.contains(refName) == false)
+ return refName;
+ }
+ }
+}
package org.opendaylight.controller.netconf.confignetconfconnector.mapping.config;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
-import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
-import com.google.common.collect.Multimap;
-import com.google.common.collect.Sets;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectNameAttributeReadingStrategy;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.w3c.dom.Element;
import javax.management.ObjectName;
-import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public static final String TYPE_KEY = "type";
public static final String SERVICE_KEY = "service";
- private long suffix = 1;
-
private final Map<String /*Namespace*/, Map<String/* ServiceName */, Map<String/* refName */, ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = Maps
.newHashMap();
- private ServiceReferenceReadableRegistry configServiceRefRegistry;
-
- public Services(ServiceReferenceReadableRegistry configServiceRefRegistry) {
- this.configServiceRefRegistry = configServiceRefRegistry;
- }
-
- @VisibleForTesting
- public String getNewDefaultRefName(String namespace, String serviceName, String moduleName, String instanceName) {
- String refName;
- refName = "ref_" + instanceName;
-
- Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
- Map<String, String> refNameToInstance;
- if(serviceNameToRefNameToInstance == null || serviceNameToRefNameToInstance.containsKey(serviceName) == false) {
- refNameToInstance = Collections.emptyMap();
- } else
- refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
-
- final Set<String> refNamesAsSet = toSet(refNameToInstance.keySet());
- if (refNamesAsSet.contains(refName)) {
- refName = findAvailableRefName(refName, refNamesAsSet);
- }
-
- return refName;
- }
-
- private Set<String> toSet(Collection<String> values) {
- Set<String> refNamesAsSet = Sets.newHashSet();
-
- for (String refName : values) {
- boolean resultAdd = refNamesAsSet.add(refName);
- Preconditions.checkState(resultAdd,
- "Error occurred building services element, reference name {} was present twice", refName);
- }
-
- return refNamesAsSet;
- }
-
- public ServiceInstance getByServiceAndRefName(String namespace, String serviceName, String refName) {
- Map<String, Map<String, String>> serviceNameToRefNameToInstance = getMappedServices().get(namespace);
-
- Preconditions.checkArgument(serviceNameToRefNameToInstance != null, "No serviceInstances mapped to " + namespace);
-
- Map<String, String> refNameToInstance = serviceNameToRefNameToInstance.get(serviceName);
- Preconditions.checkArgument(refNameToInstance != null, "No serviceInstances mapped to " + serviceName + " , "
- + serviceNameToRefNameToInstance.keySet());
-
- String instanceId = refNameToInstance.get(refName);
- Preconditions.checkArgument(instanceId != null, "No serviceInstances mapped to " + serviceName + ":"
- + refName + ", " + serviceNameToRefNameToInstance.keySet());
-
- ServiceInstance serviceInstance = ServiceInstance.fromString(instanceId);
- Preconditions.checkArgument(serviceInstance != null, "No serviceInstance mapped to " + refName
- + " under service name " + serviceName + " , " + refNameToInstance.keySet());
- return serviceInstance;
- }
-
- // TODO hide getMappedServices, call it explicitly in toXml
-
- public Map<String, Map<String, Map<String, String>>> getMappedServices() {
- Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
-
- for (String namespace : namespaceToServiceNameToRefNameToInstance.keySet()) {
-
- Map<String, Map<String, ServiceInstance>> serviceNameToRefNameToInstance = namespaceToServiceNameToRefNameToInstance
- .get(namespace);
- Map<String, Map<String, String>> innerRetVal = Maps.newHashMap();
-
- for (String serviceName : serviceNameToRefNameToInstance.keySet()) {
-
- Map<String, String> innerInnerRetVal = Maps.newHashMap();
- for (Entry<String, ServiceInstance> refNameToSi : serviceNameToRefNameToInstance.get(serviceName).entrySet()) {
- innerInnerRetVal.put(refNameToSi.getKey(), refNameToSi.getValue().toString());
- }
- innerRetVal.put(serviceName, innerInnerRetVal);
- }
- retVal.put(namespace, innerRetVal);
- }
-
- Map<String, Map<String, ObjectName>> serviceMapping = configServiceRefRegistry.getServiceMapping();
- for (String serviceQName : serviceMapping.keySet())
- for (String refName : serviceMapping.get(serviceQName).keySet()) {
-
- ObjectName on = serviceMapping.get(serviceQName).get(refName);
- ServiceInstance si = ServiceInstance.fromObjectName(on);
-
- // FIXME use QName's new String constructor, after its implemented
- Pattern p = Pattern.compile("\\(([^\\(\\?]+)\\?[^\\?\\)]*\\)([^\\)]+)");
- Matcher matcher = p.matcher(serviceQName);
- Preconditions.checkArgument(matcher.matches());
- String namespace = matcher.group(1);
- String localName = matcher.group(2);
-
- Map<String, Map<String, String>> serviceToRefs = retVal.get(namespace);
- if(serviceToRefs==null) {
- serviceToRefs = Maps.newHashMap();
- retVal.put(namespace, serviceToRefs);
- }
-
- Map<String, String> refsToSis = serviceToRefs.get(localName);
- if(refsToSis==null) {
- refsToSis = Maps.newHashMap();
- serviceToRefs.put(localName, refsToSis);
- }
-
- Preconditions.checkState(refsToSis.containsKey(refName) == false,
- "Duplicate reference name %s for service %s:%s, now for instance %s", refName, namespace,
- localName, on);
- refsToSis.put(refName, si.toString());
- }
-
- return retVal;
- }
/**
*
return namespaceToServiceNameToRefNameToInstance;
}
- // TODO hide resolveServices, call it explicitly in fromXml
-
- public static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices, ServiceReferenceReadableRegistry taClient) {
- Services tracker = new Services(taClient);
+ private static Services resolveServices(Map<String, Map<String, Map<String, String>>> mappedServices) {
+ Services tracker = new Services();
for (Entry<String, Map<String, Map<String, String>>> namespaceEntry : mappedServices.entrySet()) {
String namespace = namespaceEntry.getKey();
// TODO support edit strategies on services
- public static Map<String, Map<String, Map<String, String>>> fromXml(XmlElement xml) {
+ public static Services fromXml(XmlElement xml) {
Map<String, Map<String, Map<String, String>>> retVal = Maps.newHashMap();
List<XmlElement> services = xml.getChildElements(SERVICE_KEY);
}
}
- return retVal;
- }
-
- private String findAvailableRefName(String refName, Set<String> refNamesAsSet) {
- String intitialRefName = refName;
-
- while (true) {
- refName = intitialRefName + "_" + suffix++;
- if (refNamesAsSet.contains(refName) == false)
- return refName;
- }
+ return resolveServices(retVal);
}
- public Element toXml(Map<String, Map<String, Map<String, String>>> mappedServices, Document document) {
+ public static Element toXml(ServiceRegistryWrapper serviceRegistryWrapper, Document document) {
Element root = document.createElement(XmlNetconfConstants.SERVICES_KEY);
XmlUtil.addNamespaceAttr(root, XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
+ Map<String, Map<String, Map<String, String>>> mappedServices = serviceRegistryWrapper.getMappedServices();
for (String namespace : mappedServices.keySet()) {
for (Entry<String, Map<String, String>> serviceEntry : mappedServices.get(namespace).entrySet()) {
return root;
}
- public String getRefName(String namespace, String serviceName, ObjectName on, Optional<String> expectedRefName) {
- Optional<String> refNameOptional = getRefNameOptional(namespace, serviceName, on, expectedRefName);
- Preconditions.checkState(refNameOptional.isPresent(), "No reference names mapped to %s, %s, %s", namespace,
- serviceName, on);
- return refNameOptional.get();
- }
-
- public Optional<String> getRefNameOptional(String namespace, String serviceName, ObjectName on,
- Optional<String> expectedRefName) {
- Map<String, Map<String, String>> services = getMappedServices().get(namespace);
-
- if(services == null) return Optional.absent();
- Map<String, String> refs = services.get(serviceName);
-
- if(refs == null) return Optional.absent();
- Multimap<ServiceInstance, String> reverted = revertMap(refs);
-
- ServiceInstance serviceInstance = ServiceInstance.fromObjectName(on);
- Collection<String> references = reverted.get(serviceInstance);
-
- if (expectedRefName.isPresent() && references.contains(expectedRefName.get())) {
- logger.debug("Returning expected ref name {} for {}", expectedRefName.get(), on);
- return expectedRefName;
- } else if (references.size() > 0) {
- String next = references.iterator().next();
- logger.debug("Returning random ref name {} for {}", next, on);
- return Optional.of(next);
- } else
- return Optional.absent();
- }
-
- private Multimap<ServiceInstance, String> revertMap(Map<String, String> refs) {
- Multimap<ServiceInstance, String> multimap = HashMultimap.create();
-
- for (Entry<String, String> e : refs.entrySet()) {
- multimap.put(ServiceInstance.fromString(e.getValue()), e.getKey());
- }
-
- return multimap;
- }
-
- public boolean hasRefName(String key, String value, ObjectName on) {
- return getRefNameOptional(key, value, on, Optional.<String>absent()).isPresent();
- }
-
public static final class ServiceInstance {
public ServiceInstance(String moduleName, String instanceName) {
this.moduleName = moduleName;
import com.google.common.collect.Sets;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
}
public Element toXml(String namespace, Collection<ObjectName> runtimeBeanOns,
- Document document, ModuleConfig moduleConfig, ObjectName configBeanON, Services serviceTracker) {
+ Document document, ModuleConfig moduleConfig, ObjectName configBeanON, ServiceRegistryWrapper serviceTracker) {
Element moduleElement = moduleConfig.toXml(configBeanON, serviceTracker, document, namespace);
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
-import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
import org.opendaylight.controller.netconf.util.xml.XmlUtil;
import org.w3c.dom.Document;
return retVal;
}
- public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceReferenceReadableRegistry serviceRegistry) {
- Services serviceTracker = new Services(serviceRegistry);
-
+ public Element toXml(Set<ObjectName> instancesToMap, Set<ObjectName> configBeans, Document document, ServiceRegistryWrapper serviceRegistry) {
Element root = document.createElement(XmlNetconfConstants.DATA_KEY);
Element modulesElement = document.createElement(XmlNetconfConstants.MODULES_KEY);
Element runtimeXml;
ModuleConfig moduleConfig = moduleConfigs.get(localNamespace).get(moduleName);
if(instanceToRbe==null || instanceToRbe.containsKey(instanceName) == false) {
- runtimeXml = moduleConfig.toXml(instanceON, serviceTracker, document, localNamespace);
+ runtimeXml = moduleConfig.toXml(instanceON, serviceRegistry, document, localNamespace);
} else {
ModuleRuntime moduleRuntime = moduleRuntimes.get(localNamespace).get(moduleName);
runtimeXml = moduleRuntime.toXml(localNamespace, instanceToRbe.get(instanceName), document,
- moduleConfig, instanceON, serviceTracker);
+ moduleConfig, instanceON, serviceRegistry);
}
modulesElement.appendChild(runtimeXml);
}
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, Services services) {
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) {
try {
ObjectName on = ta.lookupConfigBean(module, instance);
}
+ // TODO split missing instances handling strategies from edit config strategies in this hierarchy = REFACTOR
+ // edit configs should not handle missing
+
abstract void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services);
+ String module, String instance, ServiceRegistryWrapper services);
abstract void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- ObjectName objectName, Services services);
+ ObjectName objectName, ServiceRegistryWrapper services);
}
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
+ String module, String instance, ServiceRegistryWrapper services) {
throw new IllegalStateException("Unable to delete " + module + ":" + instance + " , ServiceInstance not found");
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
try {
ta.destroyModule(on);
logger.debug("ServiceInstance {} deleted successfully", on);
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
logger.debug("Test phase for {} operation successful", EditConfigXmlParser.EDIT_CONFIG);
}
- private void test(ConfigRegistryClient configRegistryClient,
- EditConfigExecution execution, EditStrategyType editStrategyType) {
+ private void test(ConfigRegistryClient configRegistryClient, EditConfigExecution execution,
+ EditStrategyType editStrategyType) {
ObjectName taON = transactionProvider.getTestTransaction();
try {
transactionProvider.wipeTestTransaction(taON);
}
- setOnTransaction(configRegistryClient, execution.getResolvedXmlElements(), execution.getServices(), taON);
- // TODO add service reference persistance testing here
+ ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+ handleMisssingInstancesOnTransaction(ta, execution);
+ setServicesOnTransaction(ta, execution);
+ setOnTransaction(ta, execution);
transactionProvider.validateTestTransaction(taON);
} finally {
transactionProvider.abortTestTransaction(taON);
transactionProvider.wipeTransaction();
}
- setOnTransaction(configRegistryClient, editConfigExecution.getResolvedXmlElements(),
- editConfigExecution.getServices(), taON);
- setServicesOnTransaction(configRegistryClient, editConfigExecution.getServices(), taON);
+ ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+
+ handleMisssingInstancesOnTransaction(ta, editConfigExecution);
+ setServicesOnTransaction(ta, editConfigExecution);
+ setOnTransaction(ta, editConfigExecution);
}
- private void setServicesOnTransaction(ConfigRegistryClient configRegistryClient, Services services,
- ObjectName taON) {
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+ private void setServicesOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+ Services services = execution.getServices();
Map<String, Map<String, Map<String, Services.ServiceInstance>>> namespaceToServiceNameToRefNameToInstance = services
.getNamespaceToServiceNameToRefNameToInstance();
for (String refName : refNameToInstance.keySet()) {
ObjectName on = refNameToInstance.get(refName).getObjectName(ta.getTransactionName());
- // TODO check for duplicates
try {
- ta.saveServiceReference(qnameOfService, refName, on);
+ ObjectName saved = ta.saveServiceReference(qnameOfService, refName, on);
+ logger.debug("Saving service {} with on {} under name {} with service on {}", qnameOfService,
+ on, refName, saved);
} catch (InstanceNotFoundException e) {
throw new IllegalStateException("Unable to save ref name " + refName + " for instance " + on, e);
}
return ta.getServiceInterfaceName(namespace, serviceName);
}
- private void setOnTransaction(ConfigRegistryClient configRegistryClient,
- Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements, Services services, ObjectName taON) {
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
+ private void setOnTransaction(ConfigTransactionClient ta, EditConfigExecution execution) {
+
+ for (Multimap<String, ModuleElementResolved> modulesToResolved : execution.getResolvedXmlElements(ta).values()) {
- for (Multimap<String, ModuleElementResolved> modulesToResolved : resolvedXmlElements.values()) {
for (Entry<String, ModuleElementResolved> moduleToResolved : modulesToResolved.entries()) {
String moduleName = moduleToResolved.getKey();
InstanceConfigElementResolved ice = moduleElementResolved.getInstanceConfigElementResolved();
EditConfigStrategy strategy = ice.getEditStrategy();
- strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, services);
+ strategy.executeConfiguration(moduleName, instanceName, ice.getConfiguration(), ta, execution.getServiceRegistryWrapper(ta));
+ }
+ }
+ }
+
+ private void handleMisssingInstancesOnTransaction(ConfigTransactionClient ta,
+ EditConfigExecution execution) {
+
+ for (Multimap<String,ModuleElementDefinition> modulesToResolved : execution.getModulesDefinition(ta).values()) {
+ for (Entry<String, ModuleElementDefinition> moduleToResolved : modulesToResolved.entries()) {
+ String moduleName = moduleToResolved.getKey();
+
+ ModuleElementDefinition moduleElementDefinition = moduleToResolved.getValue();
+
+ EditConfigStrategy strategy = moduleElementDefinition.getEditStrategy();
+ strategy.executeConfiguration(moduleName, moduleElementDefinition.getInstanceName(), null, ta, execution.getServiceRegistryWrapper(ta));
}
}
}
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import java.util.Map;
public interface EditConfigStrategy {
void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, Services services);
+ ConfigTransactionClient ta, ServiceRegistryWrapper services);
}
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
import org.opendaylight.controller.config.util.ConfigRegistryClient;
-import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import javax.management.ObjectName;
import java.util.Arrays;
import java.util.Map;
XmlElement configElement = xml.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.CONFIG_KEY);
- ObjectName taON = transactionProvider.getOrCreateTransaction();
- ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(taON);
-
- return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption,
- ta, editStrategyType);
+ return new EditConfigXmlParser.EditConfigExecution(cfgMapping, configElement, testOption, editStrategyType);
}
@VisibleForTesting
@VisibleForTesting
static class EditConfigExecution {
- private final Map<String, Multimap<String, ModuleElementResolved>> resolvedXmlElements;
private final TestOption testOption;
private final EditStrategyType defaultEditStrategyType;
private final Services services;
-
- EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, ServiceReferenceReadableRegistry ta, EditStrategyType defaultStrategy) {
- Config.ConfigElementResolved configElementResolved = configResolver.fromXml(configElement, defaultStrategy, ta);
- this.resolvedXmlElements = configElementResolved.getResolvedModules();
- this.services = configElementResolved.getServices();
+ private final Config configResolver;
+ private final XmlElement configElement;
+
+ EditConfigExecution(Config configResolver, XmlElement configElement, TestOption testOption, EditStrategyType defaultStrategy) {
+ Config.checkUnrecognisedChildren(configElement);
+ this.configResolver = configResolver;
+ this.configElement = configElement;
+ this.services = configResolver.fromXmlServices(configElement);
this.testOption = testOption;
this.defaultEditStrategyType = defaultStrategy;
}
return testOption == TestOption.set || testOption == TestOption.testThenSet;
}
- Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements() {
- return resolvedXmlElements;
+ Map<String, Multimap<String, ModuleElementResolved>> getResolvedXmlElements(ServiceReferenceReadableRegistry serviceRegistry) {
+ return configResolver.fromXmlModulesResolved(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
+ }
+
+ ServiceRegistryWrapper getServiceRegistryWrapper(ServiceReferenceReadableRegistry serviceRegistry) {
+ // TODO cache service registry
+ return new ServiceRegistryWrapper(serviceRegistry);
+ }
+
+ Map<String, Multimap<String,ModuleElementDefinition>> getModulesDefinition(ServiceReferenceReadableRegistry serviceRegistry) {
+ return configResolver.fromXmlModulesMap(configElement, defaultEditStrategyType, getServiceRegistryWrapper(serviceRegistry));
}
EditStrategyType getDefaultStrategy() {
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
import java.util.Map;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
- ObjectName on = null;
- try {
- on = ta.createModule(module, instance);
- logger.info("New instance for {} {} created under name {}", module, instance, on);
- addRefNames(services, providedServices, module, instance, ta, on);
- executeStrategy(configuration, ta, on, services);
- } catch (InstanceAlreadyExistsException e1) {
- throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
- } catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
- }
+ String module, String instance, ServiceRegistryWrapper services) {
+ throw new IllegalStateException(
+ "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+ + module + ":" + instance);
}
- private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
- String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+ private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
for (Entry<String, String> namespaceToService : providedServices.entries()) {
if(services.hasRefName(namespaceToService.getKey(),
continue;
String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
- module, instance);
+ ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
ta.saveServiceReference(
ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
}
}
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ try {
+ addRefNames(services, providedServices, ta, on);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+ }
+
for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
try {
AttributeConfigElement ace = configAttributeEntry.getValue();
--- /dev/null
+/*
+ * 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.netconf.confignetconfconnector.operations.editconfig;
+
+import org.opendaylight.controller.config.util.ConfigTransactionClient;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.ObjectName;
+import java.util.Map;
+
+public class MissingInstanceHandlingStrategy extends AbstractEditConfigStrategy {
+
+ private static final Logger logger = LoggerFactory.getLogger(MissingInstanceHandlingStrategy.class);
+
+ @Override
+ void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+ String module, String instance, ServiceRegistryWrapper services) {
+ ObjectName on = null;
+ try {
+ on = ta.createModule(module, instance);
+ logger.info("New instance for {} {} created under name {}", module, instance, on);
+ } catch (InstanceAlreadyExistsException e1) {
+ throw new IllegalStateException("Unable to create instance for " + module + " : " + instance);
+ }
+ }
+
+ @Override
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
+ ObjectName objectName, ServiceRegistryWrapper services) {
+ return;
+ }
+}
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
-import java.util.Map;
-
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Map;
+
public class NoneEditConfigStrategy implements EditConfigStrategy {
private static final Logger logger = LoggerFactory.getLogger(NoneEditConfigStrategy.class);
@Override
public void executeConfiguration(String module, String instance, Map<String, AttributeConfigElement> configuration,
- ConfigTransactionClient ta, Services services) {
+ ConfigTransactionClient ta, ServiceRegistryWrapper services) {
logger.debug("Skipping configuration element for {}:{}", module, instance);
}
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
+ String module, String instance, ServiceRegistryWrapper services) {
logger.warn("Unable to delete {}:{}, ServiceInstance not found", module, instance);
}
}
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
+import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
import org.opendaylight.controller.config.util.ConfigTransactionClient;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.management.Attribute;
-import javax.management.InstanceAlreadyExistsException;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
import java.util.Map;
@Override
void handleMissingInstance(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta,
- String module, String instance, Services services) {
- ObjectName on = null;
- try {
- on = ta.createModule(module, instance);
- logger.debug("New instance for {} {} created under name {}", module, instance, on);
- addRefNames(services, providedServices, module, instance, ta, on);
- executeStrategy(configuration, ta, on, services);
- } catch (InstanceAlreadyExistsException e) {
- logger.warn("Error creating instance {}:{}, replace failed", module, instance, e);
- throw new IllegalStateException("Unable to create new instance for " + module + " : " + instance, e);
- } catch (InstanceNotFoundException e) {
- throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
- }
+ String module, String instance, ServiceRegistryWrapper services) {
+ throw new IllegalStateException(
+ "Unable to handle missing instance, no missing instances should appear at this point, missing: "
+ + module + ":" + instance);
}
- private void addRefNames(Services services, Multimap<String, String> providedServices, String module,
- String instance, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
+ private void addRefNames(ServiceRegistryWrapper services, Multimap<String, String> providedServices, ConfigTransactionClient ta, ObjectName on) throws InstanceNotFoundException {
for (Entry<String, String> namespaceToService : providedServices.entries()) {
if(services.hasRefName(namespaceToService.getKey(),
continue;
String refName = services.getNewDefaultRefName(namespaceToService.getKey(), namespaceToService.getValue(),
- module, instance);
+ ObjectNameUtil.getFactoryName(on), ObjectNameUtil.getInstanceName(on));
ta.saveServiceReference(
ta.getServiceInterfaceName(namespaceToService.getKey(), namespaceToService.getValue()), refName, on);
}
}
+
@Override
- void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, Services services) {
+ void executeStrategy(Map<String, AttributeConfigElement> configuration, ConfigTransactionClient ta, ObjectName on, ServiceRegistryWrapper services) {
+ try {
+ addRefNames(services, providedServices, ta, on);
+ } catch (InstanceNotFoundException e) {
+ throw new IllegalStateException("Unable to save default ref name for instance " + on, e);
+ }
+
for (Entry<String, AttributeConfigElement> configAttributeEntry : configuration.entrySet()) {
try {
AttributeConfigElement ace = configAttributeEntry.getValue();
import org.opendaylight.controller.netconf.api.NetconfDocumentedException.ErrorType;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.InstanceRuntime;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.ModuleRuntime;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.runtime.Runtime;
ObjectName txOn = transactionProvider.getOrCreateTransaction();
ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(txOn);
- final Element element = runtime.toXml(runtimeBeans, configBeans, document, ta);
+ final Element element = runtime.toXml(runtimeBeans, configBeans, document, new ServiceRegistryWrapper(ta));
logger.info("{} operation successful", XmlNetconfConstants.GET);
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Config;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfig;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleConfig;
-import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.Datastore;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
ObjectName on = transactionProvider.getOrCreateTransaction();
ConfigTransactionClient ta = configRegistryClient.getConfigTransactionClient(on);
- Services serviceTracker = new Services(ta);
+ ServiceRegistryWrapper serviceTracker = new ServiceRegistryWrapper(ta);
dataElement = configMapping.toXml(instances, this.maybeNamespace, document, dataElement, serviceTracker);
logger.info("{} operation successful", GET_CONFIG);
"ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
"ref_from_code_to_instance-from-code_1");
+
edit("netconfMessages/editConfig_addServiceName.xml");
config = getConfigCandidate();
assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
"ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
"ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
+ edit("netconfMessages/editConfig_addServiceNameOnTest.xml");
+ config = getConfigCandidate();
+ assertCorrectServiceNames(config, 7, "ref_test2", "user_to_instance_from_code", "ref_dep_user",
+ "ref_dep_user_two", "ref_from_code_to_instance-from-code_dep_1",
+ "ref_from_code_to_instance-from-code_1", "ref_dep_user_another");
+
commit();
config = getConfigRunning();
assertCorrectRefNamesForDependencies(config);
edit("netconfMessages/editConfig.xml");
Element configCandidate = getConfigCandidate();
+ System.err.println(XmlUtil.toString(configCandidate));
checkBinaryLeafEdited(configCandidate);
import org.opendaylight.controller.netconf.api.NetconfDocumentedException;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.InstanceConfigElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementDefinition;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ModuleElementResolved;
+import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.ServiceRegistryWrapper;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.config.Services;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.ValidateTest;
import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfigXmlParser.EditConfigExecution;
import java.util.Map;
import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyMap;
+import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
ValidateTest.NETCONF_SESSION_ID_FOR_REPORTING);
EditConfigStrategy editStrat = mock(EditConfigStrategy.class);
- doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMap(),
- any(ConfigTransactionClient.class), any(Services.class));
+ doNothing().when(editStrat).executeConfiguration(anyString(), anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+ any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
EditConfigExecution editConfigExecution = mockExecution(editStrat);
verify(provider).getOrCreateTransaction();
// For every instance execute strat
- verify(editStrat, times(2/* Test */+ 2/* Set */)).executeConfiguration(anyString(), anyString(), anyMap(),
- any(ConfigTransactionClient.class), any(Services.class));
+ verify(editStrat, times(2/* Test */+ 2/* Set */ + 2/*Handle missing instance Test*/ + 2 /*Handle missing instance Set*/)).executeConfiguration(anyString(),
+ anyString(), anyMapOf(String.class, AttributeConfigElement.class),
+ any(ConfigTransactionClient.class), any(ServiceRegistryWrapper.class));
}
private EditConfigExecution mockExecution(EditConfigStrategy editStrat) {
EditConfigExecution mock = mock(EditConfigExecution.class);
- doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements();
+ doReturn(getMapping(editStrat)).when(mock).getResolvedXmlElements(any(ConfigTransactionClient.class));
+ doReturn(getMappingDefinition(editStrat)).when(mock).getModulesDefinition(any(ConfigTransactionClient.class));
doReturn(EditStrategyType.merge).when(mock).getDefaultStrategy();
doReturn(true).when(mock).shouldSet();
doReturn(true).when(mock).shouldTest();
- doReturn(mockServices()).when(mock).getServices();
+ doReturn(mockServices()).when(mock).getServiceRegistryWrapper(any(ConfigTransactionClient.class));
+ doReturn(new Services()).when(mock).getServices();
return mock;
}
+ private Object getMappingDefinition(EditConfigStrategy editStrat) {
+ Map<String, Multimap<String, ModuleElementDefinition>> result = Maps.newHashMap();
+
+ Multimap<String, ModuleElementDefinition> innerMultimap = HashMultimap.create();
+ Map<String, AttributeConfigElement> attributes = getSimpleAttributes();
+
+ ModuleElementDefinition mockedDefinition = mock(ModuleElementDefinition.class);
+ doReturn(editStrat).when(mockedDefinition).getEditStrategy();
+ doReturn("i1").when(mockedDefinition).getInstanceName();
+ innerMultimap.put("m1", mockedDefinition);
+
+ ModuleElementDefinition mockedDefinition2 = mock(ModuleElementDefinition.class);
+ doReturn(editStrat).when(mockedDefinition2).getEditStrategy();
+ doReturn("i2").when(mockedDefinition2).getInstanceName();
+ innerMultimap.put("m1", mockedDefinition2);
+
+ result.put("n1", innerMultimap);
+
+ return result;
+ }
+
private static ServiceReferenceReadableRegistry mockServiceRegistry() {
ServiceReferenceReadableRegistry mock = mock(ServiceReferenceReadableRegistry.class);
doReturn(
return mock;
}
- static Services mockServices() {
- return new Services(mockServiceRegistry());
+ static ServiceRegistryWrapper mockServices() {
+ return new ServiceRegistryWrapper(mockServiceRegistry());
}
private Map<String, Multimap<String, ModuleElementResolved>> getMapping(EditConfigStrategy editStrat) {
-/**
- * @author Tomas Olvecky
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
*
- * 11 2013
- *
- * Copyright (c) 2013 by Cisco Systems, Inc.
- * 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.netconf.persist.impl.osgi;
--- /dev/null
+<rpc message-id="a" a="64" xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <edit-config>
+ <target>
+ <candidate/>
+ </target>
+ <test-option>
+ test-only
+ </test-option>
+ <default-operation>merge</default-operation>
+ <config>
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ <module>
+ <name>instance-from-code_dep</name>
+ <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+ test-impl:impl-dep
+ </type>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <service>
+ <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test">prefix:testing</type>
+ <instance>
+ <name>ref_dep_user_another_test1</name>
+ <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+ </provider>
+ </instance>
+ <instance>
+ <name>ref_dep_user_another_test2</name>
+ <provider>/modules/module[type='impl-dep'][name='instance-from-code_dep']
+ </provider>
+ </instance>
+ </service>
+ </services>
+ </config>
+ </edit-config>
+</rpc>
</type>
</module>
-
<module>
<type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
test-impl:impl-netconf
</type>
- <name>test1</name>
+ <name>instance-from-code</name>
<simple-long-2>44</simple-long-2>
<binaryLeaf>8ad1</binaryLeaf>
<dto_d>
<type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
test-impl:impl-netconf
</type>
- <name>test2</name>
+ <name>test3</name>
</module>
</modules>