1 package org.opendaylight.controller.sal.connect.netconf
3 import org.opendaylight.controller.sal.core.api.mount.MountProvisionInstance
4 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier
5 import org.opendaylight.controller.md.sal.common.api.data.DataReader
6 import org.opendaylight.yangtools.yang.data.api.CompositeNode
7 import org.opendaylight.controller.netconf.client.NetconfClient
8 import org.opendaylight.controller.sal.core.api.RpcImplementation
9 import static extension org.opendaylight.controller.sal.connect.netconf.NetconfMapping.*
10 import java.net.InetSocketAddress
11 import org.opendaylight.yangtools.yang.data.api.Node
12 import org.opendaylight.yangtools.yang.data.api.SimpleNode
13 import org.opendaylight.yangtools.yang.common.QName
14 import java.util.Collections
15 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher
16 import org.opendaylight.yangtools.concepts.Registration
17 import org.opendaylight.controller.sal.core.api.Provider
18 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession
19 import org.opendaylight.controller.sal.core.api.mount.MountProvisionService
20 import static org.opendaylight.controller.sal.connect.netconf.InventoryUtils.*;
21 import org.opendaylight.controller.sal.core.api.data.DataBrokerService
22 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction
23 import org.opendaylight.yangtools.yang.data.impl.SimpleNodeTOImpl
24 import org.opendaylight.yangtools.yang.data.impl.CompositeNodeTOImpl
26 class NetconfDevice implements Provider, DataReader<InstanceIdentifier, CompositeNode>, RpcImplementation, AutoCloseable {
28 var NetconfClient client;
31 var InetSocketAddress socketAddress;
34 var MountProvisionInstance mountInstance;
37 var InstanceIdentifier path;
39 Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
41 Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
45 MountProvisionService mountService
47 public new(String name) {
49 this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
50 Collections.singletonMap(INVENTORY_ID, name)).toInstance;
53 def start(NetconfClientDispatcher dispatcher) {
54 client = new NetconfClient(name, socketAddress, dispatcher);
55 confReaderReg = mountInstance.registerConfigurationReader(path, this);
56 operReaderReg = mountInstance.registerOperationalReader(path, this);
59 override readConfigurationData(InstanceIdentifier path) {
60 val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, path.toFilterStructure()));
61 val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
62 return data?.findNode(path) as CompositeNode;
65 override readOperationalData(InstanceIdentifier path) {
66 val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure()));
67 val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
68 return data?.findNode(path) as CompositeNode;
71 override getSupportedRpcs() {
75 override invokeRpc(QName rpc, CompositeNode input) {
76 val message = rpc.toRpcMessage(input);
77 val result = client.sendMessage(message);
78 return result.toRpcResult();
81 override getProviderFunctionality() {
85 override onSessionInitiated(ProviderSession session) {
86 val dataBroker = session.getService(DataBrokerService);
90 val transaction = dataBroker.beginTransaction
91 if(transaction.operationalNodeNotExisting) {
92 transaction.putOperationalData(path,nodeWithId)
94 if(transaction.configurationNodeNotExisting) {
95 transaction.putConfigurationData(path,nodeWithId)
97 transaction.commit().get();
98 mountService = session.getService(MountProvisionService);
99 mountInstance = mountService.createOrGetMountPoint(path);
102 def getNodeWithId() {
103 val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
104 return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
107 def boolean configurationNodeNotExisting(DataModificationTransaction transaction) {
108 return null === transaction.readConfigurationData(path);
111 def boolean operationalNodeNotExisting(DataModificationTransaction transaction) {
112 return null === transaction.readOperationalData(path);
115 def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
117 var Node<?> current = node;
118 for (arg : identifier.path) {
119 if (current instanceof SimpleNode<?>) {
121 } else if (current instanceof CompositeNode) {
122 val currentComposite = (current as CompositeNode);
124 current = currentComposite.getFirstCompositeByName(arg.nodeType);
125 if (current == null) {
126 current = currentComposite.getFirstSimpleByName(arg.nodeType);
128 if (current == null) {
137 confReaderReg?.close()
138 operReaderReg?.close()