2 * Copyright (c) 2015 Cisco Systems, Inc. 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.lispflowmapping.dsbackend;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import com.google.common.util.concurrent.FutureCallback;
14 import com.google.common.util.concurrent.Futures;
15 import java.util.ArrayList;
16 import java.util.List;
17 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
18 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
19 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
20 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
21 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
22 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
23 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
24 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
25 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
26 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingDatabase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.AuthenticationKey;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.Mapping;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.mapping.XtrIdMapping;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.database.VirtualNetworkIdentifier;
34 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
39 * Stores data coming from the mapping database RPCs into the MD-SAL datastore.
41 * @author Lorand Jakab
44 public class DataStoreBackEnd implements TransactionChainListener {
45 protected static final Logger LOG = LoggerFactory.getLogger(DataStoreBackEnd.class);
46 private static final InstanceIdentifier<MappingDatabase> DATABASE_ROOT =
47 InstanceIdentifier.create(MappingDatabase.class);
48 private BindingTransactionChain txChain;
50 public DataStoreBackEnd(DataBroker broker) {
51 this.txChain = broker.createTransactionChain(this);
55 public void addAuthenticationKey(AuthenticationKey authenticationKey) {
56 if (LOG.isDebugEnabled()) {
57 LOG.debug("MD-SAL: Adding authentication key '{}' for {}",
58 authenticationKey.getMappingAuthkey().getKeyString(),
59 LispAddressStringifier.getString(authenticationKey.getEid()));
62 InstanceIdentifier<AuthenticationKey> path = InstanceIdentifierUtil
63 .createAuthenticationKeyIid(authenticationKey.getEid());
64 writePutTransaction(path, authenticationKey, LogicalDatastoreType.CONFIGURATION,
65 "Adding authentication key to MD-SAL datastore failed");
68 public void addMapping(Mapping mapping) {
69 if (LOG.isDebugEnabled()) {
70 LOG.debug("MD-SAL: Adding mapping for {}",
71 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()));
74 InstanceIdentifier<Mapping> path = InstanceIdentifierUtil
75 .createMappingIid(mapping.getMappingRecord().getEid(), mapping.getOrigin());
76 writePutTransaction(path, mapping, getDestinationDatastore(mapping),
77 "Adding mapping to MD-SAL datastore failed");
80 // This method assumes that it is only called for southbound originated Map-Registers
81 public void addXtrIdMapping(XtrIdMapping mapping) {
82 XtrId xtrId = mapping.getMappingRecord().getXtrId();
83 Preconditions.checkNotNull(xtrId, "Make sure you only call addXtrIdMapping when the MappingRecord "
84 + "contains an xTR-ID");
85 if (LOG.isDebugEnabled()) {
86 LOG.debug("MD-SAL: Adding mapping for {}, xTR-ID {}",
87 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()), xtrId);
90 InstanceIdentifier<XtrIdMapping> path = InstanceIdentifierUtil
91 .createXtrIdMappingIid(mapping.getMappingRecord().getEid(), MappingOrigin.Southbound, xtrId);
92 writePutTransaction(path, mapping, LogicalDatastoreType.OPERATIONAL,
93 "Adding xTR-ID mapping to MD-SAL datastore failed");
96 public void removeAuthenticationKey(AuthenticationKey authenticationKey) {
97 if (LOG.isDebugEnabled()) {
98 LOG.debug("MD-SAL: Removing authentication key for {}",
99 LispAddressStringifier.getString(authenticationKey.getEid()));
102 InstanceIdentifier<AuthenticationKey> path = InstanceIdentifierUtil
103 .createAuthenticationKeyIid(authenticationKey.getEid());
104 deleteTransaction(path, LogicalDatastoreType.CONFIGURATION,
105 "Deleting authentication key from MD-SAL datastore failed");
108 public void removeMapping(Mapping mapping) {
109 if (LOG.isDebugEnabled()) {
110 LOG.debug("MD-SAL: Removing mapping for {}",
111 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()));
114 InstanceIdentifier<Mapping> path = InstanceIdentifierUtil
115 .createMappingIid(mapping.getMappingRecord().getEid(), mapping.getOrigin());
116 deleteTransaction(path, getDestinationDatastore(mapping), "Deleting mapping from MD-SAL datastore failed");
119 public void removeXtrIdMapping(XtrIdMapping mapping) {
120 XtrId xtrId = mapping.getMappingRecord().getXtrId();
121 Preconditions.checkNotNull(xtrId, "Make sure you only call addXtrIdMapping when the MappingRecord "
122 + "contains an xTR-ID");
123 if (LOG.isDebugEnabled()) {
124 LOG.debug("MD-SAL: Removing mapping for {}, xTR-ID {}",
125 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()), xtrId);
128 InstanceIdentifier<XtrIdMapping> path = InstanceIdentifierUtil
129 .createXtrIdMappingIid(mapping.getMappingRecord().getEid(), MappingOrigin.Southbound, xtrId);
130 deleteTransaction(path, LogicalDatastoreType.OPERATIONAL,
131 "Deleting xTR-ID mapping from MD-SAL datastore failed");
134 public void removeAllDatastoreContent() {
135 LOG.debug("MD-SAL: Removing all mapping database datastore content (mappings and keys)");
136 removeAllConfigDatastoreContent();
137 removeAllOperationalDatastoreContent();
140 public void removeAllConfigDatastoreContent() {
141 deleteTransaction(DATABASE_ROOT, LogicalDatastoreType.CONFIGURATION,
142 "Removal of all database content in config datastore failed");
145 public void removeAllOperationalDatastoreContent() {
146 deleteTransaction(DATABASE_ROOT, LogicalDatastoreType.OPERATIONAL,
147 "Removal of all database content in operational datastore failed");
150 public void updateAuthenticationKey(AuthenticationKey authenticationKey) {
151 if (LOG.isDebugEnabled()) {
152 LOG.debug("MD-SAL: Updating authentication key for {} with '{}'",
153 LispAddressStringifier.getString(authenticationKey.getEid()),
154 authenticationKey.getMappingAuthkey().getKeyString());
157 InstanceIdentifier<AuthenticationKey> path = InstanceIdentifierUtil
158 .createAuthenticationKeyIid(authenticationKey.getEid());
159 writePutTransaction(path, authenticationKey, LogicalDatastoreType.CONFIGURATION,
160 "Updating authentication key in MD-SAL datastore failed");
163 public void updateMapping(Mapping mapping) {
164 if (LOG.isDebugEnabled()) {
165 LOG.debug("MD-SAL: Updating mapping for {}",
166 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()));
169 InstanceIdentifier<Mapping> path = InstanceIdentifierUtil
170 .createMappingIid(mapping.getMappingRecord().getEid(), mapping.getOrigin());
171 writePutTransaction(path, mapping, getDestinationDatastore(mapping),
172 "Updating mapping in MD-SAL datastore failed");
175 public List<Mapping> getAllMappings() {
176 List<Mapping> mappings = getAllMappings(LogicalDatastoreType.CONFIGURATION);
177 mappings.addAll(getAllMappings(LogicalDatastoreType.OPERATIONAL));
181 public List<Mapping> getAllMappings(LogicalDatastoreType logicalDataStore) {
182 LOG.debug("MD-SAL: Get all mappings from datastore");
183 List<Mapping> mappings = new ArrayList<Mapping>();
184 MappingDatabase mdb = readTransaction(DATABASE_ROOT, logicalDataStore);
187 for (VirtualNetworkIdentifier id : mdb.getVirtualNetworkIdentifier()) {
188 List<Mapping> ms = id.getMapping();
198 public List<AuthenticationKey> getAllAuthenticationKeys() {
199 LOG.debug("MD-SAL: Get all authentication keys from datastore");
200 List<AuthenticationKey> authKeys = new ArrayList<AuthenticationKey>();
201 MappingDatabase mdb = readTransaction(DATABASE_ROOT, LogicalDatastoreType.CONFIGURATION);
204 for (VirtualNetworkIdentifier id : mdb.getVirtualNetworkIdentifier()) {
205 List<AuthenticationKey> keys = id.getAuthenticationKey();
207 authKeys.addAll(keys);
215 private static LogicalDatastoreType getDestinationDatastore(Mapping mapping) {
216 return mapping.getOrigin().equals(MappingOrigin.Southbound) ? LogicalDatastoreType.OPERATIONAL
217 : LogicalDatastoreType.CONFIGURATION;
220 private <U extends org.opendaylight.yangtools.yang.binding.DataObject> void writePutTransaction(
221 InstanceIdentifier<U> addIID, U data, LogicalDatastoreType logicalDatastoreType, String errMsg) {
222 WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
223 writeTx.put(logicalDatastoreType, addIID, data, true);
224 Futures.addCallback(writeTx.submit(), new FutureCallback<Void>() {
226 public void onSuccess(Void result) {
229 public void onFailure(Throwable throwable) {
230 LOG.error("Transaction failed:", throwable);
235 private <U extends org.opendaylight.yangtools.yang.binding.DataObject> U readTransaction(
236 InstanceIdentifier<U> readIID, LogicalDatastoreType logicalDatastoreType) {
237 ReadOnlyTransaction readTx = txChain.newReadOnlyTransaction();
238 CheckedFuture<Optional<U>, ReadFailedException> readFuture = readTx.read(logicalDatastoreType, readIID);
241 Optional<U> optionalDataObject = readFuture.checkedGet();
242 if (optionalDataObject != null && optionalDataObject.isPresent()) {
243 return optionalDataObject.get();
245 LOG.debug("{}: Failed to read", Thread.currentThread().getStackTrace()[1]);
247 } catch (ReadFailedException e) {
248 LOG.warn("Failed to ....", e);
253 private <U extends org.opendaylight.yangtools.yang.binding.DataObject> void deleteTransaction(
254 InstanceIdentifier<U> deleteIID, LogicalDatastoreType logicalDatastoreType, String errMsg) {
256 WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
257 writeTx.delete(logicalDatastoreType, deleteIID);
258 Futures.addCallback(writeTx.submit(), new FutureCallback<Void>() {
260 public void onSuccess(Void result) {
263 public void onFailure(Throwable throwable) {
264 LOG.error("Transaction failed:", throwable);
269 public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction,
271 LOG.error("Broken chain {} in DataStoreBackEnd, transaction {}, cause {}", chain, transaction.getIdentifier(),
275 public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
276 LOG.info("DataStoreBackEnd closed successfully, chain {}", chain);