X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fconfig-netconf-connector%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fconfignetconfconnector%2Foperations%2Fruntimerpc%2FRuntimeRpc.java;h=2be3308b90c801e89dff101e10a52360b04d6ee4;hp=f7d28b789e30d7f631f053249f46f09407901932;hb=refs%2Fchanges%2F13%2F23413%2F26;hpb=071a641d7c12c0e6112d5ce0afe806b54f116ed2 diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java index f7d28b789e..2be3308b90 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/operations/runtimerpc/RuntimeRpc.java @@ -10,32 +10,18 @@ package org.opendaylight.controller.netconf.confignetconfconnector.operations.ru import com.google.common.base.Optional; import com.google.common.base.Preconditions; -import com.google.common.collect.Maps; -import java.util.Map; -import javax.management.ObjectName; -import javax.management.openmbean.OpenType; -import org.opendaylight.controller.config.util.ConfigRegistryClient; -import org.opendaylight.controller.config.yangjmxgenerator.ModuleMXBeanEntry; -import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry; -import org.opendaylight.controller.config.yangjmxgenerator.RuntimeBeanEntry.Rpc; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.AttributeIfc; -import org.opendaylight.controller.config.yangjmxgenerator.attribute.VoidAttribute; -import org.opendaylight.controller.netconf.api.NetconfDocumentedException; +import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade; +import org.opendaylight.controller.config.facade.xml.RpcFacade; +import org.opendaylight.controller.config.facade.xml.rpc.InstanceRuntimeRpc; +import org.opendaylight.controller.config.facade.xml.rpc.ModuleRpcs; +import org.opendaylight.controller.config.facade.xml.rpc.Rpcs; +import org.opendaylight.controller.config.facade.xml.rpc.RuntimeRpcElementResolved; +import org.opendaylight.controller.config.util.xml.DocumentedException; +import org.opendaylight.controller.config.util.xml.XmlElement; +import org.opendaylight.controller.config.util.xml.XmlUtil; import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.fromxml.AttributeConfigElement; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.AttributeMappingStrategy; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.mapping.ObjectMapper; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.attributes.toxml.ObjectXmlWriter; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.InstanceRuntimeRpc; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.ModuleRpcs; -import org.opendaylight.controller.netconf.confignetconfconnector.mapping.rpc.Rpcs; import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.EnumResolver; -import org.opendaylight.controller.netconf.confignetconfconnector.osgi.YangStoreContext; import org.opendaylight.controller.netconf.mapping.api.HandlingPriority; -import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; -import org.opendaylight.controller.netconf.util.xml.XmlElement; -import org.opendaylight.controller.netconf.util.xml.XmlUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; @@ -44,83 +30,14 @@ import org.w3c.dom.Element; public class RuntimeRpc extends AbstractConfigNetconfOperation { private static final Logger LOG = LoggerFactory.getLogger(RuntimeRpc.class); - public static final String CONTEXT_INSTANCE = "context-instance"; - private final YangStoreContext yangStoreSnapshot; - - public RuntimeRpc(final YangStoreContext yangStoreSnapshot, ConfigRegistryClient configRegistryClient, - String netconfSessionIdForReporting) { - super(configRegistryClient, netconfSessionIdForReporting); - this.yangStoreSnapshot = yangStoreSnapshot; - } - - private Element toXml(Document doc, Object result, AttributeIfc returnType, String namespace, String elementName) throws NetconfDocumentedException { - AttributeMappingStrategy> mappingStrategy = new ObjectMapper().prepareStrategy(returnType); - Optional mappedAttributeOpt = mappingStrategy.mapAttribute(result); - Preconditions.checkState(mappedAttributeOpt.isPresent(), "Unable to map return value %s as %s", result, returnType.getOpenType()); - - // FIXME: multiple return values defined as leaf-list and list in yang should not be wrapped in output xml element, - // they need to be appended directly under rpc-reply element - // - // Either allow List of Elements to be returned from NetconfOperation or - // pass reference to parent output xml element for netconf operations to - // append result(s) on their own - Element tempParent = XmlUtil.createElement(doc, "output", Optional.of(XmlNetconfConstants.URN_IETF_PARAMS_XML_NS_NETCONF_BASE_1_0)); - new ObjectXmlWriter().prepareWritingStrategy(elementName, returnType, doc).writeElement(tempParent, namespace, mappedAttributeOpt.get()); - - XmlElement xmlElement = XmlElement.fromDomElement(tempParent); - return xmlElement.getChildElements().size() > 1 ? tempParent : xmlElement.getOnlyChildElement().getDomElement(); + public RuntimeRpc(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) { + super(configSubsystemFacade, netconfSessionIdForReporting); } - private Object executeOperation(final ConfigRegistryClient configRegistryClient, final ObjectName on, - final String name, final Map attributes) { - final Object[] params = new Object[attributes.size()]; - final String[] signature = new String[attributes.size()]; - - int i = 0; - for (final AttributeConfigElement attribute : attributes.values()) { - final Optional resolvedValueOpt = attribute.getResolvedValue(); - - params[i] = resolvedValueOpt.isPresent() ? resolvedValueOpt.get() : attribute.getResolvedDefaultValue(); - signature[i] = resolvedValueOpt.isPresent() ? resolvedValueOpt.get().getClass().getName() : attribute - .getResolvedDefaultValue().getClass().getName(); - i++; - } - - return configRegistryClient.invokeMethod(on, name, params, signature); - } - - public NetconfOperationExecution fromXml(final XmlElement xml) throws NetconfDocumentedException { - final String namespace; - try { - namespace = xml.getNamespace(); - } catch (MissingNameSpaceException e) { - LOG.trace("Can't get namespace from xml element due to ",e); - throw NetconfDocumentedException.wrap(e); - } - final XmlElement contextInstanceElement = xml.getOnlyChildElement(CONTEXT_INSTANCE); - final String operationName = xml.getName(); - - final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath( - contextInstanceElement.getTextContent(), operationName, namespace); - - final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap(), yangStoreSnapshot.getEnumResolver()); - - final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id); - final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(), operationName); - - // TODO move to Rpcs after xpath attribute is redesigned - - final ObjectName on = id.getObjectName(rpcMapping); - Map attributes = instanceRuntimeRpc.fromXml(xml); - attributes = sortAttributes(attributes, xml); - - return new NetconfOperationExecution(on, instanceRuntimeRpc.getName(), attributes, - instanceRuntimeRpc.getReturnType(), namespace); - } @Override - public HandlingPriority canHandle(Document message) throws NetconfDocumentedException { + public HandlingPriority canHandle(Document message) throws DocumentedException { XmlElement requestElement = null; requestElement = getRequestElementWithCheck(message); @@ -129,13 +46,13 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { final String netconfOperationNamespace; try { netconfOperationNamespace = operationElement.getNamespace(); - } catch (MissingNameSpaceException e) { + } catch (DocumentedException e) { LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e); return HandlingPriority.CANNOT_HANDLE; } final Optional contextInstanceElement = operationElement - .getOnlyChildElementOptionally(CONTEXT_INSTANCE); + .getOnlyChildElementOptionally(RpcFacade.CONTEXT_INSTANCE); if (!contextInstanceElement.isPresent()){ return HandlingPriority.CANNOT_HANDLE; @@ -145,16 +62,14 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { .getTextContent(), netconfOperationName, netconfOperationNamespace); // TODO reuse rpcs instance in fromXml method - final Rpcs rpcs = mapRpcs(yangStoreSnapshot.getModuleMXBeanEntryMap(), yangStoreSnapshot.getEnumResolver()); + final Rpcs rpcs = getConfigSubsystemFacade().getRpcFacade().mapRpcs(); try { - final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id); final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(), netconfOperationName); Preconditions.checkState(instanceRuntimeRpc != null, "No rpc found for %s:%s", netconfOperationNamespace, netconfOperationName); - } catch (IllegalStateException e) { LOG.debug("Cannot handle runtime operation {}:{}", netconfOperationNamespace, netconfOperationName, e); return HandlingPriority.CANNOT_HANDLE; @@ -175,103 +90,22 @@ public class RuntimeRpc extends AbstractConfigNetconfOperation { } @Override - protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws NetconfDocumentedException { + protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException { // TODO check for namespaces and unknown elements - final NetconfOperationExecution execution = fromXml(xml); + final RpcFacade.OperationExecution execution = getConfigSubsystemFacade().getRpcFacade().fromXml(xml); - LOG.debug("Invoking operation {} on {} with arguments {}", execution.operationName, execution.on, - execution.attributes); - final Object result = executeOperation(getConfigRegistryClient(), execution.on, execution.operationName, - execution.attributes); + LOG.debug("Invoking operation {} on {} with arguments {}", execution.getOperationName(), execution.getOn(), + execution.getAttributes()); + final Object result = getConfigSubsystemFacade().getRpcFacade().executeOperation(execution); - LOG.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.operationName, - execution.on, execution.attributes, result); + LOG.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.getOperationName(), + execution.getOn(), execution.getAttributes(), result); if (execution.isVoid()) { return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.absent()); } else { - return toXml(document, result, execution.returnType, execution.namespace, - execution.returnType.getAttributeYangName()); - } - } - - private static class NetconfOperationExecution { - - private final ObjectName on; - private final String operationName; - private final Map attributes; - private final AttributeIfc returnType; - private final String namespace; - - public NetconfOperationExecution(final ObjectName on, final String name, - final Map attributes, final AttributeIfc returnType, final String namespace) { - this.on = on; - this.operationName = name; - this.attributes = attributes; - this.returnType = returnType; - this.namespace = namespace; - } - - boolean isVoid() { - return returnType == VoidAttribute.getInstance(); + return getConfigSubsystemFacade().getRpcFacade().toXml(document, result, execution); } - - } - - private static Map sortAttributes( - final Map attributes, final XmlElement xml) { - final Map sorted = Maps.newLinkedHashMap(); - - for (XmlElement xmlElement : xml.getChildElements()) { - final String name = xmlElement.getName(); - if (!CONTEXT_INSTANCE.equals(name)) { // skip context - // instance child node - // because it - // specifies - // ObjectName - final AttributeConfigElement value = attributes.get(name); - if (value == null) { - throw new IllegalArgumentException("Cannot find yang mapping for node " + xmlElement); - } - sorted.put(name, value); - } - } - - return sorted; - } - - private static Rpcs mapRpcs(final Map> mBeanEntries, final EnumResolver enumResolver) { - - final Map> map = Maps.newHashMap(); - - for (final Map.Entry> namespaceToModuleEntry : mBeanEntries.entrySet()) { - - Map namespaceToModules = map.get(namespaceToModuleEntry.getKey()); - if (namespaceToModules == null) { - namespaceToModules = Maps.newHashMap(); - map.put(namespaceToModuleEntry.getKey(), namespaceToModules); - } - - for (final Map.Entry moduleEntry : namespaceToModuleEntry.getValue().entrySet()) { - - ModuleRpcs rpcMapping = namespaceToModules.get(moduleEntry.getKey()); - if (rpcMapping == null) { - rpcMapping = new ModuleRpcs(enumResolver); - namespaceToModules.put(moduleEntry.getKey(), rpcMapping); - } - - final ModuleMXBeanEntry entry = moduleEntry.getValue(); - - for (final RuntimeBeanEntry runtimeEntry : entry.getRuntimeBeans()) { - rpcMapping.addNameMapping(runtimeEntry); - for (final Rpc rpc : runtimeEntry.getRpcs()) { - rpcMapping.addRpc(runtimeEntry, rpc); - } - } - } - } - - return new Rpcs(map); } }