2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.restconf.nb.rfc8040;
11 import com.google.common.base.Preconditions;
12 import com.google.common.collect.ImmutableSet;
13 import com.google.common.collect.ImmutableSet.Builder;
15 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
16 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
17 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
19 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
20 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationService;
21 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
22 import org.opendaylight.controller.sal.core.api.model.SchemaService;
23 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
24 import org.opendaylight.restconf.common.errors.RestconfDocumentedException;
25 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMDataBrokerHandler;
26 import org.opendaylight.restconf.nb.rfc8040.handlers.DOMMountPointServiceHandler;
27 import org.opendaylight.restconf.nb.rfc8040.handlers.NotificationServiceHandler;
28 import org.opendaylight.restconf.nb.rfc8040.handlers.RpcServiceHandler;
29 import org.opendaylight.restconf.nb.rfc8040.handlers.SchemaContextHandler;
30 import org.opendaylight.restconf.nb.rfc8040.handlers.TransactionChainHandler;
31 import org.opendaylight.restconf.nb.rfc8040.services.wrapper.ServiceWrapper;
32 import org.opendaylight.yangtools.concepts.ListenerRegistration;
33 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
38 * Provider for restconf draft18.
41 public class RestConnectorProvider<T extends ServiceWrapper> implements RestconfConnector, AutoCloseable {
43 private static final Logger LOG = LoggerFactory.getLogger(RestConnectorProvider.class);
45 public static final TransactionChainListener TRANSACTION_CHAIN_LISTENER = new TransactionChainListener() {
47 public void onTransactionChainFailed(final TransactionChain<?, ?> chain,
48 final AsyncTransaction<?, ?> transaction, final Throwable cause) {
49 LOG.warn("TransactionChain({}) {} FAILED!", chain, transaction.getIdentifier(), cause);
50 resetTransactionChainForAdapaters(chain);
51 throw new RestconfDocumentedException("TransactionChain(" + chain + ") not committed correctly", cause);
55 public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
56 LOG.trace("TransactionChain({}) {} SUCCESSFUL", chain);
60 private static TransactionChainHandler transactionChainHandler;
61 private static DOMDataBroker dataBroker;
62 private static DOMMountPointServiceHandler mountPointServiceHandler;
64 private final SchemaService schemaService;
65 private final DOMRpcService rpcService;
66 private final DOMNotificationService notificationService;
67 private final DOMMountPointService mountPointService;
68 private final DOMSchemaService domSchemaService;
69 private final Builder<Object> servicesProperties;
71 private ListenerRegistration<SchemaContextListener> listenerRegistration;
72 private SchemaContextHandler schemaCtxHandler;
73 private T wrapperServices;
75 // FIXME: refactor this class and its users to interact via builder pattern, where individual
76 // services are injected and then the provider is created
77 public RestConnectorProvider(final DOMDataBroker domDataBroker,
78 final SchemaService schemaService, final DOMRpcService rpcService,
79 final DOMNotificationService notificationService, final DOMMountPointService mountPointService,
80 final DOMSchemaService domSchemaService) {
81 this(domDataBroker, schemaService, rpcService, notificationService, mountPointService, domSchemaService, null);
85 public RestConnectorProvider(final DOMDataBroker domDataBroker, final SchemaService schemaService,
86 final DOMRpcService rpcService,
87 final DOMNotificationService notificationService,
88 final DOMMountPointService mountPointService,
89 final DOMSchemaService domSchemaService, final T wrapperServices) {
90 this.servicesProperties = ImmutableSet.<Object>builder();
91 this.wrapperServices = wrapperServices;
92 this.schemaService = Preconditions.checkNotNull(schemaService);
93 this.rpcService = Preconditions.checkNotNull(rpcService);
94 this.notificationService = Preconditions.checkNotNull(notificationService);
95 this.mountPointService = Preconditions.checkNotNull(mountPointService);
96 this.domSchemaService = Preconditions.checkNotNull(domSchemaService);
98 RestConnectorProvider.dataBroker = Preconditions.checkNotNull(domDataBroker);
101 public synchronized void start() {
102 mountPointServiceHandler = new DOMMountPointServiceHandler(mountPointService);
103 servicesProperties.add(mountPointServiceHandler);
105 final DOMDataBrokerHandler brokerHandler = new DOMDataBrokerHandler(dataBroker);
106 servicesProperties.add(brokerHandler);
108 RestConnectorProvider.transactionChainHandler = new TransactionChainHandler(dataBroker
109 .createTransactionChain(RestConnectorProvider.TRANSACTION_CHAIN_LISTENER));
110 servicesProperties.add(transactionChainHandler);
112 this.schemaCtxHandler = new SchemaContextHandler(transactionChainHandler);
113 servicesProperties.add(schemaCtxHandler);
114 this.listenerRegistration = schemaService.registerSchemaContextListener(this.schemaCtxHandler);
116 final RpcServiceHandler rpcServiceHandler = new RpcServiceHandler(rpcService);
117 servicesProperties.add(rpcServiceHandler);
119 final NotificationServiceHandler notificationServiceHandler =
120 new NotificationServiceHandler(notificationService);
121 servicesProperties.add(notificationServiceHandler);
123 if (wrapperServices != null) {
124 wrapperServices.setHandlers(this.schemaCtxHandler, RestConnectorProvider.mountPointServiceHandler,
125 RestConnectorProvider.transactionChainHandler, brokerHandler, rpcServiceHandler,
126 notificationServiceHandler, domSchemaService);
130 public DOMMountPointServiceHandler getMountPointServiceHandler() {
131 return mountPointServiceHandler;
135 * After {@link TransactionChain} failed, this updates {@link TransactionChainHandler} with new transaction chain.
138 * old {@link TransactionChain}
140 public static void resetTransactionChainForAdapaters(final TransactionChain<?, ?> chain) {
141 LOG.trace("Resetting TransactionChain({})", chain);
143 RestConnectorProvider.transactionChainHandler.update(
144 Preconditions.checkNotNull(dataBroker).createTransactionChain(
145 RestConnectorProvider.TRANSACTION_CHAIN_LISTENER)
150 * Get current {@link DOMMountPointService} from {@link DOMMountPointServiceHandler}.
151 * @return {@link DOMMountPointService}
153 public static DOMMountPointService getMountPointService() {
154 return mountPointServiceHandler.get();
158 public void close() throws Exception {
159 // close registration
160 if (this.listenerRegistration != null) {
161 this.listenerRegistration.close();
164 // close transaction chain
165 if (transactionChainHandler != null && transactionChainHandler.get() != null) {
166 transactionChainHandler.get().close();
169 transactionChainHandler = null;
170 mountPointServiceHandler = null;
174 public final synchronized Set<Object> getServicesProperties() {
175 return servicesProperties.build();