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 com.google.common.base.Objects;
13 import java.util.concurrent.Future;
15 import javax.ws.rs.core.Response.Status;
17 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
18 import org.opendaylight.controller.md.sal.common.api.data.DataReader;
19 import org.opendaylight.controller.sal.core.api.Broker.ConsumerSession;
20 import org.opendaylight.controller.sal.core.api.data.DataBrokerService;
21 import org.opendaylight.controller.sal.core.api.data.DataChangeListener;
22 import org.opendaylight.controller.sal.core.api.data.DataModificationTransaction;
23 import org.opendaylight.controller.sal.core.api.mount.MountInstance;
24 import org.opendaylight.controller.sal.rest.impl.RestconfProvider;
25 import org.opendaylight.controller.sal.restconf.impl.ResponseException;
26 import org.opendaylight.controller.sal.streams.listeners.ListenerAdapter;
27 import org.opendaylight.yangtools.concepts.ListenerRegistration;
28 import org.opendaylight.yangtools.yang.common.QName;
29 import org.opendaylight.yangtools.yang.common.RpcResult;
30 import org.opendaylight.yangtools.yang.data.api.CompositeNode;
31 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 public class BrokerFacade implements DataReader<InstanceIdentifier, CompositeNode> {
36 private final static Logger LOG = LoggerFactory.getLogger( BrokerFacade.class );
38 private final static BrokerFacade INSTANCE = new BrokerFacade();
40 private volatile DataBrokerService dataService;
41 private volatile ConsumerSession context;
43 private BrokerFacade() {
46 public void setContext( final ConsumerSession context ) {
47 this.context = context;
50 public void setDataService( final DataBrokerService dataService ) {
51 this.dataService = dataService;
54 public static BrokerFacade getInstance() {
55 return BrokerFacade.INSTANCE;
58 private void checkPreconditions() {
59 if( context == null || dataService == null ) {
60 ResponseException _responseException = new ResponseException( Status.SERVICE_UNAVAILABLE,
61 RestconfProvider.NOT_INITALIZED_MSG );
62 throw _responseException;
67 public CompositeNode readConfigurationData( final InstanceIdentifier path ) {
68 this.checkPreconditions();
70 LOG.trace( "Read Configuration via Restconf: {}", path );
72 return dataService.readConfigurationData( path );
75 public CompositeNode readConfigurationDataBehindMountPoint( final MountInstance mountPoint,
76 final InstanceIdentifier path ) {
77 this.checkPreconditions();
79 LOG.trace( "Read Configuration via Restconf: {}", path );
81 return mountPoint.readConfigurationData( path );
85 public CompositeNode readOperationalData( final InstanceIdentifier path ) {
86 this.checkPreconditions();
88 BrokerFacade.LOG.trace( "Read Operational via Restconf: {}", path );
90 return dataService.readOperationalData( path );
93 public CompositeNode readOperationalDataBehindMountPoint( final MountInstance mountPoint,
94 final InstanceIdentifier path ) {
95 this.checkPreconditions();
97 BrokerFacade.LOG.trace( "Read Operational via Restconf: {}", path );
99 return mountPoint.readOperationalData( path );
102 public RpcResult<CompositeNode> invokeRpc( final QName type, final CompositeNode payload ) {
103 this.checkPreconditions();
105 final Future<RpcResult<CompositeNode>> future = context.rpc( type, payload );
110 catch( Exception e ) {
111 throw new ResponseException( e, "Error invoking RPC " + type );
115 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPut( final InstanceIdentifier path,
116 final CompositeNode payload ) {
117 this.checkPreconditions();
119 final DataModificationTransaction transaction = dataService.beginTransaction();
120 BrokerFacade.LOG.trace( "Put Configuration via Restconf: {}", path );
121 transaction.putConfigurationData( path, payload );
122 return transaction.commit();
125 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPutBehindMountPoint(
126 final MountInstance mountPoint, final InstanceIdentifier path, final CompositeNode payload ) {
127 this.checkPreconditions();
129 final DataModificationTransaction transaction = mountPoint.beginTransaction();
130 BrokerFacade.LOG.trace( "Put Configuration via Restconf: {}", path );
131 transaction.putConfigurationData( path, payload );
132 return transaction.commit();
135 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPost( final InstanceIdentifier path,
136 final CompositeNode payload ) {
137 this.checkPreconditions();
139 final DataModificationTransaction transaction = dataService.beginTransaction();
140 transaction.putConfigurationData( path, payload );
141 Map<InstanceIdentifier, CompositeNode> createdConfigurationData =
142 transaction.getCreatedConfigurationData();
143 CompositeNode createdNode = createdConfigurationData.get( path );
145 if( Objects.equal( payload, createdNode ) ) {
146 LOG.trace( "Post Configuration via Restconf: {}", path );
147 return transaction.commit();
150 LOG.trace( "Post Configuration via Restconf was not executed because data already exists: {}",
155 public Future<RpcResult<TransactionStatus>> commitConfigurationDataPostBehindMountPoint(
156 final MountInstance mountPoint, final InstanceIdentifier path, final CompositeNode payload ) {
157 this.checkPreconditions();
159 final DataModificationTransaction transaction = mountPoint.beginTransaction();
160 transaction.putConfigurationData( path, payload );
161 Map<InstanceIdentifier, CompositeNode> createdConfigurationData =
162 transaction.getCreatedConfigurationData();
163 CompositeNode createdNode = createdConfigurationData.get( path );
165 if( Objects.equal( payload, createdNode ) ) {
166 LOG.trace( "Post Configuration via Restconf: {}", path );
167 return transaction.commit();
170 LOG.trace( "Post Configuration via Restconf was not executed because data already exists: {}",
175 public Future<RpcResult<TransactionStatus>> commitConfigurationDataDelete( final InstanceIdentifier path ) {
176 this.checkPreconditions();
178 final DataModificationTransaction transaction = dataService.beginTransaction();
179 LOG.info( "Delete Configuration via Restconf: {}", path );
180 transaction.removeConfigurationData( path );
181 return transaction.commit();
184 public Future<RpcResult<TransactionStatus>> commitConfigurationDataDeleteBehindMountPoint(
185 final MountInstance mountPoint, final InstanceIdentifier path ) {
186 this.checkPreconditions();
188 final DataModificationTransaction transaction = mountPoint.beginTransaction();
189 LOG.info( "Delete Configuration via Restconf: {}", path );
190 transaction.removeConfigurationData( path );
191 return transaction.commit();
194 public void registerToListenDataChanges( final ListenerAdapter listener ) {
195 this.checkPreconditions();
197 if( listener.isListening() ) {
201 InstanceIdentifier path = listener.getPath();
202 final ListenerRegistration<DataChangeListener> registration =
203 dataService.registerDataChangeListener( path, listener );
205 listener.setRegistration( registration );