Decouple config and netconf subsystems.
[controller.git] / opendaylight / netconf / config-netconf-connector / src / main / java / org / opendaylight / controller / netconf / confignetconfconnector / operations / runtimerpc / RuntimeRpc.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.controller.netconf.confignetconfconnector.operations.runtimerpc;
10
11 import com.google.common.base.Optional;
12 import com.google.common.base.Preconditions;
13 import org.opendaylight.controller.config.facade.xml.ConfigSubsystemFacade;
14 import org.opendaylight.controller.config.facade.xml.RpcFacade;
15 import org.opendaylight.controller.config.facade.xml.rpc.InstanceRuntimeRpc;
16 import org.opendaylight.controller.config.facade.xml.rpc.ModuleRpcs;
17 import org.opendaylight.controller.config.facade.xml.rpc.Rpcs;
18 import org.opendaylight.controller.config.facade.xml.rpc.RuntimeRpcElementResolved;
19 import org.opendaylight.controller.config.util.xml.DocumentedException;
20 import org.opendaylight.controller.config.util.xml.XmlElement;
21 import org.opendaylight.controller.config.util.xml.XmlUtil;
22 import org.opendaylight.controller.netconf.api.xml.XmlNetconfConstants;
23 import org.opendaylight.controller.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
24 import org.opendaylight.controller.netconf.mapping.api.HandlingPriority;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
27 import org.w3c.dom.Document;
28 import org.w3c.dom.Element;
29
30 public class RuntimeRpc extends AbstractConfigNetconfOperation {
31
32     private static final Logger LOG = LoggerFactory.getLogger(RuntimeRpc.class);
33
34     public RuntimeRpc(final ConfigSubsystemFacade configSubsystemFacade, final String netconfSessionIdForReporting) {
35         super(configSubsystemFacade, netconfSessionIdForReporting);
36     }
37
38
39     @Override
40     public HandlingPriority canHandle(Document message) throws DocumentedException {
41         XmlElement requestElement = null;
42         requestElement = getRequestElementWithCheck(message);
43
44         XmlElement operationElement = requestElement.getOnlyChildElement();
45         final String netconfOperationName = operationElement.getName();
46         final String netconfOperationNamespace;
47         try {
48             netconfOperationNamespace = operationElement.getNamespace();
49         } catch (DocumentedException e) {
50             LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e);
51             return HandlingPriority.CANNOT_HANDLE;
52         }
53
54         final Optional<XmlElement> contextInstanceElement = operationElement
55                 .getOnlyChildElementOptionally(RpcFacade.CONTEXT_INSTANCE);
56
57         if (!contextInstanceElement.isPresent()){
58             return HandlingPriority.CANNOT_HANDLE;
59         }
60
61         final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
62                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
63
64         // TODO reuse rpcs instance in fromXml method
65         final Rpcs rpcs = getConfigSubsystemFacade().getRpcFacade().mapRpcs();
66
67         try {
68             final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id);
69             final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(),
70                     netconfOperationName);
71             Preconditions.checkState(instanceRuntimeRpc != null, "No rpc found for %s:%s", netconfOperationNamespace,
72                     netconfOperationName);
73         } catch (IllegalStateException e) {
74             LOG.debug("Cannot handle runtime operation {}:{}", netconfOperationNamespace, netconfOperationName, e);
75             return HandlingPriority.CANNOT_HANDLE;
76         }
77
78         return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
79     }
80
81     @Override
82     protected HandlingPriority canHandle(String netconfOperationName, String namespace) {
83         throw new UnsupportedOperationException(
84                 "This should not be used since it is not possible to provide check with these attributes");
85     }
86
87     @Override
88     protected String getOperationName() {
89         throw new UnsupportedOperationException("Runtime rpc does not have a stable name");
90     }
91
92     @Override
93     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
94         // TODO check for namespaces and unknown elements
95         final RpcFacade.OperationExecution execution = getConfigSubsystemFacade().getRpcFacade().fromXml(xml);
96
97         LOG.debug("Invoking operation {} on {} with arguments {}", execution.getOperationName(), execution.getOn(),
98                 execution.getAttributes());
99         final Object result = getConfigSubsystemFacade().getRpcFacade().executeOperation(execution);
100
101         LOG.trace("Operation {} called successfully on {} with arguments {} with result {}", execution.getOperationName(),
102                 execution.getOn(), execution.getAttributes(), result);
103
104         if (execution.isVoid()) {
105             return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.<String>absent());
106         } else {
107             return getConfigSubsystemFacade().getRpcFacade().toXml(document, result, execution);
108         }
109     }
110
111 }