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 java.util.ArrayList;
11 import java.util.List;
13 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
14 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
15 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
16 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
17 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
20 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
21 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
22 import org.opendaylight.lispflowmapping.lisp.util.LispAddressStringifier;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.lisp.proto.rev151105.XtrId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingDatabase;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.MappingOrigin;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.AuthenticationKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.Mapping;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.db.instance.mapping.XtrIdMapping;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.lfm.mappingservice.rev150906.mapping.database.VirtualNetworkIdentifier;
30 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
34 import com.google.common.base.Optional;
35 import com.google.common.base.Preconditions;
36 import com.google.common.util.concurrent.CheckedFuture;
37 import com.google.common.util.concurrent.FutureCallback;
38 import com.google.common.util.concurrent.Futures;
41 * Stores data coming from the mapping database RPCs into the MD-SAL datastore.
43 * @author Lorand Jakab
46 public class DataStoreBackEnd implements TransactionChainListener {
47 protected static final Logger LOG = LoggerFactory.getLogger(DataStoreBackEnd.class);
48 private static final InstanceIdentifier<MappingDatabase> DATABASE_ROOT =
49 InstanceIdentifier.create(MappingDatabase.class);
50 private BindingTransactionChain txChain;
52 public DataStoreBackEnd(DataBroker broker) {
53 this.txChain = broker.createTransactionChain(this);
57 public void addAuthenticationKey(AuthenticationKey authenticationKey) {
58 if (LOG.isDebugEnabled()) {
59 LOG.debug("MD-SAL: Adding authentication key '{}' for {}",
60 authenticationKey.getMappingAuthkey().getKeyString(),
61 LispAddressStringifier.getString(authenticationKey.getEid()));
64 InstanceIdentifier<AuthenticationKey> path = InstanceIdentifierUtil
65 .createAuthenticationKeyIid(authenticationKey.getEid());
66 writePutTransaction(path, authenticationKey, LogicalDatastoreType.CONFIGURATION,
67 "Adding authentication key to MD-SAL datastore failed");
70 public void addMapping(Mapping mapping) {
71 if (LOG.isDebugEnabled()) {
72 LOG.debug("MD-SAL: Adding mapping for {}",
73 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()));
76 InstanceIdentifier<Mapping> path = InstanceIdentifierUtil
77 .createMappingIid(mapping.getMappingRecord().getEid(), mapping.getOrigin());
78 writePutTransaction(path, mapping, getDestinationDatastore(mapping),
79 "Adding mapping to MD-SAL datastore failed");
82 // This method assumes that it is only called for southbound originated Map-Registers
83 public void addXtrIdMapping(XtrIdMapping mapping) {
84 XtrId xtrId = mapping.getMappingRecord().getXtrId();
85 Preconditions.checkNotNull(xtrId, "Make sure you only call addXtrIdMapping when the MappingRecord "
86 + "contains an xTR-ID");
87 if (LOG.isDebugEnabled()) {
88 LOG.debug("MD-SAL: Adding mapping for {}, xTR-ID {}",
89 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()), xtrId);
92 InstanceIdentifier<XtrIdMapping> path = InstanceIdentifierUtil
93 .createXtrIdMappingIid(mapping.getMappingRecord().getEid(), MappingOrigin.Southbound, xtrId);
94 writePutTransaction(path, mapping, LogicalDatastoreType.OPERATIONAL,
95 "Adding xTR-ID mapping to MD-SAL datastore failed");
98 public void removeAuthenticationKey(AuthenticationKey authenticationKey) {
99 if (LOG.isDebugEnabled()) {
100 LOG.debug("MD-SAL: Removing authentication key for {}",
101 LispAddressStringifier.getString(authenticationKey.getEid()));
104 InstanceIdentifier<AuthenticationKey> path = InstanceIdentifierUtil
105 .createAuthenticationKeyIid(authenticationKey.getEid());
106 deleteTransaction(path, LogicalDatastoreType.CONFIGURATION,
107 "Deleting authentication key from MD-SAL datastore failed");
110 public void removeMapping(Mapping mapping) {
111 if (LOG.isDebugEnabled()) {
112 LOG.debug("MD-SAL: Removing mapping for {}",
113 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()));
116 InstanceIdentifier<Mapping> path = InstanceIdentifierUtil
117 .createMappingIid(mapping.getMappingRecord().getEid(), mapping.getOrigin());
118 deleteTransaction(path, getDestinationDatastore(mapping), "Deleting mapping from MD-SAL datastore failed");
121 public void removeXtrIdMapping(XtrIdMapping mapping) {
122 XtrId xtrId = mapping.getMappingRecord().getXtrId();
123 Preconditions.checkNotNull(xtrId, "Make sure you only call addXtrIdMapping when the MappingRecord "
124 + "contains an xTR-ID");
125 if (LOG.isDebugEnabled()) {
126 LOG.debug("MD-SAL: Removing mapping for {}, xTR-ID {}",
127 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()), xtrId);
130 InstanceIdentifier<XtrIdMapping> path = InstanceIdentifierUtil
131 .createXtrIdMappingIid(mapping.getMappingRecord().getEid(), MappingOrigin.Southbound, xtrId);
132 deleteTransaction(path, LogicalDatastoreType.OPERATIONAL,
133 "Deleting xTR-ID mapping from MD-SAL datastore failed");
136 public void removeAllDatastoreContent() {
137 LOG.debug("MD-SAL: Removing all mapping database datastore content (mappings and keys)");
138 removeAllConfigDatastoreContent();
139 removeAllOperationalDatastoreContent();
142 public void removeAllConfigDatastoreContent() {
143 deleteTransaction(DATABASE_ROOT, LogicalDatastoreType.CONFIGURATION,
144 "Removal of all database content in config datastore failed");
147 public void removeAllOperationalDatastoreContent() {
148 deleteTransaction(DATABASE_ROOT, LogicalDatastoreType.OPERATIONAL,
149 "Removal of all database content in operational datastore failed");
152 public void updateAuthenticationKey(AuthenticationKey authenticationKey) {
153 if (LOG.isDebugEnabled()) {
154 LOG.debug("MD-SAL: Updating authentication key for {} with '{}'",
155 LispAddressStringifier.getString(authenticationKey.getEid()),
156 authenticationKey.getMappingAuthkey().getKeyString());
159 InstanceIdentifier<AuthenticationKey> path = InstanceIdentifierUtil
160 .createAuthenticationKeyIid(authenticationKey.getEid());
161 writePutTransaction(path, authenticationKey, LogicalDatastoreType.CONFIGURATION,
162 "Updating authentication key in MD-SAL datastore failed");
165 public void updateMapping(Mapping mapping) {
166 if (LOG.isDebugEnabled()) {
167 LOG.debug("MD-SAL: Updating mapping for {}",
168 LispAddressStringifier.getString(mapping.getMappingRecord().getEid()));
171 InstanceIdentifier<Mapping> path = InstanceIdentifierUtil
172 .createMappingIid(mapping.getMappingRecord().getEid(), mapping.getOrigin());
173 writePutTransaction(path, mapping, getDestinationDatastore(mapping),
174 "Updating mapping in MD-SAL datastore failed");
177 public List<Mapping> getAllMappings() {
178 List<Mapping> mappings = getAllMappings(LogicalDatastoreType.CONFIGURATION);
179 mappings.addAll(getAllMappings(LogicalDatastoreType.OPERATIONAL));
183 public List<Mapping> getAllMappings(LogicalDatastoreType logicalDataStore) {
184 LOG.debug("MD-SAL: Get all mappings from datastore");
185 List<Mapping> mappings = new ArrayList<Mapping>();
186 MappingDatabase mdb = readTransaction(DATABASE_ROOT, logicalDataStore);
189 for (VirtualNetworkIdentifier id : mdb.getVirtualNetworkIdentifier()) {
190 List<Mapping> ms = id.getMapping();
200 public List<AuthenticationKey> getAllAuthenticationKeys() {
201 LOG.debug("MD-SAL: Get all authentication keys from datastore");
202 List<AuthenticationKey> authKeys = new ArrayList<AuthenticationKey>();
203 MappingDatabase mdb = readTransaction(DATABASE_ROOT, LogicalDatastoreType.CONFIGURATION);
206 for (VirtualNetworkIdentifier id : mdb.getVirtualNetworkIdentifier()) {
207 List<AuthenticationKey> keys = id.getAuthenticationKey();
209 authKeys.addAll(keys);
217 private static LogicalDatastoreType getDestinationDatastore(Mapping mapping) {
218 return mapping.getOrigin().equals(MappingOrigin.Southbound) ? LogicalDatastoreType.OPERATIONAL
219 : LogicalDatastoreType.CONFIGURATION;
222 private <U extends org.opendaylight.yangtools.yang.binding.DataObject> void writePutTransaction(
223 InstanceIdentifier<U> addIID, U data, LogicalDatastoreType logicalDatastoreType, String errMsg) {
224 WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
225 writeTx.put(logicalDatastoreType, addIID, data, true);
226 Futures.addCallback(writeTx.submit(), new FutureCallback<Void>() {
228 public void onSuccess(Void result) {
231 public void onFailure(Throwable t) {
232 LOG.error("Transaction failed:", t);
237 private <U extends org.opendaylight.yangtools.yang.binding.DataObject> U readTransaction(
238 InstanceIdentifier<U> readIID, LogicalDatastoreType logicalDatastoreType) {
239 ReadOnlyTransaction readTx = txChain.newReadOnlyTransaction();
240 CheckedFuture<Optional<U>, ReadFailedException> readFuture = readTx.read(logicalDatastoreType, readIID);
243 Optional<U> optionalDataObject = readFuture.checkedGet();
244 if (optionalDataObject != null && optionalDataObject.isPresent()) {
245 return optionalDataObject.get();
247 LOG.debug("{}: Failed to read", Thread.currentThread().getStackTrace()[1]);
249 } catch (ReadFailedException e) {
250 LOG.warn("Failed to ....", e);
255 private <U extends org.opendaylight.yangtools.yang.binding.DataObject> void deleteTransaction(
256 InstanceIdentifier<U> deleteIID, LogicalDatastoreType logicalDatastoreType, String errMsg) {
258 WriteTransaction writeTx = txChain.newWriteOnlyTransaction();
259 writeTx.delete(logicalDatastoreType, deleteIID);
260 Futures.addCallback(writeTx.submit(), new FutureCallback<Void>() {
262 public void onSuccess(Void result) {
265 public void onFailure(Throwable t) {
266 LOG.error("Transaction failed:", t);
271 public void onTransactionChainFailed(TransactionChain<?, ?> chain, AsyncTransaction<?, ?> transaction,
273 LOG.error("Broken chain {} in DataStoreBackEnd, transaction {}, cause {}", chain, transaction.getIdentifier(),
277 public void onTransactionChainSuccessful(TransactionChain<?, ?> chain) {
278 LOG.info("DataStoreBackEnd closed successfully, chain {}", chain);