aboutsummaryrefslogtreecommitdiffstats
path: root/odl-aaa-moon/aaa/aaa-h2-store/src/main
diff options
context:
space:
mode:
authorDUVAL Thomas <thomas.duval@orange.com>2016-06-16 14:50:31 +0200
committerDUVAL Thomas <thomas.duval@orange.com>2016-06-16 14:50:31 +0200
commitadf7e6616c2a8d6f60207059288423f693509928 (patch)
treeb79848d3b61f28e975f4730de541532c5089c6ed /odl-aaa-moon/aaa/aaa-h2-store/src/main
parent506a1fc1252268fa31ba89882ea55b7665579965 (diff)
Add new version of aaa
Change-Id: I94d72011e6019e66c98f46d11436a5cb33ff295d
Diffstat (limited to 'odl-aaa-moon/aaa/aaa-h2-store/src/main')
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java133
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java187
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java166
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java158
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java316
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java151
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java29
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java202
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModule.java49
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModuleFactory.java29
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml26
-rw-r--r--odl-aaa-moon/aaa/aaa-h2-store/src/main/yang/aaa-h2-store.yang28
12 files changed, 1474 insertions, 0 deletions
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java
new file mode 100644
index 00000000..a35ca48f
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2014, 2015 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.config;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for providing configuration properties for the IDMLight/H2
+ * data store implementation.
+ *
+ * @author peter.mellquist@hp.com
+ *
+ */
+public class IdmLightConfig {
+
+ private static final Logger LOG = LoggerFactory.getLogger(IdmLightConfig.class);
+
+ /**
+ * The default timeout for db connections in seconds.
+ */
+ private static final int DEFAULT_DB_TIMEOUT = 3;
+
+ /**
+ * The default password for the database
+ */
+ private static final String DEFAULT_PASSWORD = "bar";
+
+ /**
+ * The default username for the database
+ */
+ private static final String DEFAULT_USERNAME = "foo";
+
+ /**
+ * The default driver for the databse is H2; a pure-java implementation
+ * of JDBC.
+ */
+ private static final String DEFAULT_JDBC_DRIVER = "org.h2.Driver";
+
+ /**
+ * The default connection string includes the intention to use h2 as
+ * the JDBC driver, and the path for the file is located relative to
+ * KARAF_HOME.
+ */
+ private static final String DEFAULT_CONNECTION_STRING = "jdbc:h2:./";
+
+ /**
+ * The default filename for the database file.
+ */
+ private static final String DEFAULT_IDMLIGHT_DB_FILENAME = "idmlight.db";
+
+ /**
+ * The database filename
+ */
+ private String dbName;
+
+ /**
+ * the database connection string
+ */
+ private String dbPath;
+
+ /**
+ * The database driver (i.e., H2)
+ */
+ private String dbDriver;
+
+ /**
+ * The database password. This is not the same as AAA credentials!
+ */
+ private String dbUser;
+
+ /**
+ * The database username. This is not the same as AAA credentials!
+ */
+ private String dbPwd;
+
+ /**
+ * Timeout for database connections in seconds
+ */
+ private int dbValidTimeOut;
+
+ /**
+ * Creates an valid database configuration using default values.
+ */
+ public IdmLightConfig() {
+ // TODO make this configurable
+ dbName = DEFAULT_IDMLIGHT_DB_FILENAME;
+ dbPath = DEFAULT_CONNECTION_STRING + dbName;
+ dbDriver = DEFAULT_JDBC_DRIVER;
+ dbUser = DEFAULT_USERNAME;
+ dbPwd = DEFAULT_PASSWORD;
+ dbValidTimeOut = DEFAULT_DB_TIMEOUT;
+ }
+
+ /**
+ * Outputs some debugging information surrounding idmlight config
+ */
+ public void log() {
+ LOG.info("DB Path : {}", dbPath);
+ LOG.info("DB Driver : {}", dbDriver);
+ LOG.info("DB Valid Time Out : {}", dbValidTimeOut);
+ }
+
+ public String getDbName() {
+ return this.dbName;
+ }
+
+ public String getDbPath() {
+ return this.dbPath;
+ }
+
+ public String getDbDriver() {
+ return this.dbDriver;
+ }
+
+ public String getDbUser() {
+ return this.dbUser;
+ }
+
+ public String getDbPwd() {
+ return this.dbPwd;
+ }
+
+ public int getDbValidTimeOut() {
+ return this.dbValidTimeOut;
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java
new file mode 100644
index 00000000..ba00eb84
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright © 2016 Red Hat, Inc. and others.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.aaa.h2.persistence;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base class for H2 stores.
+ */
+abstract class AbstractStore<T> {
+ /**
+ * Logger.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(AbstractStore.class);
+
+ /**
+ * The name of the table used to represent this store.
+ */
+ private final String tableName;
+
+ /**
+ * Database connection, only used for tests.
+ */
+ Connection dbConnection = null;
+
+ /**
+ * Table types we're interested in (when checking tables' existence).
+ */
+ public static final String[] TABLE_TYPES = new String[] { "TABLE" };
+
+ /**
+ * Creates an instance.
+ *
+ * @param tableName The name of the table being managed.
+ */
+ protected AbstractStore(String tableName) {
+ this.tableName = tableName;
+ }
+
+ /**
+ * Returns a database connection. It is the caller's responsibility to close it. If the managed table does not
+ * exist, it will be created (using {@link #getTableCreationStatement()}).
+ *
+ * @return A database connection.
+ *
+ * @throws StoreException if an error occurs.
+ */
+ protected Connection dbConnect() throws StoreException {
+ Connection conn = H2Store.getConnection(dbConnection);
+ try {
+ // Ensure table check/creation is atomic
+ synchronized (this) {
+ DatabaseMetaData dbm = conn.getMetaData();
+ try (ResultSet rs = dbm.getTables(null, null, tableName, TABLE_TYPES)) {
+ if (rs.next()) {
+ LOG.debug("Table {} already exists", tableName);
+ } else {
+ LOG.info("Table {} does not exist, creating it", tableName);
+ try (Statement stmt = conn.createStatement()) {
+ stmt.executeUpdate(getTableCreationStatement());
+ }
+ }
+ }
+ }
+ } catch (SQLException e) {
+ LOG.error("Error connecting to the H2 database", e);
+ throw new StoreException("Cannot connect to database server", e);
+ }
+ return conn;
+ }
+
+ /**
+ * Empties the store.
+ *
+ * @throws StoreException if a connection error occurs.
+ */
+ protected void dbClean() throws StoreException {
+ try (Connection c = dbConnect()) {
+ // The table name can't be a parameter in a prepared statement
+ String sql = "DELETE FROM " + tableName;
+ c.createStatement().execute(sql);
+ } catch (SQLException e) {
+ LOG.error("Error clearing table {}", tableName, e);
+ throw new StoreException("Error clearing table " + tableName, e);
+ }
+ }
+
+ /**
+ * Returns the SQL code required to create the managed table.
+ *
+ * @return The SQL table creation statement.
+ */
+ protected abstract String getTableCreationStatement();
+
+ /**
+ * Lists all the stored items.
+ *
+ * @return The stored item.
+ *
+ * @throws StoreException if an error occurs.
+ */
+ protected List<T> listAll() throws StoreException {
+ List<T> result = new ArrayList<>();
+ String query = "SELECT * FROM " + tableName;
+ try (Connection conn = dbConnect();
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(query)) {
+ while (rs.next()) {
+ result.add(fromResultSet(rs));
+ }
+ } catch (SQLException e) {
+ LOG.error("Error listing all items from {}", tableName, e);
+ throw new StoreException(e);
+ }
+ return result;
+ }
+
+ /**
+ * Lists the stored items returned by the given statement.
+ *
+ * @param ps The statement (which must be ready for execution). It is the caller's reponsibility to close this.
+ *
+ * @return The stored items.
+ *
+ * @throws StoreException if an error occurs.
+ */
+ protected List<T> listFromStatement(PreparedStatement ps) throws StoreException {
+ List<T> result = new ArrayList<>();
+ try (ResultSet rs = ps.executeQuery()) {
+ while (rs.next()) {
+ result.add(fromResultSet(rs));
+ }
+ } catch (SQLException e) {
+ LOG.error("Error listing matching items from {}", tableName, e);
+ throw new StoreException(e);
+ }
+ return result;
+ }
+
+ /**
+ * Extracts the first item returned by the given statement, if any.
+ *
+ * @param ps The statement (which must be ready for execution). It is the caller's reponsibility to close this.
+ *
+ * @return The first item, or {@code null} if none.
+ *
+ * @throws StoreException if an error occurs.
+ */
+ protected T firstFromStatement(PreparedStatement ps) throws StoreException {
+ try (ResultSet rs = ps.executeQuery()) {
+ if (rs.next()) {
+ return fromResultSet(rs);
+ } else {
+ return null;
+ }
+ } catch (SQLException e) {
+ LOG.error("Error listing first matching item from {}", tableName, e);
+ throw new StoreException(e);
+ }
+ }
+
+ /**
+ * Converts a single row in a result set to an instance of the managed type.
+ *
+ * @param rs The result set (which is ready for extraction; {@link ResultSet#next()} must <b>not</b> be called).
+ *
+ * @return The corresponding instance.
+ *
+ * @throws SQLException if an error occurs.
+ */
+ protected abstract T fromResultSet(ResultSet rs) throws SQLException;
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java
new file mode 100644
index 00000000..aa8f4b30
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2014, 2016 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+import com.google.common.base.Preconditions;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.opendaylight.aaa.api.model.Domain;
+import org.opendaylight.aaa.api.model.Domains;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author peter.mellquist@hp.com
+ *
+ */
+public class DomainStore extends AbstractStore<Domain> {
+ private static final Logger LOG = LoggerFactory.getLogger(DomainStore.class);
+
+ protected final static String SQL_ID = "domainid";
+ protected final static String SQL_NAME = "name";
+ protected final static String SQL_DESCR = "description";
+ protected final static String SQL_ENABLED = "enabled";
+ private static final String TABLE_NAME = "DOMAINS";
+
+ protected DomainStore() {
+ super(TABLE_NAME);
+ }
+
+ @Override
+ protected String getTableCreationStatement() {
+ return "CREATE TABLE DOMAINS "
+ + "(domainid VARCHAR(128) PRIMARY KEY,"
+ + "name VARCHAR(128) UNIQUE NOT NULL, "
+ + "description VARCHAR(128) , "
+ + "enabled INTEGER NOT NULL)";
+ }
+
+ @Override
+ protected Domain fromResultSet(ResultSet rs) throws SQLException {
+ Domain domain = new Domain();
+ domain.setDomainid(rs.getString(SQL_ID));
+ domain.setName(rs.getString(SQL_NAME));
+ domain.setDescription(rs.getString(SQL_DESCR));
+ domain.setEnabled(rs.getInt(SQL_ENABLED) == 1);
+ return domain;
+ }
+
+ protected Domains getDomains() throws StoreException {
+ Domains domains = new Domains();
+ domains.setDomains(listAll());
+ return domains;
+ }
+
+ protected Domains getDomains(String domainName) throws StoreException {
+ LOG.debug("getDomains for: {}", domainName);
+ Domains domains = new Domains();
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM DOMAINS WHERE name = ?")) {
+ pstmt.setString(1, domainName);
+ LOG.debug("query string: {}", pstmt.toString());
+ domains.setDomains(listFromStatement(pstmt));
+ } catch (SQLException e) {
+ LOG.error("Error listing domains matching {}", domainName, e);
+ throw new StoreException("Error listing domains", e);
+ }
+ return domains;
+ }
+
+ protected Domain getDomain(String id) throws StoreException {
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM DOMAINS WHERE domainid = ? ")) {
+ pstmt.setString(1, id);
+ LOG.debug("query string: {}", pstmt.toString());
+ return firstFromStatement(pstmt);
+ } catch (SQLException e) {
+ LOG.error("Error retrieving domain {}", id, e);
+ throw new StoreException("Error loading domain", e);
+ }
+ }
+
+ protected Domain createDomain(Domain domain) throws StoreException {
+ Preconditions.checkNotNull(domain);
+ Preconditions.checkNotNull(domain.getName());
+ Preconditions.checkNotNull(domain.isEnabled());
+ String query = "insert into DOMAINS (domainid,name,description,enabled) values(?, ?, ?, ?)";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ statement.setString(1, domain.getName());
+ statement.setString(2, domain.getName());
+ statement.setString(3, domain.getDescription());
+ statement.setInt(4, domain.isEnabled() ? 1 : 0);
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows == 0) {
+ throw new StoreException("Creating domain failed, no rows affected.");
+ }
+ domain.setDomainid(domain.getName());
+ return domain;
+ } catch (SQLException e) {
+ LOG.error("Error creating domain {}", domain.getName(), e);
+ throw new StoreException("Error creating domain", e);
+ }
+ }
+
+ protected Domain putDomain(Domain domain) throws StoreException {
+ Domain savedDomain = this.getDomain(domain.getDomainid());
+ if (savedDomain == null) {
+ return null;
+ }
+
+ if (domain.getDescription() != null) {
+ savedDomain.setDescription(domain.getDescription());
+ }
+ if (domain.getName() != null) {
+ savedDomain.setName(domain.getName());
+ }
+ if (domain.isEnabled() != null) {
+ savedDomain.setEnabled(domain.isEnabled());
+ }
+
+ String query = "UPDATE DOMAINS SET description = ?, enabled = ? WHERE domainid = ?";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ statement.setString(1, savedDomain.getDescription());
+ statement.setInt(2, savedDomain.isEnabled() ? 1 : 0);
+ statement.setString(3, savedDomain.getDomainid());
+ statement.executeUpdate();
+ } catch (SQLException e) {
+ LOG.error("Error updating domain {}", domain.getDomainid(), e);
+ throw new StoreException("Error updating domain", e);
+ }
+
+ return savedDomain;
+ }
+
+ protected Domain deleteDomain(String domainid) throws StoreException {
+ domainid = StringEscapeUtils.escapeHtml4(domainid);
+ Domain deletedDomain = this.getDomain(domainid);
+ if (deletedDomain == null) {
+ return null;
+ }
+ String query = String.format("DELETE FROM DOMAINS WHERE domainid = '%s'", domainid);
+ try (Connection conn = dbConnect();
+ Statement statement = conn.createStatement()) {
+ int deleteCount = statement.executeUpdate(query);
+ LOG.debug("deleted {} records", deleteCount);
+ return deletedDomain;
+ } catch (SQLException e) {
+ LOG.error("Error deleting domain {}", domainid, e);
+ throw new StoreException("Error deleting domain", e);
+ }
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java
new file mode 100644
index 00000000..ee86e0ba
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2014, 2016 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.opendaylight.aaa.api.IDMStoreUtil;
+import org.opendaylight.aaa.api.model.Grant;
+import org.opendaylight.aaa.api.model.Grants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author peter.mellquist@hp.com
+ *
+ */
+public class GrantStore extends AbstractStore<Grant> {
+ private static final Logger LOG = LoggerFactory.getLogger(GrantStore.class);
+
+ protected final static String SQL_ID = "grantid";
+ protected final static String SQL_TENANTID = "domainid";
+ protected final static String SQL_USERID = "userid";
+ protected final static String SQL_ROLEID = "roleid";
+ private static final String TABLE_NAME = "GRANTS";
+
+ protected GrantStore() {
+ super(TABLE_NAME);
+ }
+
+ @Override
+ protected String getTableCreationStatement() {
+ return "CREATE TABLE GRANTS "
+ + "(grantid VARCHAR(128) PRIMARY KEY,"
+ + "domainid VARCHAR(128) NOT NULL, "
+ + "userid VARCHAR(128) NOT NULL, "
+ + "roleid VARCHAR(128) NOT NULL)";
+ }
+
+ protected Grant fromResultSet(ResultSet rs) throws SQLException {
+ Grant grant = new Grant();
+ try {
+ grant.setGrantid(rs.getString(SQL_ID));
+ grant.setDomainid(rs.getString(SQL_TENANTID));
+ grant.setUserid(rs.getString(SQL_USERID));
+ grant.setRoleid(rs.getString(SQL_ROLEID));
+ } catch (SQLException sqle) {
+ LOG.error("SQL Exception: ", sqle);
+ throw sqle;
+ }
+ return grant;
+ }
+
+ protected Grants getGrants(String did, String uid) throws StoreException {
+ Grants grants = new Grants();
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn
+ .prepareStatement("SELECT * FROM grants WHERE domainid = ? AND userid = ?")) {
+ pstmt.setString(1, did);
+ pstmt.setString(2, uid);
+ LOG.debug("query string: {}", pstmt.toString());
+ grants.setGrants(listFromStatement(pstmt));
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ return grants;
+ }
+
+ protected Grants getGrants(String userid) throws StoreException {
+ Grants grants = new Grants();
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM GRANTS WHERE userid = ? ")) {
+ pstmt.setString(1, userid);
+ LOG.debug("query string: {}", pstmt.toString());
+ grants.setGrants(listFromStatement(pstmt));
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ return grants;
+ }
+
+ protected Grant getGrant(String id) throws StoreException {
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM GRANTS WHERE grantid = ? ")) {
+ pstmt.setString(1, id);
+ LOG.debug("query string: ", pstmt.toString());
+ return firstFromStatement(pstmt);
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+
+ protected Grant getGrant(String did, String uid, String rid) throws StoreException {
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn
+ .prepareStatement("SELECT * FROM GRANTS WHERE domainid = ? AND userid = ? AND roleid = ? ")) {
+ pstmt.setString(1, did);
+ pstmt.setString(2, uid);
+ pstmt.setString(3, rid);
+ LOG.debug("query string: {}", pstmt.toString());
+ return firstFromStatement(pstmt);
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+
+ protected Grant createGrant(Grant grant) throws StoreException {
+ String query = "insert into grants (grantid,domainid,userid,roleid) values(?,?,?,?)";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ statement.setString(
+ 1,
+ IDMStoreUtil.createGrantid(grant.getUserid(), grant.getDomainid(),
+ grant.getRoleid()));
+ statement.setString(2, grant.getDomainid());
+ statement.setString(3, grant.getUserid());
+ statement.setString(4, grant.getRoleid());
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows == 0) {
+ throw new StoreException("Creating grant failed, no rows affected.");
+ }
+ grant.setGrantid(IDMStoreUtil.createGrantid(grant.getUserid(), grant.getDomainid(),
+ grant.getRoleid()));
+ return grant;
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+
+ protected Grant deleteGrant(String grantid) throws StoreException {
+ grantid = StringEscapeUtils.escapeHtml4(grantid);
+ Grant savedGrant = this.getGrant(grantid);
+ if (savedGrant == null) {
+ return null;
+ }
+
+ String query = String.format("DELETE FROM GRANTS WHERE grantid = '%s'", grantid);
+ try (Connection conn = dbConnect();
+ Statement statement = conn.createStatement()) {
+ int deleteCount = statement.executeUpdate(query);
+ LOG.debug("deleted {} records", deleteCount);
+ return savedGrant;
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java
new file mode 100644
index 00000000..da40a17b
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2015 Cisco Systems and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+
+import org.opendaylight.aaa.api.IDMStoreException;
+import org.opendaylight.aaa.api.IDMStoreUtil;
+import org.opendaylight.aaa.api.IIDMStore;
+import org.opendaylight.aaa.api.model.Domain;
+import org.opendaylight.aaa.api.model.Domains;
+import org.opendaylight.aaa.api.model.Grant;
+import org.opendaylight.aaa.api.model.Grants;
+import org.opendaylight.aaa.api.model.Role;
+import org.opendaylight.aaa.api.model.Roles;
+import org.opendaylight.aaa.api.model.User;
+import org.opendaylight.aaa.api.model.Users;
+import org.opendaylight.aaa.h2.config.IdmLightConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class H2Store implements IIDMStore {
+
+ private static final Logger LOG = LoggerFactory.getLogger(H2Store.class);
+
+ private static IdmLightConfig config = new IdmLightConfig();
+ private DomainStore domainStore = new DomainStore();
+ private UserStore userStore = new UserStore();
+ private RoleStore roleStore = new RoleStore();
+ private GrantStore grantStore = new GrantStore();
+
+ public H2Store() {
+ }
+
+ public static Connection getConnection(Connection existingConnection) throws StoreException {
+ Connection connection = existingConnection;
+ try {
+ if (existingConnection == null || existingConnection.isClosed()) {
+ new org.h2.Driver();
+ connection = DriverManager.getConnection(config.getDbPath(), config.getDbUser(),
+ config.getDbPwd());
+ }
+ } catch (Exception e) {
+ throw new StoreException("Cannot connect to database server" + e);
+ }
+
+ return connection;
+ }
+
+ public static IdmLightConfig getConfig() {
+ return config;
+ }
+
+ @Override
+ public Domain writeDomain(Domain domain) throws IDMStoreException {
+ try {
+ return domainStore.createDomain(domain);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while writing domain", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Domain readDomain(String domainid) throws IDMStoreException {
+ try {
+ return domainStore.getDomain(domainid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading domain", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Domain deleteDomain(String domainid) throws IDMStoreException {
+ try {
+ return domainStore.deleteDomain(domainid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while deleting domain", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Domain updateDomain(Domain domain) throws IDMStoreException {
+ try {
+ return domainStore.putDomain(domain);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while updating domain", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Domains getDomains() throws IDMStoreException {
+ try {
+ return domainStore.getDomains();
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading domains", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Role writeRole(Role role) throws IDMStoreException {
+ try {
+ return roleStore.createRole(role);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while writing role", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Role readRole(String roleid) throws IDMStoreException {
+ try {
+ return roleStore.getRole(roleid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading role", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Role deleteRole(String roleid) throws IDMStoreException {
+ try {
+ return roleStore.deleteRole(roleid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while deleting role", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Role updateRole(Role role) throws IDMStoreException {
+ try {
+ return roleStore.putRole(role);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while updating role", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Roles getRoles() throws IDMStoreException {
+ try {
+ return roleStore.getRoles();
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while getting roles", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public User writeUser(User user) throws IDMStoreException {
+ try {
+ return userStore.createUser(user);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while writing user", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public User readUser(String userid) throws IDMStoreException {
+ try {
+ return userStore.getUser(userid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading user", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public User deleteUser(String userid) throws IDMStoreException {
+ try {
+ return userStore.deleteUser(userid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while deleting user", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public User updateUser(User user) throws IDMStoreException {
+ try {
+ return userStore.putUser(user);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while updating user", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Users getUsers(String username, String domain) throws IDMStoreException {
+ try {
+ return userStore.getUsers(username, domain);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading users", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Users getUsers() throws IDMStoreException {
+ try {
+ return userStore.getUsers();
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading users", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Grant writeGrant(Grant grant) throws IDMStoreException {
+ try {
+ return grantStore.createGrant(grant);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while writing grant", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Grant readGrant(String grantid) throws IDMStoreException {
+ try {
+ return grantStore.getGrant(grantid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while reading grant", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Grant deleteGrant(String grantid) throws IDMStoreException {
+ try {
+ return grantStore.deleteGrant(grantid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while deleting grant", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Grants getGrants(String domainid, String userid) throws IDMStoreException {
+ try {
+ return grantStore.getGrants(domainid, userid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while getting grants", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Grants getGrants(String userid) throws IDMStoreException {
+ try {
+ return grantStore.getGrants(userid);
+ } catch (StoreException e) {
+ LOG.error("StoreException encountered while getting grants", e);
+ throw new IDMStoreException(e);
+ }
+ }
+
+ @Override
+ public Grant readGrant(String domainid, String userid, String roleid) throws IDMStoreException {
+ return readGrant(IDMStoreUtil.createGrantid(userid, domainid, roleid));
+ }
+
+ public static Domain createDomain(String domainName, boolean enable) throws StoreException {
+ DomainStore ds = new DomainStore();
+ Domain d = new Domain();
+ d.setName(domainName);
+ d.setEnabled(enable);
+ return ds.createDomain(d);
+ }
+
+ public static User createUser(String name, String password, String domain, String description,
+ String email, boolean enabled, String SALT) throws StoreException {
+ UserStore us = new UserStore();
+ User u = new User();
+ u.setName(name);
+ u.setDomainid(domain);
+ u.setDescription(description);
+ u.setEmail(email);
+ u.setEnabled(enabled);
+ u.setPassword(password);
+ u.setSalt(SALT);
+ return us.createUser(u);
+ }
+
+ public static Role createRole(String name, String domain, String description)
+ throws StoreException {
+ RoleStore rs = new RoleStore();
+ Role r = new Role();
+ r.setDescription(description);
+ r.setName(name);
+ r.setDomainid(domain);
+ return rs.createRole(r);
+ }
+
+ public static Grant createGrant(String domain, String user, String role) throws StoreException {
+ GrantStore gs = new GrantStore();
+ Grant g = new Grant();
+ g.setDomainid(domain);
+ g.setRoleid(role);
+ g.setUserid(user);
+ return gs.createGrant(g);
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java
new file mode 100644
index 00000000..e7defa4a
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2014, 2016 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+import com.google.common.base.Preconditions;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.opendaylight.aaa.api.IDMStoreUtil;
+import org.opendaylight.aaa.api.model.Role;
+import org.opendaylight.aaa.api.model.Roles;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author peter.mellquist@hp.com
+ *
+ */
+public class RoleStore extends AbstractStore<Role> {
+ private static final Logger LOG = LoggerFactory.getLogger(RoleStore.class);
+
+ protected final static String SQL_ID = "roleid";
+ protected final static String SQL_DOMAIN_ID = "domainid";
+ protected final static String SQL_NAME = "name";
+ protected final static String SQL_DESCR = "description";
+ private static final String TABLE_NAME = "ROLES";
+
+ protected RoleStore() {
+ super(TABLE_NAME);
+ }
+
+ @Override
+ protected String getTableCreationStatement() {
+ return "CREATE TABLE ROLES "
+ + "(roleid VARCHAR(128) PRIMARY KEY,"
+ + "name VARCHAR(128) NOT NULL, "
+ + "domainid VARCHAR(128) NOT NULL, "
+ + "description VARCHAR(128) NOT NULL)";
+ }
+
+ protected Role fromResultSet(ResultSet rs) throws SQLException {
+ Role role = new Role();
+ try {
+ role.setRoleid(rs.getString(SQL_ID));
+ role.setDomainid(rs.getString(SQL_DOMAIN_ID));
+ role.setName(rs.getString(SQL_NAME));
+ role.setDescription(rs.getString(SQL_DESCR));
+ } catch (SQLException sqle) {
+ LOG.error("SQL Exception: ", sqle);
+ throw sqle;
+ }
+ return role;
+ }
+
+ protected Roles getRoles() throws StoreException {
+ Roles roles = new Roles();
+ roles.setRoles(listAll());
+ return roles;
+ }
+
+ protected Role getRole(String id) throws StoreException {
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn
+ .prepareStatement("SELECT * FROM ROLES WHERE roleid = ? ")) {
+ pstmt.setString(1, id);
+ LOG.debug("query string: {}", pstmt.toString());
+ return firstFromStatement(pstmt);
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception: " + s);
+ }
+ }
+
+ protected Role createRole(Role role) throws StoreException {
+ Preconditions.checkNotNull(role);
+ Preconditions.checkNotNull(role.getName());
+ Preconditions.checkNotNull(role.getDomainid());
+ String query = "insert into roles (roleid,domainid,name,description) values(?,?,?,?)";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ role.setRoleid(IDMStoreUtil.createRoleid(role.getName(), role.getDomainid()));
+ statement.setString(1, role.getRoleid());
+ statement.setString(2, role.getDomainid());
+ statement.setString(3, role.getName());
+ statement.setString(4, role.getDescription());
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows == 0) {
+ throw new StoreException("Creating role failed, no rows affected.");
+ }
+ return role;
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+
+ protected Role putRole(Role role) throws StoreException {
+
+ Role savedRole = this.getRole(role.getRoleid());
+ if (savedRole == null) {
+ return null;
+ }
+
+ if (role.getDescription() != null) {
+ savedRole.setDescription(role.getDescription());
+ }
+ if (role.getName() != null) {
+ savedRole.setName(role.getName());
+ }
+
+ String query = "UPDATE roles SET description = ? WHERE roleid = ?";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ statement.setString(1, savedRole.getDescription());
+ statement.setString(2, savedRole.getRoleid());
+ statement.executeUpdate();
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+
+ return savedRole;
+ }
+
+ protected Role deleteRole(String roleid) throws StoreException {
+ roleid = StringEscapeUtils.escapeHtml4(roleid);
+ Role savedRole = this.getRole(roleid);
+ if (savedRole == null) {
+ return null;
+ }
+
+ String query = String.format("DELETE FROM ROLES WHERE roleid = '%s'", roleid);
+ try (Connection conn = dbConnect();
+ Statement statement = conn.createStatement()) {
+ int deleteCount = statement.executeUpdate(query);
+ LOG.debug("deleted {} records", deleteCount);
+ return savedRole;
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java
new file mode 100644
index 00000000..7d2f2b9a
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2014, 2016 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+/**
+ * Exception indicating an error in an H2 data store.
+ *
+ * @author peter.mellquist@hp.com
+ */
+
+public class StoreException extends Exception {
+ public StoreException(String message) {
+ super(message);
+ }
+
+ public StoreException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public StoreException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java
new file mode 100644
index 00000000..96b8013f
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2014, 2016 Hewlett-Packard Development Company, L.P. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+import com.google.common.base.Preconditions;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.apache.commons.lang3.StringEscapeUtils;
+import org.opendaylight.aaa.api.IDMStoreUtil;
+import org.opendaylight.aaa.api.SHA256Calculator;
+import org.opendaylight.aaa.api.model.User;
+import org.opendaylight.aaa.api.model.Users;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author peter.mellquist@hp.com
+ *
+ */
+public class UserStore extends AbstractStore<User> {
+ private static final Logger LOG = LoggerFactory.getLogger(UserStore.class);
+
+ protected final static String SQL_ID = "userid";
+ protected final static String SQL_DOMAIN_ID = "domainid";
+ protected final static String SQL_NAME = "name";
+ protected final static String SQL_EMAIL = "email";
+ protected final static String SQL_PASSWORD = "password";
+ protected final static String SQL_DESCR = "description";
+ protected final static String SQL_ENABLED = "enabled";
+ protected final static String SQL_SALT = "salt";
+ private static final String TABLE_NAME = "USERS";
+
+ protected UserStore() {
+ super(TABLE_NAME);
+ }
+
+ @Override
+ protected String getTableCreationStatement() {
+ return "CREATE TABLE users "
+ + "(userid VARCHAR(128) PRIMARY KEY,"
+ + "name VARCHAR(128) NOT NULL, "
+ + "domainid VARCHAR(128) NOT NULL, "
+ + "email VARCHAR(128) NOT NULL, "
+ + "password VARCHAR(128) NOT NULL, "
+ + "description VARCHAR(128) NOT NULL, "
+ + "salt VARCHAR(15) NOT NULL, "
+ + "enabled INTEGER NOT NULL)";
+ }
+
+ @Override
+ protected User fromResultSet(ResultSet rs) throws SQLException {
+ User user = new User();
+ try {
+ user.setUserid(rs.getString(SQL_ID));
+ user.setDomainid(rs.getString(SQL_DOMAIN_ID));
+ user.setName(rs.getString(SQL_NAME));
+ user.setEmail(rs.getString(SQL_EMAIL));
+ user.setPassword(rs.getString(SQL_PASSWORD));
+ user.setDescription(rs.getString(SQL_DESCR));
+ user.setEnabled(rs.getInt(SQL_ENABLED) == 1);
+ user.setSalt(rs.getString(SQL_SALT));
+ } catch (SQLException sqle) {
+ LOG.error("SQL Exception: ", sqle);
+ throw sqle;
+ }
+ return user;
+ }
+
+ protected Users getUsers() throws StoreException {
+ Users users = new Users();
+ users.setUsers(listAll());
+ return users;
+ }
+
+ protected Users getUsers(String username, String domain) throws StoreException {
+ LOG.debug("getUsers for: {} in domain {}", username, domain);
+
+ Users users = new Users();
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM USERS WHERE userid = ? ")) {
+ pstmt.setString(1, IDMStoreUtil.createUserid(username, domain));
+ LOG.debug("query string: {}", pstmt.toString());
+ users.setUsers(listFromStatement(pstmt));
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ return users;
+ }
+
+ protected User getUser(String id) throws StoreException {
+ try (Connection conn = dbConnect();
+ PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM USERS WHERE userid = ? ")) {
+ pstmt.setString(1, id);
+ LOG.debug("query string: {}", pstmt.toString());
+ return firstFromStatement(pstmt);
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+
+ protected User createUser(User user) throws StoreException {
+ Preconditions.checkNotNull(user);
+ Preconditions.checkNotNull(user.getName());
+ Preconditions.checkNotNull(user.getDomainid());
+
+ user.setSalt(SHA256Calculator.generateSALT());
+ String query = "insert into users (userid,domainid,name,email,password,description,enabled,salt) values(?,?,?,?,?,?,?,?)";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ user.setUserid(IDMStoreUtil.createUserid(user.getName(), user.getDomainid()));
+ statement.setString(1, user.getUserid());
+ statement.setString(2, user.getDomainid());
+ statement.setString(3, user.getName());
+ statement.setString(4, user.getEmail());
+ statement.setString(5, SHA256Calculator.getSHA256(user.getPassword(), user.getSalt()));
+ statement.setString(6, user.getDescription());
+ statement.setInt(7, user.isEnabled() ? 1 : 0);
+ statement.setString(8, user.getSalt());
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows == 0) {
+ throw new StoreException("Creating user failed, no rows affected.");
+ }
+ return user;
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+
+ protected User putUser(User user) throws StoreException {
+
+ User savedUser = this.getUser(user.getUserid());
+ if (savedUser == null) {
+ return null;
+ }
+
+ if (user.getDescription() != null) {
+ savedUser.setDescription(user.getDescription());
+ }
+ if (user.getName() != null) {
+ savedUser.setName(user.getName());
+ }
+ if (user.isEnabled() != null) {
+ savedUser.setEnabled(user.isEnabled());
+ }
+ if (user.getEmail() != null) {
+ savedUser.setEmail(user.getEmail());
+ }
+ if (user.getPassword() != null) {
+ // If a new salt is provided, use it. Otherwise, derive salt from existing.
+ String salt = user.getSalt();
+ if (salt == null) {
+ salt = savedUser.getSalt();
+ }
+ savedUser.setPassword(SHA256Calculator.getSHA256(user.getPassword(), salt));
+ }
+
+ String query = "UPDATE users SET email = ?, password = ?, description = ?, enabled = ? WHERE userid = ?";
+ try (Connection conn = dbConnect();
+ PreparedStatement statement = conn.prepareStatement(query)) {
+ statement.setString(1, savedUser.getEmail());
+ statement.setString(2, savedUser.getPassword());
+ statement.setString(3, savedUser.getDescription());
+ statement.setInt(4, savedUser.isEnabled() ? 1 : 0);
+ statement.setString(5, savedUser.getUserid());
+ statement.executeUpdate();
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+
+ return savedUser;
+ }
+
+ protected User deleteUser(String userid) throws StoreException {
+ userid = StringEscapeUtils.escapeHtml4(userid);
+ User savedUser = this.getUser(userid);
+ if (savedUser == null) {
+ return null;
+ }
+
+ String query = String.format("DELETE FROM USERS WHERE userid = '%s'", userid);
+ try (Connection conn = dbConnect();
+ Statement statement = conn.createStatement()) {
+ int deleteCount = statement.executeUpdate(query);
+ LOG.debug("deleted {} records", deleteCount);
+ return savedUser;
+ } catch (SQLException s) {
+ throw new StoreException("SQL Exception : " + s);
+ }
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModule.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModule.java
new file mode 100644
index 00000000..fe7dd2a6
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModule.java
@@ -0,0 +1,49 @@
+package org.opendaylight.yang.gen.v1.config.aaa.authn.h2.store.rev151128;
+
+import org.opendaylight.aaa.api.IIDMStore;
+import org.opendaylight.aaa.h2.persistence.H2Store;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AAAH2StoreModule extends org.opendaylight.yang.gen.v1.config.aaa.authn.h2.store.rev151128.AbstractAAAH2StoreModule {
+
+ private BundleContext bundleContext;
+ private static final Logger LOG = LoggerFactory.getLogger(AAAH2StoreModule.class);
+
+ public AAAH2StoreModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
+ super(identifier, dependencyResolver);
+ }
+
+ public AAAH2StoreModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.yang.gen.v1.config.aaa.authn.h2.store.rev151128.AAAH2StoreModule oldModule, java.lang.AutoCloseable oldInstance) {
+ super(identifier, dependencyResolver, oldModule, oldInstance);
+ }
+
+ @Override
+ public java.lang.AutoCloseable createInstance() {
+ final H2Store h2Store = new H2Store();
+ final ServiceRegistration<?> serviceRegistration = bundleContext.registerService(IIDMStore.class.getName(), h2Store, null);
+ LOG.info("AAA H2 Store Initialized");
+ return new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ serviceRegistration.unregister();
+ }
+ };
+ }
+
+ /**
+ * @param bundleContext
+ */
+ public void setBundleContext(BundleContext bundleContext) {
+ this.bundleContext = bundleContext;
+ }
+
+ /**
+ * @return the bundleContext
+ */
+ public BundleContext getBundleContext() {
+ return bundleContext;
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModuleFactory.java b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModuleFactory.java
new file mode 100644
index 00000000..dc9e7f99
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModuleFactory.java
@@ -0,0 +1,29 @@
+/*
+* Generated file
+*
+* Generated from: yang module name: aaa-h2-store yang module local name: aaa-h2-store
+* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
+* Generated at: Sat Nov 28 11:00:15 PST 2015
+*
+* Do not modify this file unless it is present under src/main directory
+*/
+package org.opendaylight.yang.gen.v1.config.aaa.authn.h2.store.rev151128;
+
+import org.opendaylight.controller.config.api.DependencyResolver;
+import org.osgi.framework.BundleContext;
+
+public class AAAH2StoreModuleFactory extends org.opendaylight.yang.gen.v1.config.aaa.authn.h2.store.rev151128.AbstractAAAH2StoreModuleFactory {
+ @Override
+ public AAAH2StoreModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, AAAH2StoreModule oldModule, AutoCloseable oldInstance, BundleContext bundleContext) {
+ AAAH2StoreModule module = super.instantiateModule(instanceName, dependencyResolver, oldModule, oldInstance, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+
+ @Override
+ public AAAH2StoreModule instantiateModule(String instanceName, DependencyResolver dependencyResolver, BundleContext bundleContext) {
+ AAAH2StoreModule module = super.instantiateModule(instanceName, dependencyResolver, bundleContext);
+ module.setBundleContext(bundleContext);
+ return module;
+ }
+}
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml b/odl-aaa-moon/aaa/aaa-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml
new file mode 100644
index 00000000..cfe60812
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- vi: set et smarttab sw=4 tabstop=4: -->
+<!--
+ Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+
+ This program and the accompanying materials are made available under the
+ terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ and is available at http://www.eclipse.org/legal/epl-v10.html
+-->
+<snapshot>
+ <configuration>
+ <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+ <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">
+ <module>
+ <type xmlns:authn="config:aaa:authn:h2:store">authn:aaa-h2-store</type>
+ <name>aaa-h2-store</name>
+ </module>
+ </modules>
+ </data>
+ </configuration>
+ <required-capabilities>
+ <capability>config:aaa:authn:h2:store?module=aaa-h2-store&amp;revision=2015-11-28</capability>
+ </required-capabilities>
+
+</snapshot>
+
diff --git a/odl-aaa-moon/aaa/aaa-h2-store/src/main/yang/aaa-h2-store.yang b/odl-aaa-moon/aaa/aaa-h2-store/src/main/yang/aaa-h2-store.yang
new file mode 100644
index 00000000..af2d9bdc
--- /dev/null
+++ b/odl-aaa-moon/aaa/aaa-h2-store/src/main/yang/aaa-h2-store.yang
@@ -0,0 +1,28 @@
+module aaa-h2-store {
+ yang-version 1;
+ namespace "config:aaa:authn:h2:store";
+ prefix "aaa-h2-store";
+ organization "OpenDayLight";
+
+ import config { prefix config; revision-date 2013-04-05; }
+ import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
+
+ contact "saichler@gmail.com";
+
+ revision 2015-11-28 {
+ description
+ "Initial revision.";
+ }
+
+ identity aaa-h2-store {
+ base config:module-type;
+ config:java-name-prefix AAAH2Store;
+ }
+
+ augment "/config:modules/config:module/config:configuration" {
+ case aaa-h2-store {
+ when "/config:modules/config:module/config:type = 'aaa-h2-store'";
+ }
+ }
+
+}