return caseJavaBinaryAttribute(openType);
} else if(((JavaAttribute)attributeIfc).isUnion()) {
return caseJavaUnionAttribute(openType);
+ } else if(((JavaAttribute)attributeIfc).isIdentityRef()) {
+ return caseJavaIdentityRefAttribute(openType);
} else
return caseJavaAttribute(openType);
} catch (UnknownOpenTypeException e) {
throw getIllegalArgumentException(attributeIfc);
}
+ protected T caseJavaIdentityRefAttribute(OpenType<?> openType) {
+ return caseJavaAttribute(openType);
+ }
+
protected T caseJavaUnionAttribute(OpenType<?> openType) {
return caseJavaAttribute(openType);
}
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.operations.editconfig.EditConfig;
import javax.management.openmbean.ArrayType;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
+import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
public class ObjectXmlReader extends AttributeIfcSwitchStatement<AttributeReadingStrategy> {
private String key;
+ private Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
- public Map<String, AttributeReadingStrategy> prepareReading(Map<String, AttributeIfc> yangToAttrConfig) {
+ public Map<String, AttributeReadingStrategy> prepareReading(Map<String, AttributeIfc> yangToAttrConfig, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
Map<String, AttributeReadingStrategy> strategies = Maps.newHashMap();
+ this.identityMap = identityMap;
for (Entry<String, AttributeIfc> attributeEntry : yangToAttrConfig.entrySet()) {
AttributeReadingStrategy strat = prepareReadingStrategy(attributeEntry.getKey(), attributeEntry.getValue());
return new SimpleCompositeAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey);
}
+ @Override
+ protected AttributeReadingStrategy caseJavaIdentityRefAttribute(OpenType<?> openType) {
+ Preconditions.checkState(openType instanceof CompositeType);
+ Set<String> keys = ((CompositeType) openType).keySet();
+ Preconditions.checkState(keys.size() == 1, "Unexpected number of elements for open type %s, should be 1", openType);
+ String mappingKey = keys.iterator().next();
+ return new SimpleIdentityRefAttributeReadingStrategy(lastAttribute.getNullableDefault(), mappingKey, identityMap);
+ }
+
@Override
protected AttributeReadingStrategy caseDependencyAttribute(SimpleType<?> openType) {
return new ObjectNameAttributeReadingStrategy(lastAttribute.getNullableDefault());
String textContent = "";
try{
- textContent = xmlElement.getTextContent();
+ textContent = readElementContent(xmlElement);
}catch(IllegalStateException | NullPointerException e) {
// yuma sends <attribute /> for empty value instead of <attribute></attribute>
logger.warn("Ignoring exception caused by failure to read text element", e);
postprocessParsedValue(textContent));
}
+ protected String readElementContent(XmlElement xmlElement) {
+ return xmlElement.getTextContent();
+ }
+
@Override
protected Object postprocessNullableDefault(String nullableDefault) {
return nullableDefault;
super(nullableDefault);
}
+ @Override
protected Object postprocessParsedValue(String textContent) {
BaseEncoding en = BaseEncoding.base64();
byte[] decode = en.decode(textContent);
this.key = key;
}
+ @Override
protected Object postprocessParsedValue(String textContent) {
HashMap<String,String> map = Maps.newHashMap();
map.put(key, textContent);
--- /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.fromxml;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Maps;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
+import org.opendaylight.controller.netconf.util.xml.XmlElement;
+import org.opendaylight.yangtools.yang.common.QName;
+
+
+public class SimpleIdentityRefAttributeReadingStrategy extends SimpleAttributeReadingStrategy {
+
+ private final String key;
+ private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
+
+ public SimpleIdentityRefAttributeReadingStrategy(String nullableDefault, String key, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
+ super(nullableDefault);
+ this.key = key;
+ this.identityMap = identityMap;
+ }
+
+ @Override
+ protected String readElementContent(XmlElement xmlElement) {
+ // TODO test
+ Map.Entry<String, String> namespaceOfTextContent = xmlElement.findNamespaceOfTextContent();
+ String content = xmlElement.getTextContent();
+
+ String prefix = namespaceOfTextContent.getKey() + ":";
+ Preconditions.checkArgument(content.startsWith(prefix), "Identity ref should be prefixed");
+
+ String localName = content.substring(prefix.length());
+ String namespace = namespaceOfTextContent.getValue();
+
+ Date revision = null;
+ Map<Date, EditConfig.IdentityMapping> revisions = identityMap.get(namespace);
+ if(revisions.keySet().size() > 1) {
+ for (Date date : revisions.keySet()) {
+ if(revisions.get(date).containsIdName(localName)) {
+ Preconditions.checkState(revision == null, "Duplicate identity %s, in namespace %s, with revisions: %s, %s detected. Cannot map attribute",
+ localName, namespace, revision, date);
+ revision = date;
+ }
+ }
+ } else
+ revision = revisions.keySet().iterator().next();
+
+
+ return QName.create(URI.create(namespace), revision, localName).toString();
+ }
+
+ @Override
+ protected Object postprocessParsedValue(String textContent) {
+ HashMap<String,String> map = Maps.newHashMap();
+ map.put(key, textContent);
+ return map;
+ }
+
+ @Override
+ protected Object postprocessNullableDefault(String nullableDefault) {
+ return nullableDefault == null ? null : postprocessParsedValue(nullableDefault);
+ }
+}
this.key = key;
}
+ @Override
protected Object postprocessParsedValue(String textContent) {
char[] charArray = textContent.toCharArray();
List<String> chars = Lists.newArrayListWithCapacity(charArray.length);
return new ArrayAttributeWritingStrategy(innerStrategy);
}
+ @Override
+ protected AttributeWritingStrategy caseJavaIdentityRefAttribute(OpenType<?> openType) {
+ return new SimpleIdentityRefAttributeWritingStrategy(document, key);
+ }
+
@Override
protected AttributeWritingStrategy caseJavaCompositeAttribute(CompositeType openType) {
return new SimpleCompositeAttributeWritingStrategy(document, key);
public void writeElement(Element parentElement, String namespace, Object value) {
value = preprocess(value);
Util.checkType(value, String.class);
- Element innerNode = XmlUtil.createTextElement(document, key, (String) value);
+ Element innerNode = createElement(document, key, (String) value);
XmlUtil.addNamespaceAttr(innerNode, namespace);
parentElement.appendChild(innerNode);
}
+ protected Element createElement(Document document, String key, String value) {
+ return XmlUtil.createTextElement(document, key, (String) value);
+ }
+
protected Object preprocess(Object value) {
return value;
}
--- /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.toxml;
+
+import java.util.Map;
+
+import org.opendaylight.controller.netconf.confignetconfconnector.util.Util;
+import org.opendaylight.controller.netconf.util.xml.XmlUtil;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.w3c.dom.Document;
+
+import com.google.common.base.Preconditions;
+import org.w3c.dom.Element;
+
+public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWritingStrategy {
+
+ private static final char QNAME_SEPARATOR = ':';
+ private static final String PREFIX = "prefix";
+
+ /**
+ * @param document
+ * @param key
+ */
+ public SimpleIdentityRefAttributeWritingStrategy(Document document, String key) {
+ super(document, key);
+ }
+
+ protected Object preprocess(Object value) {
+ Util.checkType(value, Map.class);
+ Preconditions.checkArgument(((Map)value).size() == 1, "Unexpected number of values in %s, expected 1", value);
+ Object stringValue = ((Map) value).values().iterator().next();
+ Util.checkType(stringValue, String.class);
+
+ return stringValue;
+ }
+
+ @Override
+ protected Element createElement(Document doc, String key, String value) {
+ QName qName = QName.create(value);
+ String identity = qName.getLocalName();
+ Element element = XmlUtil.createPrefixedTextElement(doc, key, PREFIX, identity);
+
+ String identityNamespace = qName.getNamespace().toString();
+ XmlUtil.addPrefixedNamespaceAttr(element, PREFIX, identityNamespace);
+ return element;
+ }
+}
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.EditConfig;
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 javax.management.ObjectName;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Map<String /* Name of module entry from yang file */, ModuleConfig>> moduleConfigs;
private final Map<String, ModuleConfig> moduleNamesToConfigs;
+ private final Map<String, Map<Date, EditConfig.IdentityMapping>> identityMap;
+
public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs) {
+ this(moduleConfigs, Collections.<String, Map<Date, EditConfig.IdentityMapping>>emptyMap());
+ }
+
+ public Config(Map<String, Map<String, ModuleConfig>> moduleConfigs, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
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);
+ this.identityMap = identityMap;
}
public static Map<String, Map<String, Collection<ObjectName>>> getMappedInstances(Set<ObjectName> instancesToMap,
@Override
public ModuleElementResolved resolveElement(ModuleConfig moduleMapping, XmlElement moduleElement, ServiceRegistryWrapper serviceTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy) {
return moduleMapping.fromXml(moduleElement, serviceTracker,
- instanceName, moduleNamespace, defaultStrategy);
+ instanceName, moduleNamespace, defaultStrategy, identityMap);
}
};
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.EditConfig;
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 javax.management.ObjectName;
import javax.management.openmbean.OpenType;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
}
public InstanceConfigElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper services, String moduleNamespace,
- EditStrategyType defaultStrategy, Multimap<String, String> providedServices) {
+ EditStrategyType defaultStrategy, Multimap<String, String> providedServices, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
- Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig);
+ Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig, identityMap);
List<XmlElement> recognisedChildren = Lists.newArrayList();
XmlElement type = moduleElement.getOnlyChildElementWithSameNamespace(XmlNetconfConstants.TYPE_KEY);
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.jmx.ObjectNameUtil;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
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 javax.management.ObjectName;
import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
public class ModuleConfig {
}
public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName,
- String moduleNamespace, EditStrategyType defaultStrategy) {
+ String moduleNamespace, EditStrategyType defaultStrategy, Map<String, Map<Date,EditConfig.IdentityMapping>> identityMap) {
- InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices);
+ InstanceConfigElementResolved ice = instanceConfig.fromXml(moduleElement, depTracker, moduleNamespace, defaultStrategy, providedServices, identityMap);
return new ModuleElementResolved(instanceName, ice);
}
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.opendaylight.controller.config.api.ServiceReferenceReadableRegistry;
+import org.opendaylight.yangtools.yang.common.QName;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
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 {
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();
+ QName qname = QName.create(serviceQName);
+ 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();
+ String localName = qname.getLocalName();
Map<String, String> refsToSis = serviceToRefs.get(localName);
if(refsToSis==null) {
refsToSis = Maps.newHashMap();
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.ObjectXmlReader;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.AttributeResolvingStrategy;
import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.resolving.ObjectResolver;
+import org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig.EditConfig;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import javax.management.openmbean.OpenType;
+import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public Map<String, AttributeConfigElement> fromXml(XmlElement configRootNode) {
Map<String, AttributeConfigElement> retVal = Maps.newHashMap();
- Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig);
+ // FIXME add identity map to runtime data
+ Map<String, AttributeReadingStrategy> strats = new ObjectXmlReader().prepareReading(yangToAttrConfig,
+ Collections.<String, Map<Date, EditConfig.IdentityMapping>> emptyMap());
for (Entry<String, AttributeReadingStrategy> readStratEntry : strats.entrySet()) {
List<XmlElement> configNodes = configRootNode.getChildElements(readStratEntry.getKey());
package org.opendaylight.controller.netconf.confignetconfconnector.operations.editconfig;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import org.opendaylight.controller.config.api.JmxAttributeValidationException;
import org.opendaylight.controller.netconf.confignetconfconnector.transactions.TransactionProvider;
import org.opendaylight.controller.netconf.util.xml.XmlElement;
import org.opendaylight.controller.netconf.util.xml.XmlNetconfConstants;
+import org.opendaylight.yangtools.yang.model.api.IdentitySchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import javax.management.InstanceNotFoundException;
import javax.management.ObjectName;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Set;
public class EditConfig extends AbstractConfigNetconfOperation {
}
}
- public static Config getConfigMapping(ConfigRegistryClient configRegistryClient,
- Map<String/* Namespace from yang file */,
- Map<String /* Name of module entry from yang file */, ModuleMXBeanEntry>> mBeanEntries) {
- Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient, mBeanEntries);
+ public static Config getConfigMapping(ConfigRegistryClient configRegistryClient, YangStoreSnapshot yangStoreSnapshot) {
+ Map<String, Map<String, ModuleConfig>> factories = transformMbeToModuleConfigs(configRegistryClient,
+ yangStoreSnapshot.getModuleMXBeanEntryMap());
+ Map<String, Map<Date, IdentityMapping>> identitiesMap = transformIdentities(yangStoreSnapshot.getModules());
+ return new Config(factories, identitiesMap);
+ }
+
+
+ public static class IdentityMapping {
+ private final Map<String, IdentitySchemaNode> identityNameToSchemaNode;
+
+ IdentityMapping() {
+ this.identityNameToSchemaNode = Maps.newHashMap();
+ }
- return new Config(factories);
+ void addIdSchemaNode(IdentitySchemaNode node) {
+ String name = node.getQName().getLocalName();
+ Preconditions.checkState(identityNameToSchemaNode.containsKey(name) == false);
+ identityNameToSchemaNode.put(name, node);
+ }
+
+ public boolean containsIdName(String idName) {
+ return identityNameToSchemaNode.containsKey(idName);
+ }
+
+ public IdentitySchemaNode getIdentitySchemaNode(String idName) {
+ Preconditions.checkState(identityNameToSchemaNode.containsKey(idName), "No identity under name %s", idName);
+ return identityNameToSchemaNode.get(idName);
+ }
+ }
+
+ private static Map<String, Map<Date, IdentityMapping>> transformIdentities(Set<Module> modules) {
+ Map<String, Map<Date, IdentityMapping>> mappedIds = Maps.newHashMap();
+ for (Module module : modules) {
+ String namespace = module.getNamespace().toString();
+ Map<Date, IdentityMapping> revisionsByNamespace= mappedIds.get(namespace);
+ if(revisionsByNamespace == null) {
+ revisionsByNamespace = Maps.newHashMap();
+ mappedIds.put(namespace, revisionsByNamespace);
+ }
+
+ Date revision = module.getRevision();
+ Preconditions.checkState(revisionsByNamespace.containsKey(revision) == false,
+ "Duplicate revision %s for namespace %s", revision, namespace);
+
+ IdentityMapping identityMapping = revisionsByNamespace.get(revision);
+ if(identityMapping == null) {
+ identityMapping = new IdentityMapping();
+ revisionsByNamespace.put(revision, identityMapping);
+ }
+
+ for (IdentitySchemaNode identitySchemaNode : module.getIdentities()) {
+ identityMapping.addIdSchemaNode(identitySchemaNode);
+ }
+
+ }
+
+ return mappedIds;
}
public static Map<String/* Namespace from yang file */,
protected Element handle(Document document, XmlElement xml) throws NetconfDocumentedException {
EditConfigXmlParser.EditConfigExecution editConfigExecution;
- Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot.getModuleMXBeanEntryMap());
+ Config cfg = getConfigMapping(configRegistryClient, yangStoreSnapshot);
try {
editConfigExecution = editConfigXmlParser.fromXml(xml, cfg, transactionProvider, configRegistryClient);
} catch (IllegalStateException e) {
return getResponseInternal(document, editConfigExecution);
}
+
}
package org.opendaylight.controller.netconf.confignetconfconnector;
-import com.google.common.base.Optional;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.ObjectName;
+import javax.xml.parsers.ParserConfigurationException;
+
import org.apache.commons.lang3.StringUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.opendaylight.controller.config.yang.test.impl.DtoAInnerInner;
import org.opendaylight.controller.config.yang.test.impl.DtoC;
import org.opendaylight.controller.config.yang.test.impl.DtoD;
+import org.opendaylight.controller.config.yang.test.impl.IdentityTestModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleFactory;
import org.opendaylight.controller.config.yang.test.impl.NetconfTestImplModuleMXBean;
import org.opendaylight.controller.config.yang.test.impl.Peers;
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.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.test.impl.rev130403.TestIdentity2;
+import org.opendaylight.yangtools.yang.data.impl.codec.CodecRegistry;
+import org.opendaylight.yangtools.yang.data.impl.codec.IdentityCodec;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.ObjectName;
-import javax.xml.parsers.ParserConfigurationException;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.math.BigInteger;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
+import com.google.common.base.Optional;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
public class NetconfMappingTest extends AbstractConfigTest {
private static final String NETCONF_SESSION_ID = "foo";
private NetconfTestImplModuleFactory factory;
private DepTestImplModuleFactory factory2;
+ private IdentityTestModuleFactory factory3;
@Mock
YangStoreSnapshot yangStoreSnapshot;
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
doReturn(getMbes()).when(this.yangStoreSnapshot).getModuleMXBeanEntryMap();
+ doReturn(getModules()).when(this.yangStoreSnapshot).getModules();
+
this.factory = new NetconfTestImplModuleFactory();
this.factory2 = new DepTestImplModuleFactory();
- super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2));
+ this.factory3 = new IdentityTestModuleFactory();
+ super.initConfigTransactionManagerImpl(new HardcodedModuleFactoriesResolver(this.factory, this.factory2,
+ this.factory3));
transactionProvider = new TransactionProvider(this.configRegistryClient, NETCONF_SESSION_ID);
}
return on;
}
+ @Test
+ public void testIdentityRefs() throws Exception {
+ edit("netconfMessages/editConfig_identities.xml");
+
+ commit();
+ getConfigRunning();
+ }
+
+ @Override
+ protected CodecRegistry getCodecRegistry() {
+ IdentityCodec<?> idCodec = mock(IdentityCodec.class);
+ doReturn(TestIdentity1.class).when(idCodec).deserialize(TestIdentity1.QNAME);
+ doReturn(TestIdentity2.class).when(idCodec).deserialize(TestIdentity2.QNAME);
+
+ CodecRegistry codecReg = super.getCodecRegistry();
+ doReturn(idCodec).when(codecReg).getIdentityCodec();
+ return codecReg;
+ }
+
@Test
public void testServicePersistance() throws Exception {
createModule(INSTANCE_NAME);
edit("netconfMessages/editConfig.xml");
Element configCandidate = getConfigCandidate();
- System.err.println(XmlUtil.toString(configCandidate));
checkBinaryLeafEdited(configCandidate);
return mBeanEntries;
}
+ private Set<org.opendaylight.yangtools.yang.model.api.Module> getModules() throws Exception {
+ SchemaContext resolveSchemaContext = getSchemaContext();
+ return resolveSchemaContext.getModules();
+ }
+
+ private SchemaContext getSchemaContext() throws Exception {
+ final List<InputStream> yangDependencies = getYangs();
+ YangParserImpl parser = new YangParserImpl();
+
+ Set<Module> allYangModules = parser.parseYangModelsFromStreams(yangDependencies);
+
+ return parser.resolveSchemaContext(Sets
+ .newHashSet(allYangModules));
+ }
+
@Test
public void testConfigNetconfRuntime() throws Exception {
root.setAttribute(concat(XMLNS_ATTRIBUTE_KEY, prefix), namespace);
}
- public static Element createPrefixedTextElement(Document document, String key, String prefix, String moduleName) {
- return createTextElement(document, key, concat(prefix, moduleName));
+ public static Element createPrefixedTextElement(Document document, String key, String prefix, String content) {
+ return createTextElement(document, key, concat(prefix, content));
}
private static String concat(String prefix, String value) {
--- /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>
+ set
+ </test-option>
+ <default-operation>merge</default-operation>
+ <config>
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:test-impl="urn:opendaylight:params:xml:ns:yang:controller:test:impl">
+ test-impl:impl-identity-test
+ </type>
+ <name>id-test</name>
+ <identities>
+ <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:test-identity1</afi>
+ <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:test-identity2</safi>
+ </identities>
+ <identities>
+ <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:test-identity2</afi>
+ <safi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:test-identity1</safi>
+ </identities>
+ <identities-container>
+ <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:test-identity2</afi>
+ </identities-container>
+ <afi xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:test:impl">prefix:test-identity1</afi>
+ </module>
+ </modules>
+
+ <services xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+
+ </services>
+ </config>
+ </edit-config>
+</rpc>