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.*;
+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<String, Map<String, ModuleConfig>> moduleConfigs;
+ private final Map<String/* Namespace from yang file */,
+ Map<String /* Name of module entry from yang file */, ModuleConfig>> moduleConfigs;
+ private final Map<String, ModuleConfig> moduleNamesToConfigs;
public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs) {
this.moduleConfigs = moduleConfigs;
+ Map<String, ModuleConfig> moduleNamesToConfigs = new HashMap<>();
+ for (Entry<String, Map<String, ModuleConfig>> entry : moduleConfigs.entrySet()) {
+ moduleNamesToConfigs.putAll(entry.getValue());
+ }
+ this.moduleNamesToConfigs = Collections.unmodifiableMap(moduleNamesToConfigs);
}
- private Map<String, Map<String, Collection<ObjectName>>> getMappedInstances(Set<ObjectName> instancesToMap,
- Services serviceTracker) {
+ public static Map<String, Map<String, Collection<ObjectName>>> getMappedInstances(Set<ObjectName> instancesToMap,
+ Services serviceTracker, Map<String, Map<String, ModuleConfig>> configs) {
Multimap<String, ObjectName> moduleToInstances = mapInstancesToModules(instancesToMap);
Map<String, Map<String, Collection<ObjectName>>> retVal = Maps.newLinkedHashMap();
- for (String namespace : moduleConfigs.keySet()) {
+ for (String namespace : configs.keySet()) {
Map<String, Collection<ObjectName>> innerRetVal = Maps.newHashMap();
- for (Entry<String, ModuleConfig> mbeEntry : moduleConfigs.get(namespace).entrySet()) {
+ for (Entry<String, ModuleConfig> mbeEntry : configs.get(namespace).entrySet()) {
String moduleName = mbeEntry.getKey();
Collection<ObjectName> instances = moduleToInstances.get(moduleName);
+ // TODO, this code does not support same module names from different namespaces
+ // Namespace should be present in ObjectName
+
if (instances == null)
continue;
// 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());
return retVal;
}
- private void addServices(Services serviceTracker, Collection<ObjectName> instances,
- Collection<String> providedServices) {
+ private static void addServices(Services serviceTracker, Collection<ObjectName> instances,
+ Multimap<String, String> providedServices) {
for (ObjectName instanceOn : instances) {
- for (String serviceName : providedServices) {
- serviceTracker.addServiceEntry(serviceName, instanceOn);
+ for (Entry<String, String> serviceName : providedServices.entries()) {
+ serviceTracker.addServiceEntry(serviceName.getKey(), serviceName.getValue(), instanceOn);
}
}
}
Services serviceTracker = new Services();
Map<String, Map<String, Collection<ObjectName>>> moduleToInstances = getMappedInstances(instancesToMap,
- serviceTracker);
+ serviceTracker, moduleConfigs);
Element root = dataElement;
if (maybeNamespace.isPresent()) {
return root;
}
+ // TODO remove commented modules from output
private void addEmptyModulesCommented(Document document, Element root, String moduleNamespace,
Entry<String, Collection<ObjectName>> moduleMappingEntry) {
Element emptyModule = document.createElement(XmlNetconfConstants.MODULE_KEY);
// TODO refactor, replace string representing namespace with namespace class
// TODO refactor, replace Map->Multimap with e.g. ConfigElementResolved
// class
- public Map<String, Multimap<String, ModuleElementResolved>> fromXml(XmlElement xml) {
+ public Map<String, Multimap<String, ModuleElementResolved>> fromXml(XmlElement xml, Set<ObjectName> instancesForFillingServiceRefMapping,
+ EditStrategyType defaultEditStrategyType) {
Map<String, Multimap<String, ModuleElementResolved>> retVal = Maps.newHashMap();
List<XmlElement> recognisedChildren = Lists.newArrayList();
- Services serviceTracker = fromXmlServices(xml, recognisedChildren);
+ Services serviceTracker = fromXmlServices(xml, recognisedChildren, instancesForFillingServiceRefMapping);
List<XmlElement> moduleElements = fromXmlModules(xml, recognisedChildren);
xml.checkUnrecognisedElements(recognisedChildren);
for (XmlElement moduleElement : moduleElements) {
- resolveModule(retVal, serviceTracker, moduleElement);
+ resolveModule(retVal, serviceTracker, moduleElement, defaultEditStrategyType);
}
return retVal;
}
private void resolveModule(Map<String, Multimap<String, ModuleElementResolved>> retVal, Services serviceTracker,
- XmlElement moduleElement) {
+ XmlElement moduleElement, EditStrategyType defaultStrategy) {
XmlElement typeElement = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
Entry<String, String> prefixToNamespace = typeElement.findNamespaceOfTextContent();
String moduleNamespace = prefixToNamespace.getValue();
}
ModuleElementResolved moduleElementResolved = moduleMapping.fromXml(moduleElement, serviceTracker,
- instanceName, moduleNamespace);
+ instanceName, moduleNamespace, defaultStrategy);
innerMap.put(factoryName, moduleElementResolved);
}
- private Services fromXmlServices(XmlElement xml, List<XmlElement> recognisedChildren) {
+ private Services fromXmlServices(XmlElement xml, List<XmlElement> recognisedChildren, Set<ObjectName> instancesForFillingServiceRefMapping) {
Optional<XmlElement> servicesElement = xml.getOnlyChildElementOptionally(XmlNetconfConstants.SERVICES_KEY,
XmlNetconfConstants.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG);
- Map<String, Map<String, String>> mappedServices;
+ Map<String, Map<String, Map<String, String>>> mappedServices;
if (servicesElement.isPresent()) {
mappedServices = Services.fromXml(servicesElement.get());
recognisedChildren.add(servicesElement.get());
} 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<String> services = ;
+ for (Entry<String, String> serviceName : moduleConfig.getProvidedServices().entries()) {
+
+ services.addServiceEntry(serviceName.getKey(), serviceName.getValue(), existingON);
+ }
+ }
- return Services.resolveServices(mappedServices);
+ return services;
}
private String getFactoryName(String factoryNameWithPrefix, String prefixOrEmptyString) {