Fix modules Restconf call for mounted devices
[controller.git] / opendaylight / md-sal / messagebus-impl / src / main / java / org / opendaylight / controller / mdsal / MdSAL.java
1 /**
2  * Copyright (c) 2014 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.mdsal;
10
11 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
12 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
13 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;
14 import org.opendaylight.controller.sal.binding.api.BindingAwareService;
15 import org.opendaylight.controller.sal.binding.api.mount.MountInstance;
16 import org.opendaylight.controller.sal.binding.api.mount.MountProviderService;
17 import org.opendaylight.controller.sal.core.api.Broker;
18 import org.opendaylight.controller.sal.core.api.BrokerService;
19 import org.opendaylight.controller.sal.core.api.notify.NotificationListener;
20 import org.opendaylight.controller.sal.core.api.notify.NotificationPublishService;
21 import org.opendaylight.controller.sal.core.api.notify.NotificationService;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeContext;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeRef;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
28 import org.opendaylight.yangtools.concepts.ListenerRegistration;
29 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
30 import org.opendaylight.yangtools.yang.binding.RpcService;
31 import org.opendaylight.yangtools.yang.common.QName;
32 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
33 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 public class MdSAL {
39     private static final Logger LOGGER = LoggerFactory.getLogger(MdSAL.class);
40
41     private BindingAwareBroker.ProviderContext bindingAwareContext;
42     private Broker.ProviderSession bindingIndependentContext;
43
44     // -----------------------------
45     // ----- FRAMEWORK METHODS -----
46     // -----------------------------
47     public void setBindingAwareContext(BindingAwareBroker.ProviderContext bindingAwareContext) {
48         this.bindingAwareContext = bindingAwareContext;
49     }
50
51     public void setBindingIndependentContext(Broker.ProviderSession bindingIndependentContext) {
52         this.bindingIndependentContext = bindingIndependentContext;
53     }
54
55     //TODO: We should hide brokers and expose functionalities instead
56     public DataBroker getDataBroker() {
57         return getBaSalService(DataBroker.class);
58     }
59
60     public synchronized boolean isReady() {
61         return (bindingAwareContext != null && bindingIndependentContext != null);
62     }
63
64     // -----------------------
65     // ----- API METHODS -----
66     // -----------------------
67     // TODO: Factor out API methods to interface
68     // method does not return registration object. Rather will hold references internally and manipulate using node id and API
69     public <T extends RpcService> void addRpcImplementation(Class<T> serviceInterface,
70                                                             T implementation)
71             throws IllegalStateException {
72         bindingAwareContext.addRpcImplementation(serviceInterface, implementation);
73     }
74
75     // method does not return registration object. Rather will hold references internally and manipulate using node id and API
76     public <T extends RpcService> void addRpcImplementation(Node node,
77                                                             Class<T> serviceInterface,
78                                                             T implementation)
79             throws IllegalStateException {
80         BindingAwareBroker.RoutedRpcRegistration<T> registration
81                 = addRoutedRpcImplementation(serviceInterface, implementation);
82
83         NodeRef nodeRef = createNodeRef(node.getId());
84         registration.registerPath(NodeContext.class, nodeRef.getValue());
85     }
86
87     public ListenerRegistration<NotificationListener> addNotificationListener(String nodeId,
88                                                                               QName notification,
89                                                                               NotificationListener listener) {
90         YangInstanceIdentifier yii = inventoryNodeBIIdentifier(nodeId);
91
92         NotificationService notificationService =
93                 getBiSalService(DOMMountPointService.class)
94                         .getMountPoint(yii)
95                         .get()
96                         .getService(NotificationPublishService.class)
97                         .get();
98
99         ListenerRegistration<NotificationListener> registration =
100                 notificationService.addNotificationListener(notification, listener);
101
102         LOGGER.info("Notification listener registered for {}, at node {}", notification, nodeId);
103
104         return registration;
105     }
106
107     public ListenerRegistration<NotificationListener> addNotificationListener(QName notification,
108                                                                               NotificationListener listener) {
109         NotificationService notificationService =
110                 getBiSalService(NotificationPublishService.class);
111
112         ListenerRegistration<NotificationListener> registration =
113                 notificationService.addNotificationListener(notification, listener);
114
115         LOGGER.info("Notification listener registered for {}.", notification);
116
117         return registration;
118     }
119
120     public <T extends RpcService> T getRpcService(Class<T> serviceInterface) {
121         return bindingAwareContext.getRpcService(serviceInterface);
122     }
123
124     public <T extends RpcService> T getRpcService(String nodeId, Class<T> serviceInterface) {
125         MountProviderService mountProviderService = getBaSalService(MountProviderService.class);
126
127         InstanceIdentifier<Node> key = InstanceIdentifier.create(Nodes.class)
128                                                          .child(Node.class,
129                                                                  new NodeKey(new NodeId(nodeId)));
130
131         MountInstance mountPoint = mountProviderService.getMountPoint(key);
132         return mountPoint.getRpcService(serviceInterface);
133     }
134
135     public void publishNotification(CompositeNode notification) {
136         getBiSalService(NotificationPublishService.class).publish(notification);
137     }
138
139     public SchemaContext getSchemaContext(String nodeId) {
140         YangInstanceIdentifier yii = inventoryNodeBIIdentifier(nodeId);
141
142         SchemaContext schemaContext =
143                 getBiSalService(DOMMountPointService.class)
144                         .getMountPoint(yii)
145                         .get().getSchemaContext();
146
147         return schemaContext;
148     }
149
150     // ---------------------------
151     // ----- UTILITY METHODS -----
152     // ---------------------------
153     private <T extends BindingAwareService> T getBaSalService(Class<T> service) {
154         return bindingAwareContext.getSALService(service);
155     }
156
157     private <T extends BrokerService> T getBiSalService(Class<T> service) {
158         return bindingIndependentContext.getService(service);
159     }
160
161     private static final String NODE_ID_NAME = "id";
162
163     public static YangInstanceIdentifier inventoryNodeBIIdentifier(String nodeId) {
164         return YangInstanceIdentifier.builder()
165                 .node(Nodes.QNAME)
166                 .nodeWithKey(Node.QNAME,
167                              QName.create(Node.QNAME.getNamespace(),
168                                           Node.QNAME.getRevision(),
169                                           NODE_ID_NAME),
170                              nodeId)
171                 .build();
172     }
173
174     private <T extends RpcService> BindingAwareBroker.RoutedRpcRegistration<T> addRoutedRpcImplementation(Class<T> serviceInterface,
175                                                                                                           T implementation)
176             throws IllegalStateException {
177         return bindingAwareContext.addRoutedRpcImplementation(serviceInterface, implementation);
178     }
179
180     public static NodeRef createNodeRef(NodeId nodeId) {
181         NodeKey nodeKey = new NodeKey(nodeId);
182         InstanceIdentifier<Node> path = InstanceIdentifier
183                 .builder(Nodes.class)
184                 .child(Node.class, nodeKey)
185                 .build();
186         return new NodeRef(path);
187     }
188 }