Merge "Fixed sal-netconf-connector readConfiguration"
[controller.git] / opendaylight / md-sal / sal-netconf-connector / src / main / java / org / opendaylight / controller / sal / connect / netconf / NetconfDevice.xtend
1 package org.opendaylight.controller.sal.connect.netconf
2
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
25 import org.opendaylight.protocol.framework.ReconnectStrategy
26 import org.opendaylight.controller.md.sal.common.api.data.DataCommitHandler
27 import org.opendaylight.controller.md.sal.common.api.data.DataModification
28
29 class NetconfDevice implements 
30     Provider, // 
31     DataReader<InstanceIdentifier, CompositeNode>, //
32     DataCommitHandler<InstanceIdentifier, CompositeNode>, //
33     RpcImplementation, //
34     AutoCloseable {
35
36     var NetconfClient client;
37
38     @Property
39     var InetSocketAddress socketAddress;
40
41     @Property
42     var MountProvisionInstance mountInstance;
43
44     @Property
45     var InstanceIdentifier path;
46
47     @Property
48     var ReconnectStrategy strategy;
49
50     Registration<DataReader<InstanceIdentifier, CompositeNode>> operReaderReg
51     Registration<DataReader<InstanceIdentifier, CompositeNode>> confReaderReg
52     Registration<DataCommitHandler<InstanceIdentifier, CompositeNode>> commitHandlerReg
53     
54     val String name
55     MountProvisionService mountService
56     
57     
58     public new(String name) {
59         this.name = name;
60         this.path = InstanceIdentifier.builder(INVENTORY_PATH).nodeWithKey(INVENTORY_NODE,
61             Collections.singletonMap(INVENTORY_ID, name)).toInstance;
62     }
63
64     def start(NetconfClientDispatcher dispatcher) {
65         client = NetconfClient.clientFor(name, socketAddress, strategy, dispatcher);
66         confReaderReg = mountInstance.registerConfigurationReader(path, this);
67         operReaderReg = mountInstance.registerOperationalReader(path, this);
68         //commitHandlerReg = mountInstance.registerCommitHandler(path,this);
69     }
70
71     override readConfigurationData(InstanceIdentifier path) {
72         val result = invokeRpc(NETCONF_GET_CONFIG_QNAME, wrap(NETCONF_GET_CONFIG_QNAME, CONFIG_SOURCE_RUNNING, path.toFilterStructure()));
73         val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
74         return data?.findNode(path) as CompositeNode;
75     }
76
77     override readOperationalData(InstanceIdentifier path) {
78         val result = invokeRpc(NETCONF_GET_QNAME, wrap(NETCONF_GET_QNAME, path.toFilterStructure()));
79         val data = result.result.getFirstCompositeByName(NETCONF_DATA_QNAME);
80         return data?.findNode(path) as CompositeNode;
81     }
82
83     override getSupportedRpcs() {
84         Collections.emptySet;
85     }
86
87     override invokeRpc(QName rpc, CompositeNode input) {
88         val message = rpc.toRpcMessage(input);
89         val result = client.sendMessage(message);
90         return result.toRpcResult();
91     }
92
93     override getProviderFunctionality() {
94         Collections.emptySet
95     }
96
97     override onSessionInitiated(ProviderSession session) {
98         val dataBroker = session.getService(DataBrokerService);
99         
100         
101         
102         val transaction = dataBroker.beginTransaction
103         if(transaction.operationalNodeNotExisting) {
104             transaction.putOperationalData(path,nodeWithId)
105         }
106         if(transaction.configurationNodeNotExisting) {
107             transaction.putConfigurationData(path,nodeWithId)
108         }
109         transaction.commit().get();
110         mountService = session.getService(MountProvisionService);
111         mountInstance = mountService.createOrGetMountPoint(path);
112     }
113     
114     def getNodeWithId() {
115         val id = new SimpleNodeTOImpl(INVENTORY_ID,null,name);
116         return new CompositeNodeTOImpl(INVENTORY_NODE,null,Collections.singletonList(id));
117     }
118     
119     def boolean configurationNodeNotExisting(DataModificationTransaction transaction) {
120         return null === transaction.readConfigurationData(path);
121     }
122     
123     def boolean operationalNodeNotExisting(DataModificationTransaction transaction) {
124         return null === transaction.readOperationalData(path);
125     }
126
127     def Node<?> findNode(CompositeNode node, InstanceIdentifier identifier) {
128
129         var Node<?> current = node;
130         for (arg : identifier.path) {
131             if (current instanceof SimpleNode<?>) {
132                 return null;
133             } else if (current instanceof CompositeNode) {
134                 val currentComposite = (current as CompositeNode);
135
136                 current = currentComposite.getFirstCompositeByName(arg.nodeType);
137                 if (current == null) {
138                     current = currentComposite.getFirstSimpleByName(arg.nodeType);
139                 }
140                 if (current == null) {
141                     return null;
142                 }
143             }
144         }
145         return current;
146     }
147
148     override requestCommit(DataModification<InstanceIdentifier, CompositeNode> modification) {
149         throw new UnsupportedOperationException("TODO: auto-generated method stub")
150     }
151
152     override close() {
153         confReaderReg?.close()
154         operReaderReg?.close()
155         client?.close()
156     }
157
158 }