summaryrefslogtreecommitdiffstats
path: root/odl-aaa-moon/aaa-h2-store
diff options
context:
space:
mode:
Diffstat (limited to 'odl-aaa-moon/aaa-h2-store')
-rw-r--r--odl-aaa-moon/aaa-h2-store/.gitignore2
-rw-r--r--odl-aaa-moon/aaa-h2-store/pom.xml160
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java133
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java187
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java166
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java158
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java316
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java151
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java29
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java202
-rw-r--r--odl-aaa-moon/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-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-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml26
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/main/yang/aaa-h2-store.yang28
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/DomainStoreTest.java76
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/GrantStoreTest.java76
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/H2StoreTest.java187
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/RoleStoreTest.java76
-rw-r--r--odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/UserStoreTest.java79
19 files changed, 2130 insertions, 0 deletions
diff --git a/odl-aaa-moon/aaa-h2-store/.gitignore b/odl-aaa-moon/aaa-h2-store/.gitignore
new file mode 100644
index 00000000..1dd33310
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/.gitignore
@@ -0,0 +1,2 @@
+/target/
+/target/
diff --git a/odl-aaa-moon/aaa-h2-store/pom.xml b/odl-aaa-moon/aaa-h2-store/pom.xml
new file mode 100644
index 00000000..2b31525c
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/pom.xml
@@ -0,0 +1,160 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-parent</artifactId>
+ <version>0.3.1-Beryllium-SR1</version>
+ <relativePath>../parent</relativePath>
+ </parent>
+
+ <artifactId>aaa-h2-store</artifactId>
+ <packaging>bundle</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>config-api</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-config</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-binding-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>sal-common-util</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-authn-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.aaa</groupId>
+ <artifactId>aaa-authn</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>org.apache.felix.dependencymanager</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- JDBC -->
+ <dependency>
+ <groupId>com.h2database</groupId>
+ <artifactId>h2</artifactId>
+ </dependency>
+ <!-- Testing Dependencies -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-simple</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>${bundle.plugin.version}</version>
+ <extensions>true</extensions>
+ <configuration>
+ <instructions>
+ <Import-Package>com.google.*,org.opendaylight.aaa.api.*,org.apache.felix.*,org.slf4j.*,org.opendaylight.*,org.osgi.*,org.apache.commons.lang3</Import-Package>
+ <Private-Package>org.h2.*</Private-Package>
+ <Embed-Dependency>h2</Embed-Dependency>
+ </instructions>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.opendaylight.yangtools</groupId>
+ <artifactId>yang-maven-plugin</artifactId>
+ <version>${yangtools.version}</version>
+ <executions>
+ <execution>
+ <id>config</id>
+ <goals>
+ <goal>generate-sources</goal>
+ </goals>
+ <configuration>
+ <codeGenerators>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator</codeGeneratorClass>
+ <outputBaseDir>${jmxGeneratorPath}</outputBaseDir>
+ <additionalConfiguration>
+ <namespaceToPackage1>urn:opendaylight:params:xml:ns:yang:controller==org.opendaylight.controller.config.yang</namespaceToPackage1>
+ </additionalConfiguration>
+ </generator>
+ <generator>
+ <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+ <outputBaseDir>${salGeneratorPath}</outputBaseDir>
+ </generator>
+ </codeGenerators>
+ <inspectDependencies>true</inspectDependencies>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.opendaylight.mdsal</groupId>
+ <artifactId>maven-sal-api-gen-plugin</artifactId>
+ <version>${yangtools.version}</version>
+ <type>jar</type>
+ </dependency>
+ <dependency>
+ <groupId>org.opendaylight.controller</groupId>
+ <artifactId>yang-jmx-generator-plugin</artifactId>
+ <version>${config.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>build-helper-maven-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>attach-artifacts</id>
+ <goals>
+ <goal>attach-artifact</goal>
+ </goals>
+ <phase>package</phase>
+ <configuration>
+ <artifacts>
+ <artifact>
+ <file>${project.build.directory}/classes/initial/08-aaa-h2-store-config.xml</file>
+ <type>xml</type>
+ <classifier>config</classifier>
+ </artifact>
+ </artifacts>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/odl-aaa-moon/aaa-h2-store/src/main/java/org/opendaylight/aaa/h2/config/IdmLightConfig.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/AbstractStore.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/DomainStore.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/GrantStore.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/H2Store.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/RoleStore.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/StoreException.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/aaa/h2/persistence/UserStore.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModule.java b/odl-aaa-moon/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-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-h2-store/src/main/java/org/opendaylight/yang/gen/v1/config/aaa/authn/h2/store/rev151128/AAAH2StoreModuleFactory.java b/odl-aaa-moon/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-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-h2-store/src/main/resources/initial/08-aaa-h2-store-config.xml b/odl-aaa-moon/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-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-h2-store/src/main/yang/aaa-h2-store.yang b/odl-aaa-moon/aaa-h2-store/src/main/yang/aaa-h2-store.yang
new file mode 100644
index 00000000..af2d9bdc
--- /dev/null
+++ b/odl-aaa-moon/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'";
+ }
+ }
+
+}
diff --git a/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/DomainStoreTest.java b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/DomainStoreTest.java
new file mode 100644
index 00000000..f11a99eb
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/DomainStoreTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.persistence;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.aaa.api.model.Domains;
+import org.opendaylight.aaa.h2.persistence.DomainStore;
+
+public class DomainStoreTest {
+
+ Connection connectionMock = mock(Connection.class);
+ private final DomainStore domainStoreUnderTest = new DomainStore();
+
+ @Before
+ public void setup() {
+ domainStoreUnderTest.dbConnection = connectionMock;
+ }
+
+ @After
+ public void teardown() {
+ // dts.destroy();
+ }
+
+ @Test
+ public void getDomainsTest() throws SQLException, Exception {
+ // Setup Mock Behavior
+ String[] tableTypes = { "TABLE" };
+ Mockito.when(connectionMock.isClosed()).thenReturn(false);
+ DatabaseMetaData dbmMock = mock(DatabaseMetaData.class);
+ Mockito.when(connectionMock.getMetaData()).thenReturn(dbmMock);
+ ResultSet rsUserMock = mock(ResultSet.class);
+ Mockito.when(dbmMock.getTables(null, null, "DOMAINS", tableTypes)).thenReturn(rsUserMock);
+ Mockito.when(rsUserMock.next()).thenReturn(true);
+
+ Statement stmtMock = mock(Statement.class);
+ Mockito.when(connectionMock.createStatement()).thenReturn(stmtMock);
+
+ ResultSet rsMock = getMockedResultSet();
+ Mockito.when(stmtMock.executeQuery(anyString())).thenReturn(rsMock);
+
+ // Run Test
+ Domains domains = domainStoreUnderTest.getDomains();
+
+ // Verify
+ assertTrue(domains.getDomains().size() == 1);
+ verify(stmtMock).close();
+ }
+
+ public ResultSet getMockedResultSet() throws SQLException {
+ ResultSet rsMock = mock(ResultSet.class);
+ Mockito.when(rsMock.next()).thenReturn(true).thenReturn(false);
+ Mockito.when(rsMock.getInt(DomainStore.SQL_ID)).thenReturn(1);
+ Mockito.when(rsMock.getString(DomainStore.SQL_NAME)).thenReturn("DomainName_1");
+ Mockito.when(rsMock.getString(DomainStore.SQL_DESCR)).thenReturn("Desc_1");
+ Mockito.when(rsMock.getInt(DomainStore.SQL_ENABLED)).thenReturn(1);
+ return rsMock;
+ }
+}
diff --git a/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/GrantStoreTest.java b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/GrantStoreTest.java
new file mode 100644
index 00000000..168b67e2
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/GrantStoreTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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 static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.aaa.api.model.Grants;
+
+public class GrantStoreTest {
+
+ Connection connectionMock = mock(Connection.class);
+ private final GrantStore grantStoreUnderTest = new GrantStore();
+ private String did = "5";
+ private String uid = "5";
+
+ @Before
+ public void setup() {
+ grantStoreUnderTest.dbConnection = connectionMock;
+ }
+
+ @Test
+ public void getGrantsTest() throws Exception {
+ // Setup Mock Behavior
+ String[] tableTypes = { "TABLE" };
+ Mockito.when(connectionMock.isClosed()).thenReturn(false);
+ DatabaseMetaData dbmMock = mock(DatabaseMetaData.class);
+ Mockito.when(connectionMock.getMetaData()).thenReturn(dbmMock);
+ ResultSet rsUserMock = mock(ResultSet.class);
+ Mockito.when(dbmMock.getTables(null, null, "GRANTS", tableTypes)).thenReturn(rsUserMock);
+ Mockito.when(rsUserMock.next()).thenReturn(true);
+
+ PreparedStatement pstmtMock = mock(PreparedStatement.class);
+ Mockito.when(connectionMock.prepareStatement(anyString())).thenReturn(pstmtMock);
+
+ ResultSet rsMock = getMockedResultSet();
+ Mockito.when(pstmtMock.executeQuery()).thenReturn(rsMock);
+
+ // Run Test
+ Grants grants = grantStoreUnderTest.getGrants(did, uid);
+
+ // Verify
+ assertTrue(grants.getGrants().size() == 1);
+ verify(pstmtMock).close();
+ }
+
+ public ResultSet getMockedResultSet() throws SQLException {
+ ResultSet rsMock = mock(ResultSet.class);
+ Mockito.when(rsMock.next()).thenReturn(true).thenReturn(false);
+ Mockito.when(rsMock.getInt(GrantStore.SQL_ID)).thenReturn(1);
+ Mockito.when(rsMock.getString(GrantStore.SQL_TENANTID)).thenReturn(did);
+ Mockito.when(rsMock.getString(GrantStore.SQL_USERID)).thenReturn(uid);
+ Mockito.when(rsMock.getString(GrantStore.SQL_ROLEID)).thenReturn("Role_1");
+
+ return rsMock;
+
+ }
+
+}
diff --git a/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/H2StoreTest.java b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/H2StoreTest.java
new file mode 100644
index 00000000..f583a302
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/H2StoreTest.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2016 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
+ */
+
+package org.opendaylight.aaa.h2.persistence;
+
+import java.io.File;
+import java.sql.SQLException;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+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.Grant;
+import org.opendaylight.aaa.api.model.Role;
+import org.opendaylight.aaa.api.model.User;
+
+public class H2StoreTest {
+ @BeforeClass
+ public static void start() {
+ File f = new File("idmlight.db.mv.db");
+ if (f.exists()) {
+ f.delete();
+ }
+ f = new File("idmlight.db.trace.db");
+ if (f.exists()) {
+ f.delete();
+ }
+ }
+
+ @AfterClass
+ public static void end() {
+ File f = new File("idmlight.db.mv.db");
+ if (f.exists()) {
+ f.delete();
+ }
+ f = new File("idmlight.db.trace.db");
+ if (f.exists()) {
+ f.delete();
+ }
+ }
+
+ @Before
+ public void before() throws StoreException, SQLException {
+ UserStore us = new UserStore();
+ us.dbClean();
+ DomainStore ds = new DomainStore();
+ ds.dbClean();
+ RoleStore rs = new RoleStore();
+ rs.dbClean();
+ GrantStore gs = new GrantStore();
+ gs.dbClean();
+ }
+
+ @Test
+ public void testCreateDefaultDomain() throws StoreException {
+ Domain d = new Domain();
+ Assert.assertEquals(true, d != null);
+ DomainStore ds = new DomainStore();
+ d.setName(IIDMStore.DEFAULT_DOMAIN);
+ d.setEnabled(true);
+ d = ds.createDomain(d);
+ Assert.assertEquals(true, d != null);
+ }
+
+ @Test
+ public void testCreateTempRole() throws StoreException {
+ Role role = H2Store.createRole("temp", "temp domain", "Temp Testing role");
+ Assert.assertEquals(true, role != null);
+ }
+
+ @Test
+ public void testCreateUser() throws StoreException {
+ User user = H2Store.createUser("test", "pass", "domain", "desc", "email", true, "SALT");
+ Assert.assertEquals(true, user != null);
+ }
+
+ @Test
+ public void testCreateGrant() throws StoreException {
+ Domain d = H2Store.createDomain("sdn", true);
+ Role role = H2Store.createRole("temp", "temp domain", "Temp Testing role");
+ User user = H2Store.createUser("test", "pass", "domain", "desc", "email", true, "SALT");
+ Grant g = H2Store.createGrant(d.getDomainid(), user.getUserid(), role.getRoleid());
+ Assert.assertEquals(true, g != null);
+ }
+
+ @Test
+ public void testUpdatingUserEmail() throws StoreException {
+ UserStore us = new UserStore();
+ Domain d = H2Store.createDomain("sdn", true);
+ User user = H2Store.createUser("test", "pass", d.getDomainid(), "desc", "email", true,
+ "SALT");
+
+ user.setName("test");
+ user = us.putUser(user);
+ Assert.assertEquals(true, user != null);
+
+ user.setEmail("Test@Test.com");
+ user = us.putUser(user);
+
+ user = new User();
+ user.setName("test");
+ user.setDomainid(d.getDomainid());
+ user = us.getUser(IDMStoreUtil.createUserid(user.getName(), user.getDomainid()));
+
+ Assert.assertEquals("Test@Test.com", user.getEmail());
+ }
+ /*
+ * @Test public void testCreateUserViaAPI() throws StoreException { Domain d
+ * = StoreBuilder.createDomain("sdn",true);
+ *
+ * User user = new User(); user.setName("Hello"); user.setPassword("Hello");
+ * user.setDomainid(d.getDomainid()); UserHandler h = new UserHandler();
+ * h.createUser(null, user);
+ *
+ * User u = new User(); u.setName("Hello"); u.setDomainid(d.getDomainid());
+ * UserStore us = new UserStore(); u =
+ * us.getUser(IDMStoreUtil.createUserid(u.getName(),u.getDomainid()));
+ *
+ * Assert.assertEquals(true, u != null); }
+ *
+ * @Test public void testUpdateUserViaAPI() throws StoreException { Domain d
+ * = StoreBuilder.createDomain("sdn",true);
+ *
+ * User user = new User(); user.setName("Hello"); user.setPassword("Hello");
+ * user.setDomainid(d.getDomainid()); UserHandler h = new UserHandler();
+ * h.createUser(null, user);
+ *
+ * user.setEmail("Hello@Hello.com"); user.setPassword("Test123");
+ * h.putUser(null, user, "" + user.getUserid());
+ *
+ * UserStore us = new UserStore();
+ *
+ * User u = new User(); u.setName("Hello"); u.setDomainid(d.getDomainid());
+ * u = us.getUser(IDMStoreUtil.createUserid(u.getName(),u.getDomainid()));
+ *
+ * Assert.assertEquals("Hello@Hello.com", u.getEmail());
+ *
+ * String hash = SHA256Calculator.getSHA256("Test123", u.getSalt());
+ * Assert.assertEquals(u.getPassword(), hash); }
+ *
+ * @Test public void testUpdateUserRoleViaAPI() throws StoreException {
+ * Domain d = StoreBuilder.createDomain("sdn",true); Role role1 =
+ * StoreBuilder.createRole("temp1",d.getDomainid(),"Temp Testing role");
+ * Role role2 =
+ * StoreBuilder.createRole("temp2",d.getDomainid(),"Temp Testing role");
+ *
+ * User user = new User(); user.setName("Hello"); user.setPassword("Hello");
+ * user.setDomainid(d.getDomainid());
+ *
+ * UserHandler h = new UserHandler(); h.createUser(null, user);
+ *
+ * user.setEmail("Hello@Hello.com"); user.setPassword("Test123");
+ * h.putUser(null, user, user.getUserid());
+ *
+ * Grant g = new Grant(); g.setUserid(user.getUserid());
+ * g.setDomainid(d.getDomainid()); g.setRoleid(role1.getRoleid());
+ * GrantStore gs = new GrantStore(); g = gs.createGrant(g);
+ *
+ * Assert.assertEquals(true, g != null); Assert.assertEquals(g.getRoleid(),
+ * role1.getRoleid());
+ *
+ * g = gs.deleteGrant(IDMStoreUtil.createGrantid(user.getUserid(),
+ * d.getDomainid(), role1.getRoleid())); g.setRoleid(role2.getRoleid()); g =
+ * gs.createGrant(g);
+ *
+ * Assert.assertEquals(true, g != null); Assert.assertEquals(g.getRoleid(),
+ * role2.getRoleid());
+ *
+ * User u = new User(); u.setName("Hello"); u.setDomainid(d.getDomainid());
+ * UserStore us = new UserStore(); u =
+ * us.getUser(IDMStoreUtil.createUserid(u.getName(),u.getDomainid()));
+ *
+ * Assert.assertEquals("Hello@Hello.com", u.getEmail());
+ *
+ * String hash = SHA256Calculator.getSHA256("Test123", u.getSalt());
+ * Assert.assertEquals(true, hash.equals(u.getPassword())); }
+ */
+}
diff --git a/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/RoleStoreTest.java b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/RoleStoreTest.java
new file mode 100644
index 00000000..37cb17a6
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/RoleStoreTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.persistence;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.aaa.api.model.Roles;
+import org.opendaylight.aaa.h2.persistence.RoleStore;
+
+public class RoleStoreTest {
+
+ Connection connectionMock = mock(Connection.class);
+ private final RoleStore RoleStoreUnderTest = new RoleStore();
+
+ @Before
+ public void setup() {
+ RoleStoreUnderTest.dbConnection = connectionMock;
+ }
+
+ @After
+ public void teardown() {
+ // dts.destroy();
+ }
+
+ @Test
+ public void getRolesTest() throws SQLException, Exception {
+ // Setup Mock Behavior
+ String[] tableTypes = { "TABLE" };
+ Mockito.when(connectionMock.isClosed()).thenReturn(false);
+ DatabaseMetaData dbmMock = mock(DatabaseMetaData.class);
+ Mockito.when(connectionMock.getMetaData()).thenReturn(dbmMock);
+ ResultSet rsUserMock = mock(ResultSet.class);
+ Mockito.when(dbmMock.getTables(null, null, "ROLES", tableTypes)).thenReturn(rsUserMock);
+ Mockito.when(rsUserMock.next()).thenReturn(true);
+
+ Statement stmtMock = mock(Statement.class);
+ Mockito.when(connectionMock.createStatement()).thenReturn(stmtMock);
+
+ ResultSet rsMock = getMockedResultSet();
+ Mockito.when(stmtMock.executeQuery(anyString())).thenReturn(rsMock);
+
+ // Run Test
+ Roles roles = RoleStoreUnderTest.getRoles();
+
+ // Verify
+ assertTrue(roles.getRoles().size() == 1);
+ verify(stmtMock).close();
+
+ }
+
+ public ResultSet getMockedResultSet() throws SQLException {
+ ResultSet rsMock = mock(ResultSet.class);
+ Mockito.when(rsMock.next()).thenReturn(true).thenReturn(false);
+ Mockito.when(rsMock.getInt(RoleStore.SQL_ID)).thenReturn(1);
+ Mockito.when(rsMock.getString(RoleStore.SQL_NAME)).thenReturn("RoleName_1");
+ Mockito.when(rsMock.getString(RoleStore.SQL_DESCR)).thenReturn("Desc_1");
+ return rsMock;
+ }
+}
diff --git a/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/UserStoreTest.java b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/UserStoreTest.java
new file mode 100644
index 00000000..e214c261
--- /dev/null
+++ b/odl-aaa-moon/aaa-h2-store/src/test/java/org/opendaylight/aaa/h2/persistence/UserStoreTest.java
@@ -0,0 +1,79 @@
+/*
+ * 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.persistence;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.opendaylight.aaa.api.model.Users;
+import org.opendaylight.aaa.h2.persistence.UserStore;
+
+public class UserStoreTest {
+
+ Connection connectionMock = mock(Connection.class);
+ private final UserStore userStoreUnderTest = new UserStore();
+
+ @Before
+ public void setup() {
+ userStoreUnderTest.dbConnection = connectionMock;
+ }
+
+ @After
+ public void teardown() {
+ // dts.destroy();
+ }
+
+ @Test
+ public void getUsersTest() throws SQLException, Exception {
+ // Setup Mock Behavior
+ String[] tableTypes = { "TABLE" };
+ Mockito.when(connectionMock.isClosed()).thenReturn(false);
+ DatabaseMetaData dbmMock = mock(DatabaseMetaData.class);
+ Mockito.when(connectionMock.getMetaData()).thenReturn(dbmMock);
+ ResultSet rsUserMock = mock(ResultSet.class);
+ Mockito.when(dbmMock.getTables(null, null, "USERS", tableTypes)).thenReturn(rsUserMock);
+ Mockito.when(rsUserMock.next()).thenReturn(true);
+
+ Statement stmtMock = mock(Statement.class);
+ Mockito.when(connectionMock.createStatement()).thenReturn(stmtMock);
+
+ ResultSet rsMock = getMockedResultSet();
+ Mockito.when(stmtMock.executeQuery(anyString())).thenReturn(rsMock);
+
+ // Run Test
+ Users users = userStoreUnderTest.getUsers();
+
+ // Verify
+ assertTrue(users.getUsers().size() == 1);
+ verify(stmtMock).close();
+
+ }
+
+ public ResultSet getMockedResultSet() throws SQLException {
+ ResultSet rsMock = mock(ResultSet.class);
+ Mockito.when(rsMock.next()).thenReturn(true).thenReturn(false);
+ Mockito.when(rsMock.getInt(UserStore.SQL_ID)).thenReturn(1);
+ Mockito.when(rsMock.getString(UserStore.SQL_NAME)).thenReturn("Name_1");
+ Mockito.when(rsMock.getString(UserStore.SQL_EMAIL)).thenReturn("Name_1@company.com");
+ Mockito.when(rsMock.getString(UserStore.SQL_PASSWORD)).thenReturn("Pswd_1");
+ Mockito.when(rsMock.getString(UserStore.SQL_DESCR)).thenReturn("Desc_1");
+ Mockito.when(rsMock.getInt(UserStore.SQL_ENABLED)).thenReturn(1);
+ return rsMock;
+ }
+}