2 * Copyright (c) 2015 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.aaa.authn.mdsal.store;
10 import com.google.common.base.Optional;
11 import com.google.common.base.Preconditions;
12 import com.google.common.util.concurrent.CheckedFuture;
13 import java.util.List;
14 import java.util.concurrent.ExecutionException;
15 import org.opendaylight.aaa.api.IDMStoreException;
16 import org.opendaylight.aaa.api.IDMStoreUtil;
17 import org.opendaylight.aaa.api.SHA256Calculator;
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.LogicalDatastoreType;
22 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
23 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
24 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.Authentication;
25 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Domain;
26 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.DomainBuilder;
27 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.DomainKey;
28 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Grant;
29 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.GrantBuilder;
30 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.GrantKey;
31 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.Role;
32 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.RoleBuilder;
33 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.RoleKey;
34 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.User;
35 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.UserBuilder;
36 import org.opendaylight.yang.gen.v1.urn.aaa.yang.authn.claims.rev141029.authentication.UserKey;
37 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
42 * @author Sharon Aicler - saichler@cisco.com
45 public class IDMMDSALStore {
47 private static final Logger LOG = LoggerFactory.getLogger(IDMMDSALStore.class);
48 private final DataBroker dataBroker;
50 public IDMMDSALStore(DataBroker dataBroker) {
51 this.dataBroker = dataBroker;
54 public static final String getString(String aValue, String bValue) {
60 public static final Boolean getBoolean(Boolean aValue, Boolean bValue) {
66 public static boolean waitForSubmit(CheckedFuture<Void, TransactionCommitFailedException> submit) {
67 // This can happen only when testing
70 while (!submit.isDone() && !submit.isCancelled()) {
73 } catch (Exception err) {
74 LOG.error("Interrupted", err);
77 return submit.isCancelled();
81 public Domain writeDomain(Domain domain) {
82 Preconditions.checkNotNull(domain);
83 Preconditions.checkNotNull(domain.getName());
84 Preconditions.checkNotNull(domain.isEnabled());
85 DomainBuilder b = new DomainBuilder();
86 b.setDescription(domain.getDescription());
87 b.setDomainid(domain.getName());
88 b.setEnabled(domain.isEnabled());
89 b.setName(domain.getName());
90 b.setKey(new DomainKey(b.getName()));
92 InstanceIdentifier<Domain> ID = InstanceIdentifier.create(Authentication.class).child(
93 Domain.class, new DomainKey(domain.getDomainid()));
94 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
95 wrt.put(LogicalDatastoreType.CONFIGURATION, ID, domain, true);
96 CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit();
97 if (!waitForSubmit(submit)) {
104 public Domain readDomain(String domainid) {
105 Preconditions.checkNotNull(domainid);
106 InstanceIdentifier<Domain> ID = InstanceIdentifier.create(Authentication.class).child(
107 Domain.class, new DomainKey(domainid));
108 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
109 CheckedFuture<Optional<Domain>, ReadFailedException> read = rot.read(
110 LogicalDatastoreType.CONFIGURATION, ID);
112 LOG.error("Failed to read domain from data store");
115 Optional<Domain> optional = null;
117 optional = read.get();
118 } catch (InterruptedException | ExecutionException e1) {
119 LOG.error("Failed to read domain from data store", e1);
123 if (optional == null)
126 if (!optional.isPresent())
129 return optional.get();
132 public Domain deleteDomain(String domainid) {
133 Preconditions.checkNotNull(domainid);
134 Domain domain = readDomain(domainid);
135 if (domain == null) {
136 LOG.error("Failed to delete domain from data store, unknown domain");
139 InstanceIdentifier<Domain> ID = InstanceIdentifier.create(Authentication.class).child(
140 Domain.class, new DomainKey(domainid));
141 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
142 wrt.delete(LogicalDatastoreType.CONFIGURATION, ID);
147 public Domain updateDomain(Domain domain) throws IDMStoreException {
148 Preconditions.checkNotNull(domain);
149 Preconditions.checkNotNull(domain.getDomainid());
150 Domain existing = readDomain(domain.getDomainid());
151 DomainBuilder b = new DomainBuilder();
152 b.setDescription(getString(domain.getDescription(), existing.getDescription()));
153 b.setName(existing.getName());
154 b.setEnabled(getBoolean(domain.isEnabled(), existing.isEnabled()));
155 return writeDomain(b.build());
158 public List<Domain> getAllDomains() {
159 InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class);
160 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
161 CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read(
162 LogicalDatastoreType.CONFIGURATION, id);
167 if (read.get() == null)
169 if (read.get().isPresent()) {
170 Authentication auth = read.get().get();
171 return auth.getDomain();
173 } catch (Exception err) {
174 LOG.error("Failed to read domains", err);
179 public List<Role> getAllRoles() {
180 InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class);
181 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
182 CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read(
183 LogicalDatastoreType.CONFIGURATION, id);
188 if (read.get() == null)
190 if (read.get().isPresent()) {
191 Authentication auth = read.get().get();
192 return auth.getRole();
194 } catch (Exception err) {
195 LOG.error("Failed to read domains", err);
200 public List<User> getAllUsers() {
201 InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class);
202 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
203 CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read(
204 LogicalDatastoreType.CONFIGURATION, id);
209 if (read.get() == null)
211 if (read.get().isPresent()) {
212 Authentication auth = read.get().get();
213 return auth.getUser();
215 } catch (Exception err) {
216 LOG.error("Failed to read domains", err);
221 public List<Grant> getAllGrants() {
222 InstanceIdentifier<Authentication> id = InstanceIdentifier.create(Authentication.class);
223 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
224 CheckedFuture<Optional<Authentication>, ReadFailedException> read = rot.read(
225 LogicalDatastoreType.CONFIGURATION, id);
230 if (read.get() == null)
232 if (read.get().isPresent()) {
233 Authentication auth = read.get().get();
234 return auth.getGrant();
236 } catch (Exception err) {
237 LOG.error("Failed to read domains", err);
243 public Role writeRole(Role role) {
244 Preconditions.checkNotNull(role);
245 Preconditions.checkNotNull(role.getName());
246 Preconditions.checkNotNull(role.getDomainid());
247 Preconditions.checkNotNull(readDomain(role.getDomainid()));
248 RoleBuilder b = new RoleBuilder();
249 b.setDescription(role.getDescription());
250 b.setRoleid(IDMStoreUtil.createRoleid(role.getName(), role.getDomainid()));
251 b.setKey(new RoleKey(b.getRoleid()));
252 b.setName(role.getName());
253 b.setDomainid(role.getDomainid());
255 InstanceIdentifier<Role> ID = InstanceIdentifier.create(Authentication.class).child(
256 Role.class, new RoleKey(role.getRoleid()));
257 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
258 wrt.put(LogicalDatastoreType.CONFIGURATION, ID, role, true);
259 CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit();
260 if (!waitForSubmit(submit)) {
267 public Role readRole(String roleid) {
268 Preconditions.checkNotNull(roleid);
269 InstanceIdentifier<Role> ID = InstanceIdentifier.create(Authentication.class).child(
270 Role.class, new RoleKey(roleid));
271 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
272 CheckedFuture<Optional<Role>, ReadFailedException> read = rot.read(
273 LogicalDatastoreType.CONFIGURATION, ID);
275 LOG.error("Failed to read role from data store");
278 Optional<Role> optional = null;
280 optional = read.get();
281 } catch (InterruptedException | ExecutionException e1) {
282 LOG.error("Failed to read role from data store", e1);
286 if (optional == null)
289 if (!optional.isPresent())
292 return optional.get();
295 public Role deleteRole(String roleid) {
296 Preconditions.checkNotNull(roleid);
297 Role role = readRole(roleid);
299 LOG.error("Failed to delete role from data store, unknown role");
302 InstanceIdentifier<Role> ID = InstanceIdentifier.create(Authentication.class).child(
303 Role.class, new RoleKey(roleid));
304 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
305 wrt.delete(LogicalDatastoreType.CONFIGURATION, ID);
310 public Role updateRole(Role role) {
311 Preconditions.checkNotNull(role);
312 Preconditions.checkNotNull(role.getRoleid());
313 Role existing = readRole(role.getRoleid());
314 RoleBuilder b = new RoleBuilder();
315 b.setDescription(getString(role.getDescription(), existing.getDescription()));
316 b.setName(existing.getName());
317 b.setDomainid(existing.getDomainid());
318 return writeRole(b.build());
322 public User writeUser(User user) throws IDMStoreException {
323 Preconditions.checkNotNull(user);
324 Preconditions.checkNotNull(user.getName());
325 Preconditions.checkNotNull(user.getDomainid());
326 Preconditions.checkNotNull(readDomain(user.getDomainid()));
327 UserBuilder b = new UserBuilder();
328 if (user.getSalt() == null) {
329 b.setSalt(SHA256Calculator.generateSALT());
331 b.setSalt(user.getSalt());
333 b.setUserid(IDMStoreUtil.createUserid(user.getName(), user.getDomainid()));
334 b.setDescription(user.getDescription());
335 b.setDomainid(user.getDomainid());
336 b.setEmail(user.getEmail());
337 b.setEnabled(user.isEnabled());
338 b.setKey(new UserKey(b.getUserid()));
339 b.setName(user.getName());
340 b.setPassword(SHA256Calculator.getSHA256(user.getPassword(), b.getSalt()));
342 InstanceIdentifier<User> ID = InstanceIdentifier.create(Authentication.class).child(
343 User.class, new UserKey(user.getUserid()));
344 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
345 wrt.put(LogicalDatastoreType.CONFIGURATION, ID, user, true);
346 CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit();
347 if (!waitForSubmit(submit)) {
354 public User readUser(String userid) {
355 Preconditions.checkNotNull(userid);
356 InstanceIdentifier<User> ID = InstanceIdentifier.create(Authentication.class).child(
357 User.class, new UserKey(userid));
358 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
359 CheckedFuture<Optional<User>, ReadFailedException> read = rot.read(
360 LogicalDatastoreType.CONFIGURATION, ID);
362 LOG.error("Failed to read user from data store");
365 Optional<User> optional = null;
367 optional = read.get();
368 } catch (InterruptedException | ExecutionException e1) {
369 LOG.error("Failed to read domain from data store", e1);
373 if (optional == null)
376 if (!optional.isPresent())
379 return optional.get();
382 public User deleteUser(String userid) {
383 Preconditions.checkNotNull(userid);
384 User user = readUser(userid);
386 LOG.error("Failed to delete user from data store, unknown user");
389 InstanceIdentifier<User> ID = InstanceIdentifier.create(Authentication.class).child(
390 User.class, new UserKey(userid));
391 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
392 wrt.delete(LogicalDatastoreType.CONFIGURATION, ID);
397 public User updateUser(User user) throws IDMStoreException {
398 Preconditions.checkNotNull(user);
399 Preconditions.checkNotNull(user.getUserid());
400 User existing = readUser(user.getUserid());
401 UserBuilder b = new UserBuilder();
402 b.setName(existing.getName());
403 b.setDomainid(existing.getDomainid());
404 b.setDescription(getString(user.getDescription(), existing.getDescription()));
405 b.setEmail(getString(user.getEmail(), existing.getEmail()));
406 b.setEnabled(getBoolean(user.isEnabled(), existing.isEnabled()));
407 b.setPassword(getString(user.getPassword(), existing.getPassword()));
408 b.setSalt(getString(user.getSalt(), existing.getSalt()));
409 return writeUser(b.build());
413 public Grant writeGrant(Grant grant) throws IDMStoreException {
414 Preconditions.checkNotNull(grant);
415 Preconditions.checkNotNull(grant.getDomainid());
416 Preconditions.checkNotNull(grant.getUserid());
417 Preconditions.checkNotNull(grant.getRoleid());
418 Preconditions.checkNotNull(readDomain(grant.getDomainid()));
419 Preconditions.checkNotNull(readUser(grant.getUserid()));
420 Preconditions.checkNotNull(readRole(grant.getRoleid()));
421 GrantBuilder b = new GrantBuilder();
422 b.setDomainid(grant.getDomainid());
423 b.setRoleid(grant.getRoleid());
424 b.setUserid(grant.getUserid());
425 b.setGrantid(IDMStoreUtil.createGrantid(grant.getUserid(), grant.getDomainid(),
427 b.setKey(new GrantKey(b.getGrantid()));
429 InstanceIdentifier<Grant> ID = InstanceIdentifier.create(Authentication.class).child(
430 Grant.class, new GrantKey(grant.getGrantid()));
431 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
432 wrt.put(LogicalDatastoreType.CONFIGURATION, ID, grant, true);
433 CheckedFuture<Void, TransactionCommitFailedException> submit = wrt.submit();
434 if (!waitForSubmit(submit)) {
441 public Grant readGrant(String grantid) {
442 Preconditions.checkNotNull(grantid);
443 InstanceIdentifier<Grant> ID = InstanceIdentifier.create(Authentication.class).child(
444 Grant.class, new GrantKey(grantid));
445 ReadOnlyTransaction rot = dataBroker.newReadOnlyTransaction();
446 CheckedFuture<Optional<Grant>, ReadFailedException> read = rot.read(
447 LogicalDatastoreType.CONFIGURATION, ID);
449 LOG.error("Failed to read grant from data store");
452 Optional<Grant> optional = null;
454 optional = read.get();
455 } catch (InterruptedException | ExecutionException e1) {
456 LOG.error("Failed to read domain from data store", e1);
460 if (optional == null)
463 if (!optional.isPresent())
466 return optional.get();
469 public Grant deleteGrant(String grantid) {
470 Preconditions.checkNotNull(grantid);
471 Grant grant = readGrant(grantid);
473 LOG.error("Failed to delete grant from data store, unknown grant");
476 InstanceIdentifier<Grant> ID = InstanceIdentifier.create(Authentication.class).child(
477 Grant.class, new GrantKey(grantid));
478 WriteTransaction wrt = dataBroker.newWriteOnlyTransaction();
479 wrt.delete(LogicalDatastoreType.CONFIGURATION, ID);