bbcdf28b6517277c1144570a1ca986144c631ad8
[netconf.git] / netconf / config-netconf-connector / src / main / java / org / opendaylight / 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.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.netconf.api.xml.XmlNetconfConstants;
23 import org.opendaylight.netconf.confignetconfconnector.operations.AbstractConfigNetconfOperation;
24 import org.opendaylight.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 = getRequestElementWithCheck(message);
42
43         XmlElement operationElement = requestElement.getOnlyChildElement();
44         final String netconfOperationName = operationElement.getName();
45         final String netconfOperationNamespace;
46         try {
47             netconfOperationNamespace = operationElement.getNamespace();
48         } catch (DocumentedException e) {
49             LOG.debug("Cannot retrieve netconf operation namespace from message due to ", e);
50             return HandlingPriority.CANNOT_HANDLE;
51         }
52
53         final Optional<XmlElement> contextInstanceElement = operationElement
54                 .getOnlyChildElementOptionally(RpcFacade.CONTEXT_INSTANCE);
55
56         if (!contextInstanceElement.isPresent()) {
57             return HandlingPriority.CANNOT_HANDLE;
58         }
59
60         final RuntimeRpcElementResolved id = RuntimeRpcElementResolved.fromXpath(contextInstanceElement.get()
61                 .getTextContent(), netconfOperationName, netconfOperationNamespace);
62
63         // TODO reuse rpcs instance in fromXml method
64         final Rpcs rpcs = getConfigSubsystemFacade().getRpcFacade().mapRpcs();
65
66         try {
67             final ModuleRpcs rpcMapping = rpcs.getRpcMapping(id);
68             final InstanceRuntimeRpc instanceRuntimeRpc = rpcMapping.getRpc(id.getRuntimeBeanName(),
69                     netconfOperationName);
70             Preconditions.checkState(instanceRuntimeRpc != null, "No rpc found for %s:%s", netconfOperationNamespace,
71                     netconfOperationName);
72         } catch (IllegalStateException e) {
73             LOG.debug("Cannot handle runtime operation {}:{}", netconfOperationNamespace, netconfOperationName, e);
74             return HandlingPriority.CANNOT_HANDLE;
75         }
76
77         return HandlingPriority.HANDLE_WITH_DEFAULT_PRIORITY;
78     }
79
80     @Override
81     protected HandlingPriority canHandle(String netconfOperationName, String namespace) {
82         throw new UnsupportedOperationException(
83                 "This should not be used since it is not possible to provide check with these attributes");
84     }
85
86     @Override
87     protected String getOperationName() {
88         throw new UnsupportedOperationException("Runtime rpc does not have a stable name");
89     }
90
91     @Override
92     protected Element handleWithNoSubsequentOperations(Document document, XmlElement xml) throws DocumentedException {
93         // TODO check for namespaces and unknown elements
94         final RpcFacade.OperationExecution execution = getConfigSubsystemFacade().getRpcFacade().fromXml(xml);
95
96         LOG.debug("Invoking operation {} on {} with arguments {}", execution.getOperationName(), execution.getOn(),
97                 execution.getAttributes());
98         final Object result = getConfigSubsystemFacade().getRpcFacade().executeOperation(execution);
99
100         LOG.trace("Operation {} called successfully on {} with arguments {} with result {}",
101                 execution.getOperationName(), execution.getOn(), execution.getAttributes(), result);
102
103         if (execution.isVoid()) {
104             return XmlUtil.createElement(document, XmlNetconfConstants.OK, Optional.absent());
105         } else {
106             return getConfigSubsystemFacade().getRpcFacade().toXml(document, result, execution);
107         }
108     }
109
110 }