2 * Copyright (c) 2014 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
8 package org.opendaylight.controller.sal.restconf.impl;
10 import java.util.concurrent.Future;
12 import javax.ws.rs.core.Response.Status;
14 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
15 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
16 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
17 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
18 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
19 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
20 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
21 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorTag;
22 import org.opendaylight.controller.sal.restconf.impl.RestconfError.ErrorType;
23 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
24 import org.opendaylight.yangtools.concepts.ListenerRegistration;
25 import org.opendaylight.yangtools.yang.common.QName;
26 import org.opendaylight.yangtools.yang.common.RpcResult;
27 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
28 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
32 public class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
33 private final static Logger LOG = LoggerFactory.getLogger( BrokerFacade.class );
35 private final static BrokerFacade INSTANCE = new BrokerFacade();
37 private volatile DataBrokerService dataService;
38 private volatile ConsumerSession context;
40 private BrokerFacade() {
43 public void setContext( final ConsumerSession context ) {
44 this.context = context;
47 public void setDataService( final DataBrokerService dataService ) {
48 this.dataService = dataService;
51 public static BrokerFacade getInstance() {
52 return BrokerFacade.INSTANCE;
55 private void checkPreconditions() {
56 if( context == null || dataService == null ) {
57 throw new RestconfDocumentedException( Status.SERVICE_UNAVAILABLE );
62 public CompositeNode readConfigurationData( final InstanceIdentifier path ) {
63 this.checkPreconditions();
65 LOG.trace( "Read Configuration via Restconf: {}", path );
67 return dataService.readConfigurationData( path );
70 public CompositeNode readConfigurationDataBehindMountPoint( final MountInstance mountPoint,
71 final InstanceIdentifier path ) {
72 this.checkPreconditions();
74 LOG.trace( "Read Configuration via Restconf: {}", path );
76 return mountPoint.readConfigurationData( path );
80 public CompositeNode readOperationalData( final InstanceIdentifier path ) {
81 this.checkPreconditions();
83 BrokerFacade.LOG.trace( "Read Operational via Restconf: {}", path );
85 return dataService.readOperationalData( path );
88 public CompositeNode readOperationalDataBehindMountPoint( final MountInstance mountPoint,
89 final InstanceIdentifier path ) {
90 this.checkPreconditions();
92 BrokerFacade.LOG.trace( "Read Operational via Restconf: {}", path );
94 return mountPoint.readOperationalData( path );
97 public Future<RpcResult<CompositeNode>> invokeRpc( final QName type, final CompositeNode payload ) {
98 this.checkPreconditions();
100 return context.rpc( type, payload );
103 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPut( final InstanceIdentifier path,
104 final CompositeNode payload ) {
105 this.checkPreconditions();
107 final DataModificationTransaction transaction = dataService.beginTransaction();
108 BrokerFacade.LOG.trace( "Put Configuration via Restconf: {}", path );
109 transaction.putConfigurationData( path, payload );
110 return transaction.commit();
113 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPutBehindMountPoint(
114 final MountInstance mountPoint, final InstanceIdentifier path, final CompositeNode payload ) {
115 this.checkPreconditions();
117 final DataModificationTransaction transaction = mountPoint.beginTransaction();
118 BrokerFacade.LOG.trace( "Put Configuration via Restconf: {}", path );
119 transaction.putConfigurationData( path, payload );
120 return transaction.commit();
123 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPost( final InstanceIdentifier path,
124 final CompositeNode payload) {
125 this.checkPreconditions();
127 final DataModificationTransaction transaction = dataService.beginTransaction();
128 /* check for available Node in Configuration DataStore by path */
129 CompositeNode availableNode = transaction.readConfigurationData( path );
130 if (availableNode != null) {
131 String errMsg = "Post Configuration via Restconf was not executed because data already exists";
132 BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString());
134 throw new RestconfDocumentedException(
135 "Data already exists for path: " + path, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS );
137 BrokerFacade.LOG.trace( "Post Configuration via Restconf: {}", path );
138 transaction.putConfigurationData( path, payload );
139 return transaction.commit();
142 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPostBehindMountPoint(
143 final MountInstance mountPoint, final InstanceIdentifier path, final CompositeNode payload ) {
144 this.checkPreconditions();
146 final DataModificationTransaction transaction = mountPoint.beginTransaction();
147 /* check for available Node in Configuration DataStore by path */
148 CompositeNode availableNode = transaction.readConfigurationData( path );
149 if (availableNode != null) {
150 String errMsg = "Post Configuration via Restconf was not executed because data already exists";
151 BrokerFacade.LOG.warn((new StringBuilder(errMsg)).append(" : ").append(path).toString());
153 throw new RestconfDocumentedException(
154 "Data already exists for path: " + path, ErrorType.PROTOCOL, ErrorTag.DATA_EXISTS );
156 BrokerFacade.LOG.trace( "Post Configuration via Restconf: {}", path );
157 transaction.putConfigurationData( path, payload );
158 return transaction.commit();
161 public Future<RpcResult<TransactionStatus>> commitConfigurationDataDelete( final InstanceIdentifier path ) {
162 this.checkPreconditions();
164 final DataModificationTransaction transaction = dataService.beginTransaction();
165 LOG.info( "Delete Configuration via Restconf: {}", path );
166 transaction.removeConfigurationData( path );
167 return transaction.commit();
170 public Future<RpcResult<TransactionStatus>> commitConfigurationDataDeleteBehindMountPoint(
171 final MountInstance mountPoint, final InstanceIdentifier path ) {
172 this.checkPreconditions();
174 final DataModificationTransaction transaction = mountPoint.beginTransaction();
175 LOG.info( "Delete Configuration via Restconf: {}", path );
176 transaction.removeConfigurationData( path );
177 return transaction.commit();
180 public void registerToListenDataChanges( final ListenerAdapter listener ) {
181 this.checkPreconditions();
183 if( listener.isListening() ) {
187 InstanceIdentifier path = listener.getPath();
188 final ListenerRegistration<DataChangeListener> registration =
189 dataService.registerDataChangeListener( path, listener );
191 listener.setRegistration( registration );