HONEYCOMB-130: Separate v3po plugin from HC infra
[honeycomb.git] / infra / impl / src / main / java / io / fd / honeycomb / v3po / impl / NorthboundFacadeHoneycombDOMBroker.java
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package io.fd.honeycomb.v3po.impl;
18
19 import com.google.common.base.Optional;
20 import com.google.common.collect.Maps;
21 import com.google.common.util.concurrent.CheckedFuture;
22 import com.google.common.util.concurrent.Futures;
23 import java.util.Map;
24 import javax.annotation.Nonnull;
25 import javax.annotation.Nullable;
26 import javax.annotation.concurrent.NotThreadSafe;
27 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
28 import org.opendaylight.controller.md.sal.dom.api.DOMMountPoint;
29 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
30 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
31 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
32 import org.opendaylight.controller.md.sal.dom.api.DOMRpcAvailabilityListener;
33 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
34 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
35 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
36 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
37 import org.opendaylight.controller.sal.core.api.Broker;
38 import org.opendaylight.controller.sal.core.api.BrokerService;
39 import org.opendaylight.controller.sal.core.api.Consumer;
40 import org.opendaylight.controller.sal.core.api.Provider;
41 import org.opendaylight.controller.sal.core.api.model.SchemaService;
42 import org.opendaylight.controller.sal.core.api.mount.MountProvisionListener;
43 import org.opendaylight.yangtools.concepts.ListenerRegistration;
44 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
45 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
46 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
47 import org.osgi.framework.BundleContext;
48
49 /**
50  * Implementation of dom broker to facade VPP pipeline for northbound APIs
51  */
52 public class NorthboundFacadeHoneycombDOMBroker implements AutoCloseable, Broker {
53
54     private static final BrokerService EMPTY_DOM_RPC_SERVICE = new EmptyDomRpcService();
55     private static final BrokerService EMPTY_DOM_MOUNT_SERVICE = new EmptyDomMountService();
56
57     private Map<Class<? extends BrokerService>, BrokerService> services;
58
59     public NorthboundFacadeHoneycombDOMBroker(@Nonnull final DOMDataBroker domDataBrokerDependency,
60                                               @Nonnull final SchemaService schemaBiService,
61                                               @Nonnull final DOMNotificationService domNotificatioNService) {
62         services = Maps.newHashMap();
63         services.put(DOMDataBroker.class, domDataBrokerDependency);
64         // All services below are required to be present by Restconf northbound
65         services.put(SchemaService.class, schemaBiService);
66         services.put(DOMRpcService.class, EMPTY_DOM_RPC_SERVICE);
67         services.put(DOMMountPointService.class, EMPTY_DOM_MOUNT_SERVICE);
68         services.put(DOMNotificationService.class, domNotificatioNService);
69         // TODO do both notification service types have to be registered ?
70         services.put(DOMNotificationPublishService.class, domNotificatioNService);
71     }
72
73     @Override
74     public void close() throws Exception {
75         // NOOP
76     }
77
78     @Override
79     public ConsumerSession registerConsumer(final Consumer consumer) {
80         final SimpleConsumerSession session = new SimpleConsumerSession(services);
81         consumer.onSessionInitiated(session);
82         return session;
83     }
84
85     @Deprecated
86     @Override
87     public ConsumerSession registerConsumer(final Consumer consumer, final BundleContext bundleContext) {
88         throw new UnsupportedOperationException();
89     }
90
91     @Override
92     public ProviderSession registerProvider(final Provider provider) {
93         final SimpleProviderSession session = new SimpleProviderSession(services);
94         provider.onSessionInitiated(session);
95         return session;
96     }
97
98     @Override
99     public ProviderSession registerProvider(final Provider provider, final BundleContext bundleContext) {
100         throw new UnsupportedOperationException();
101     }
102
103     @NotThreadSafe
104     private static class SimpleConsumerSession implements ConsumerSession {
105         private boolean closed;
106         private final Map<Class<? extends BrokerService>, BrokerService> services;
107
108         private SimpleConsumerSession(final Map<Class<? extends BrokerService>, BrokerService> services) {
109             this.services = services;
110         }
111
112         @Override
113         public boolean isClosed() {
114             return closed;
115         }
116
117         @Override
118         public <T extends BrokerService> T getService(final Class<T> aClass) {
119             return (T)services.get(aClass);
120         }
121
122         @Override
123         public void close() {
124             closed = true;
125         }
126     }
127
128     @NotThreadSafe
129     private static class SimpleProviderSession implements ProviderSession {
130         private boolean closed;
131         private final Map<Class<? extends BrokerService>, BrokerService> services;
132
133         private SimpleProviderSession(final Map<Class<? extends BrokerService>, BrokerService> services) {
134             this.services = services;
135         }
136
137         @Override
138         public boolean isClosed() {
139             return closed;
140         }
141
142         @Override
143         public <T extends BrokerService> T getService(final Class<T> aClass) {
144             return (T)services.get(aClass);
145         }
146
147         @Override
148         public void close() {
149             closed = true;
150         }
151     }
152
153     private static class EmptyDomRpcService implements DOMRpcService {
154         @Nonnull
155         @Override
156         public CheckedFuture<DOMRpcResult, DOMRpcException> invokeRpc(@Nonnull final SchemaPath schemaPath,
157                                                                       @Nullable final NormalizedNode<?, ?> normalizedNode) {
158             return Futures.<DOMRpcResult, DOMRpcException>immediateFailedCheckedFuture(
159                 new DOMRpcImplementationNotAvailableException("RPCs not supported"));
160         }
161
162         @Nonnull
163         @Override
164         public <T extends DOMRpcAvailabilityListener> ListenerRegistration<T> registerRpcListener(@Nonnull final T t) {
165             return new ListenerRegistration<T>() {
166                 @Override
167                 public void close() {
168                     // Noop
169                 }
170
171                 @Override
172                 public T getInstance() {
173                     return t;
174                 }
175             };
176         }
177     }
178
179     private static class EmptyDomMountService implements DOMMountPointService {
180         @Override
181         public Optional<DOMMountPoint> getMountPoint(final YangInstanceIdentifier yangInstanceIdentifier) {
182             return Optional.absent();
183         }
184
185         @Override
186         public DOMMountPointBuilder createMountPoint(final YangInstanceIdentifier yangInstanceIdentifier) {
187             throw new UnsupportedOperationException("No mountpoint support");
188         }
189
190         @Override
191         public ListenerRegistration<MountProvisionListener> registerProvisionListener(
192             final MountProvisionListener mountProvisionListener) {
193             return new ListenerRegistration<MountProvisionListener>() {
194                 @Override
195                 public void close() {
196                     // Noop
197                 }
198
199                 @Override
200                 public MountProvisionListener getInstance() {
201                     return mountProvisionListener;
202                 }
203             };
204         }
205     }
206 }