From 9ca21c29f8bb78858490a3b27a96486ab14e3a7a Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 23 Aug 2014 20:49:52 +0200 Subject: [PATCH] [New] Implemented opt-in audit trail in Strolch The audit trail has its own map on the Realm and a trail is written by realm at the end of the transaction. You can write your own audit trail using tx.getAuditTrail(). Enable the audit trail by setting the realm configuration value 'enableAuditTrail'. --- .../postgresql/DbSchemaVersionCheck.java | 3 +- .../postgresql/PostgreSqlAuditDao.java | 326 ++++++++++++++++++ .../PostgreSqlPersistenceHandler.java | 12 +- .../PostgreSqlStrolchTransaction.java | 37 +- .../persistence/postgresql/PostgresqlDao.java | 3 - src/main/resources/db_schema_0.2.0_drop.sql | 8 + .../resources/db_schema_0.2.0_initial.sql | 61 ++++ src/main/resources/db_version.properties | 2 +- .../dao/test/ObserverUpdateTest.java | 15 +- .../postgresql/dao/test/RealmTest.java | 16 +- .../cachedruntime/config/PrivilegeConfig.xml | 30 ++ .../cachedruntime/config/PrivilegeModel.xml | 36 ++ .../config/StrolchConfiguration.xml | 10 + .../realmtest/config/PrivilegeConfig.xml | 30 ++ .../realmtest/config/PrivilegeModel.xml | 36 ++ .../realmtest/config/StrolchConfiguration.xml | 11 + .../config/PrivilegeConfig.xml | 30 ++ .../config/PrivilegeModel.xml | 36 ++ .../config/StrolchConfiguration.xml | 10 + 19 files changed, 686 insertions(+), 26 deletions(-) create mode 100644 src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java create mode 100644 src/main/resources/db_schema_0.2.0_drop.sql create mode 100644 src/main/resources/db_schema_0.2.0_initial.sql create mode 100644 src/test/resources/cachedruntime/config/PrivilegeConfig.xml create mode 100644 src/test/resources/cachedruntime/config/PrivilegeModel.xml create mode 100644 src/test/resources/realmtest/config/PrivilegeConfig.xml create mode 100644 src/test/resources/realmtest/config/PrivilegeModel.xml create mode 100644 src/test/resources/transactionalruntime/config/PrivilegeConfig.xml create mode 100644 src/test/resources/transactionalruntime/config/PrivilegeModel.xml diff --git a/src/main/java/li/strolch/persistence/postgresql/DbSchemaVersionCheck.java b/src/main/java/li/strolch/persistence/postgresql/DbSchemaVersionCheck.java index e93c6c896..7ad6bc8cd 100644 --- a/src/main/java/li/strolch/persistence/postgresql/DbSchemaVersionCheck.java +++ b/src/main/java/li/strolch/persistence/postgresql/DbSchemaVersionCheck.java @@ -76,7 +76,7 @@ public class DbSchemaVersionCheck { String username = connectionInfo.getUsername(); String password = connectionInfo.getPassword(); - logger.info(MessageFormat.format("[{0}] Checking Schema version...", realm)); + logger.info(MessageFormat.format("[{0}] Checking Schema version for: {1}@{2}", realm, username, url)); try (Connection con = DriverManager.getConnection(url, username, password); Statement st = con.createStatement();) { @@ -202,5 +202,4 @@ public class DbSchemaVersionCheck { dropSchema(realm, dbVersion, st); createSchema(realm, dbVersion, st); } - } diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java new file mode 100644 index 000000000..8884eedae --- /dev/null +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java @@ -0,0 +1,326 @@ +/* + * Copyright 2013 Robert von Burg + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package li.strolch.persistence.postgresql; + +import java.sql.Date; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import li.strolch.model.audit.AccessType; +import li.strolch.model.audit.Audit; +import li.strolch.model.audit.AuditQuery; +import li.strolch.model.audit.AuditVisitor; +import li.strolch.persistence.api.AuditDao; +import li.strolch.persistence.api.StrolchPersistenceException; +import ch.eitchnet.utils.collections.DateRange; + +/** + * @author Robert von Burg + */ +public class PostgreSqlAuditDao implements AuditDao { + + private PostgreSqlStrolchTransaction tx; + + /** + * @param postgreSqlStrolchTransaction + */ + public PostgreSqlAuditDao(PostgreSqlStrolchTransaction postgreSqlStrolchTransaction) { + this.tx = postgreSqlStrolchTransaction; + } + + @Override + public boolean hasElement(String type, Long id) { + String sql = "select count(*) from audits where element_type = ? and id = ?"; + try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) { + + statement.setString(1, type); + statement.setLong(2, id); + + try (ResultSet result = statement.executeQuery()) { + result.next(); + long numberOfElements = result.getLong(1); + if (numberOfElements == 0) + return false; + if (numberOfElements == 1) + return true; + + String msg = MessageFormat.format("Non unique number of elements with type {0} and id {1}", type, id); + throw new StrolchPersistenceException(msg); + } + + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e); + } + } + + @Override + public long querySize(DateRange dateRange) { + String sql = "select count(*) from audits where date between ? and ?"; + try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) { + + statement.setDate(1, new Date(dateRange.getFromDate().getTime()), Calendar.getInstance()); + statement.setDate(2, new Date(dateRange.getToDate().getTime()), Calendar.getInstance()); + + try (ResultSet result = statement.executeQuery()) { + result.next(); + return result.getLong(1); + } + + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e); + } + } + + @Override + public long querySize(String type, DateRange dateRange) { + String sql = "select count(*) from audits where element_type = ? and date between ? and ?"; + try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) { + + statement.setString(1, type); + statement.setDate(2, new Date(dateRange.getFromDate().getTime()), Calendar.getInstance()); + statement.setDate(3, new Date(dateRange.getToDate().getTime()), Calendar.getInstance()); + + try (ResultSet result = statement.executeQuery()) { + result.next(); + return result.getLong(1); + } + + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query size due to: " + e.getMessage(), e); + } + } + + @Override + public Set queryTypes() { + Set keySet = new HashSet<>(); + + String sql = "select distinct element_type from audits"; + try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) { + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + keySet.add(result.getString("element_type")); + } + } + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query types due to: " + e.getMessage(), e); + } + + return keySet; + } + + @Override + public Audit queryBy(String type, Long id) { + + String sql = "select id, username, firstname, lastname, date, element_type, element_accessed, new_version, action, access_type from audits where element_type = ? and id = ?"; + try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) { + + statement.setString(1, type); + statement.setLong(2, id); + + try (ResultSet result = statement.executeQuery()) { + if (!result.next()) { + return null; + } + Audit audit = auditFrom(result); + if (result.next()) + throw new StrolchPersistenceException("Non unique result for query: " + sql); + return audit; + } + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query types due to: " + e.getMessage(), e); + } + } + + @Override + public List queryAll(String type, DateRange dateRange) { + List list = new ArrayList<>(); + String sql = "select id, username, firstname, lastname, date, element_type, element_accessed, new_version, action, access_type from audits where element_type = ? and date between ? and ?"; + try (PreparedStatement statement = this.tx.getConnection().prepareStatement(sql)) { + + statement.setString(1, type); + statement.setDate(2, new Date(dateRange.getFromDate().getTime()), Calendar.getInstance()); + statement.setDate(3, new Date(dateRange.getToDate().getTime()), Calendar.getInstance()); + + try (ResultSet result = statement.executeQuery()) { + while (result.next()) { + list.add(auditFrom(result)); + } + } + + } catch (SQLException e) { + throw new StrolchPersistenceException("Failed to query types due to: " + e.getMessage(), e); + } + + return list; + } + + @Override + public void save(Audit audit) { + String sql = "insert into audits (id, username, firstname, lastname, date, element_type, element_accessed, new_version, action, access_type) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?::access_type)"; + try (PreparedStatement preparedStatement = tx.getConnection().prepareStatement(sql)) { + + setAuditFields(audit, preparedStatement); + + int count = preparedStatement.executeUpdate(); + if (count != 1) { + throw new StrolchPersistenceException(MessageFormat.format( + "Expected to create 1 record, but created {0} for audit {2}", count, audit.getId())); + } + + } catch (SQLException e) { + throw new StrolchPersistenceException(MessageFormat.format("Failed to update Audit {0} due to {1}", audit, + e.getLocalizedMessage()), e); + } + } + + @Override + public void saveAll(List audits) { + for (Audit audit : audits) { + save(audit); + } + } + + @Override + public void update(Audit audit) { + String sql = "update audits set id = ?, username = ?, firstname = ?, lastname = ?, date = ?, element_type = ?, element_accessed = ?, new_version = ?, action = ?, access_type = ?::access_type where id = ?"; + try (PreparedStatement preparedStatement = tx.getConnection().prepareStatement(sql)) { + + setAuditFields(audit, preparedStatement); + preparedStatement.setLong(11, audit.getId()); + + int count = preparedStatement.executeUpdate(); + if (count != 1) { + throw new StrolchPersistenceException(MessageFormat.format( + "Expected to update 1 record, but updated {0} for audit {2}", count, audit.getId())); + } + + } catch (SQLException e) { + throw new StrolchPersistenceException(MessageFormat.format("Failed to update Audit {0} due to {1}", audit, + e.getLocalizedMessage()), e); + } + } + + @Override + public void updateAll(List audits) { + for (Audit audit : audits) { + update(audit); + } + } + + @Override + public void remove(Audit audit) { + String sql = "delete from audits where id = ?"; + try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) { + + preparedStatement.setLong(1, audit.getId()); + + int count = preparedStatement.executeUpdate(); + if (count != 1) { + String msg = "Expected to delete 1 audit with id {0} but deleted {1} elements!"; + msg = MessageFormat.format(msg, audit.getId(), count); + throw new StrolchPersistenceException(msg); + } + + } catch (SQLException e) { + throw new StrolchPersistenceException(MessageFormat.format("Failed to remove {0} due to {2}", + audit.getId(), e.getLocalizedMessage()), e); + } + } + + @Override + public void removeAll(List audits) { + for (Audit audit : audits) { + remove(audit); + } + } + + @Override + public long removeAll(String type, DateRange dateRange) { + String sql = "delete from audits where element_type = ? and date between ? and ?"; + try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) { + + preparedStatement.setString(1, type); + preparedStatement.setDate(2, new Date(dateRange.getFromDate().getTime()), Calendar.getInstance()); + preparedStatement.setDate(3, new Date(dateRange.getToDate().getTime()), Calendar.getInstance()); + + int modCount = preparedStatement.executeUpdate(); + return modCount; + + } catch (SQLException e) { + throw new StrolchPersistenceException(MessageFormat.format("Failed to remove all elements due to {0}", + e.getLocalizedMessage()), e); + } + } + + @Override + public List doQuery(AuditQuery query, AuditVisitor auditVisitor) { + // TODO Auto-generated method stub + return null; + } + + private void setAuditFields(Audit audit, PreparedStatement ps) throws SQLException { + + // 1 id = ?, + // 2 username = ?, + // 3 firstname = ?, + // 4 lastname = ?, + // 5 date = ?, + // 6 element_type = ?, + // 7 element_accessed = ?, + // 8 new_version = ?, + // 9 action = ?, + // 10 access_type = ?::access_type + + ps.setLong(1, audit.getId()); + ps.setString(2, audit.getUsername()); + ps.setString(3, audit.getFirstname()); + ps.setString(4, audit.getLastname()); + ps.setDate(5, new Date(audit.getDate().getTime()), Calendar.getInstance()); + ps.setString(6, audit.getElementType()); + ps.setString(7, audit.getElementAccessed()); + + if (audit.getNewVersion() == null) + ps.setDate(8, null); + else + ps.setDate(8, new Date(audit.getNewVersion().getTime()), Calendar.getInstance()); + + ps.setString(9, audit.getAction()); + ps.setString(10, audit.getAccessType().name()); + } + + private Audit auditFrom(ResultSet resultSet) throws SQLException { + + Audit audit = new Audit(); + audit.setId(resultSet.getLong(1)); + audit.setUsername(resultSet.getString(2)); + audit.setFirstname(resultSet.getString(3)); + audit.setLastname(resultSet.getString(4)); + audit.setDate(resultSet.getDate(5)); + audit.setElementType(resultSet.getString(6)); + audit.setElementAccessed(resultSet.getString(7)); + audit.setNewVersion(resultSet.getDate(8)); + audit.setAction(resultSet.getString(9)); + audit.setAccessType(AccessType.valueOf(resultSet.getString(10))); + return audit; + } +} diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlPersistenceHandler.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlPersistenceHandler.java index c158762ca..8e18e58f4 100644 --- a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlPersistenceHandler.java +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlPersistenceHandler.java @@ -29,6 +29,7 @@ import java.util.Set; import li.strolch.agent.api.ComponentContainer; import li.strolch.agent.api.StrolchComponent; import li.strolch.agent.api.StrolchRealm; +import li.strolch.persistence.api.AuditDao; import li.strolch.persistence.api.DbConnectionInfo; import li.strolch.persistence.api.OrderDao; import li.strolch.persistence.api.PersistenceHandler; @@ -39,6 +40,7 @@ import li.strolch.runtime.StrolchConstants; import li.strolch.runtime.configuration.ComponentConfiguration; import li.strolch.runtime.configuration.StrolchConfigurationException; import li.strolch.runtime.observer.ObserverHandler; +import ch.eitchnet.privilege.model.Certificate; /** * @author Robert von Burg @@ -128,8 +130,9 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe super.start(); } - public StrolchTransaction openTx(StrolchRealm realm) { - PostgreSqlStrolchTransaction tx = new PostgreSqlStrolchTransaction(realm, this); + @Override + public StrolchTransaction openTx(StrolchRealm realm, Certificate certificate, String action) { + PostgreSqlStrolchTransaction tx = new PostgreSqlStrolchTransaction(realm, certificate, action, this); if (getContainer().hasComponent(ObserverHandler.class)) { tx.setObserverHandler(getContainer().getComponent(ObserverHandler.class)); } @@ -165,4 +168,9 @@ public class PostgreSqlPersistenceHandler extends StrolchComponent implements Pe public ResourceDao getResourceDao(StrolchTransaction tx) { return ((PostgreSqlStrolchTransaction) tx).getResourceDao(); } + + @Override + public AuditDao getAuditDao(StrolchTransaction tx) { + return ((PostgreSqlStrolchTransaction) tx).getAuditDao(); + } } diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java index fa4709d26..d8026176d 100644 --- a/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java +++ b/src/main/java/li/strolch/persistence/postgresql/PostgreSqlStrolchTransaction.java @@ -19,6 +19,7 @@ import java.sql.Connection; import li.strolch.agent.api.StrolchRealm; import li.strolch.persistence.api.AbstractTransaction; +import li.strolch.persistence.api.AuditDao; import li.strolch.persistence.api.OrderDao; import li.strolch.persistence.api.PersistenceHandler; import li.strolch.persistence.api.ResourceDao; @@ -27,6 +28,8 @@ import li.strolch.persistence.api.TransactionResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import ch.eitchnet.privilege.model.Certificate; + public class PostgreSqlStrolchTransaction extends AbstractTransaction { private static final Logger logger = LoggerFactory.getLogger(PostgreSqlStrolchTransaction.class); @@ -34,15 +37,17 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction { private PostgresqlDao orderDao; private PostgresqlDao resourceDao; + private AuditDao auditDao; private Connection connection; - public PostgreSqlStrolchTransaction(StrolchRealm realm, PostgreSqlPersistenceHandler persistenceHandler) { - super(realm); + public PostgreSqlStrolchTransaction(StrolchRealm realm, Certificate certificate, String action, + PostgreSqlPersistenceHandler persistenceHandler) { + super(realm, certificate, action); this.persistenceHandler = persistenceHandler; } @Override - protected void commit(TransactionResult txResult) throws Exception { + protected void writeChanges(TransactionResult txResult) throws Exception { // first perform DAOs if (this.orderDao != null) @@ -50,13 +55,7 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction { if (this.resourceDao != null) this.resourceDao.commit(txResult); - // then commit the SQL connection - if (this.connection != null) { - this.connection.commit(); - - // and close the connection, but not catching, as otherwise we can't rollback in exception case - this.connection.close(); - } + // don't commit the connection, this is done in postCommit when we close the connection } @Override @@ -74,6 +73,14 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction { } } + @Override + protected void commit() throws Exception { + if (this.connection != null) { + this.connection.commit(); + this.connection.close(); + } + } + OrderDao getOrderDao() { if (this.orderDao == null) this.orderDao = new PostgreSqlOrderDao(this); @@ -86,6 +93,15 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction { return (ResourceDao) this.resourceDao; } + /** + * @return + */ + public AuditDao getAuditDao() { + if (this.auditDao == null) + this.auditDao = new PostgreSqlAuditDao(this); + return (AuditDao) this.auditDao; + } + Connection getConnection() { if (this.connection == null) { this.connection = this.persistenceHandler.getConnection(getRealm().getRealm()); @@ -97,4 +113,5 @@ public class PostgreSqlStrolchTransaction extends AbstractTransaction { public PersistenceHandler getPersistenceHandler() { return this.persistenceHandler; } + } diff --git a/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java b/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java index 12c3c4644..163da325e 100644 --- a/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java +++ b/src/main/java/li/strolch/persistence/postgresql/PostgresqlDao.java @@ -37,9 +37,6 @@ public abstract class PostgresqlDao implements Strolch protected PostgreSqlStrolchTransaction tx; protected List commands; - /** - * @param tx - */ public PostgresqlDao(PostgreSqlStrolchTransaction tx) { this.tx = tx; this.commands = new ArrayList<>(); diff --git a/src/main/resources/db_schema_0.2.0_drop.sql b/src/main/resources/db_schema_0.2.0_drop.sql new file mode 100644 index 000000000..467a2c3ed --- /dev/null +++ b/src/main/resources/db_schema_0.2.0_drop.sql @@ -0,0 +1,8 @@ + +DROP TABLE IF EXISTS resources; +DROP TABLE IF EXISTS orders; +DROP TABLE IF EXISTS audits; +DROP TABLE IF EXISTS db_version; + +DROP TYPE IF EXISTS order_state; +DROP TYPE IF EXISTS access_type; diff --git a/src/main/resources/db_schema_0.2.0_initial.sql b/src/main/resources/db_schema_0.2.0_initial.sql new file mode 100644 index 000000000..dd7a298be --- /dev/null +++ b/src/main/resources/db_schema_0.2.0_initial.sql @@ -0,0 +1,61 @@ + +-- DB_VERSION +CREATE TABLE IF NOT EXISTS db_version ( + id SERIAL PRIMARY KEY, + version varchar(255), + description varchar(255), + created timestamp with time zone +); + +-- RESOURCES +CREATE TABLE IF NOT EXISTS resources ( + id varchar(255) PRIMARY KEY, + name VARCHAR(255), + type VARCHAR(255), + asxml xml +); + +-- ORDERS +CREATE TYPE order_state AS ENUM ('CREATED', 'OPEN', 'EXECUTION', 'CLOSED'); + +CREATE TABLE IF NOT EXISTS orders ( + id varchar(255) PRIMARY KEY, + name VARCHAR(255), + type VARCHAR(255), + state order_state, + date timestamp with time zone, + asxml xml +); + +-- AUDITS +CREATE TYPE access_type AS ENUM ('READ', 'CREATE', 'UPDATE', 'DELETE'); +CREATE TABLE IF NOT EXISTS audits ( + id bigint PRIMARY KEY, + username VARCHAR(255) NOT NULL, + firstname VARCHAR(255) NOT NULL, + lastname VARCHAR(255) NOT NULL, + date timestamp with time zone NOT NULL, + + element_type VARCHAR(255) NOT NULL, + element_accessed VARCHAR(255) NOT NULL, + new_version timestamp with time zone, + + action VARCHAR(255) NOT NULL, + access_type access_type NOT NULL +); + +-- set version +INSERT INTO db_version + (version, description, created) +values( + '0.1.0', + 'Initial schema version', + CURRENT_TIMESTAMP +); +INSERT INTO db_version + (version, description, created) +values( + '0.2.0', + 'Added new table for audits', + CURRENT_TIMESTAMP +); diff --git a/src/main/resources/db_version.properties b/src/main/resources/db_version.properties index d0ef82ac6..ac24bcc3c 100644 --- a/src/main/resources/db_version.properties +++ b/src/main/resources/db_version.properties @@ -1,2 +1,2 @@ # Property file defining what the currently expected version is supposed to be -db_version=0.1.0 \ No newline at end of file +db_version=0.2.0 \ No newline at end of file diff --git a/src/test/java/li/strolch/persistence/postgresql/dao/test/ObserverUpdateTest.java b/src/test/java/li/strolch/persistence/postgresql/dao/test/ObserverUpdateTest.java index 6b26990a7..9af319ff7 100644 --- a/src/test/java/li/strolch/persistence/postgresql/dao/test/ObserverUpdateTest.java +++ b/src/test/java/li/strolch/persistence/postgresql/dao/test/ObserverUpdateTest.java @@ -17,6 +17,10 @@ package li.strolch.persistence.postgresql.dao.test; import static li.strolch.model.ModelGenerator.createOrder; import static li.strolch.model.ModelGenerator.createResource; +import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_PASSWORD; +import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_URL; +import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.DB_USERNAME; +import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.dropSchema; import static org.junit.Assert.assertEquals; import java.io.File; @@ -36,12 +40,14 @@ import li.strolch.persistence.api.StrolchTransaction; import li.strolch.runtime.StrolchConstants; import li.strolch.runtime.observer.Observer; import li.strolch.runtime.observer.ObserverHandler; +import li.strolch.runtime.privilege.PrivilegeHandler; import li.strolch.testbase.runtime.RuntimeMock; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; -import static li.strolch.persistence.postgresql.dao.test.CachedDaoTest.*; + +import ch.eitchnet.privilege.model.Certificate; /** * @author Robert von Burg @@ -113,15 +119,18 @@ public class ObserverUpdateTest { runtimeMock.getContainer().getComponent(ObserverHandler.class).registerObserver(Tags.ORDER, observer); runtimeMock.getContainer().getComponent(ObserverHandler.class).registerObserver(Tags.RESOURCE, observer); + PrivilegeHandler privilegeHandler = runtimeMock.getAgent().getContainer().getPrivilegeHandler(); + Certificate certificate = privilegeHandler.authenticate("test", "test".getBytes()); + // create order Order newOrder = createOrder("MyTestOrder", "Test Name", "TestType", new Date(), State.CREATED); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx();) { + try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test")) { tx.getOrderMap().add(tx, newOrder); } // create resource Resource newResource = createResource("MyTestResource", "Test Name", "TestType"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx();) { + try (StrolchTransaction tx = runtimeMock.getRealm(StrolchConstants.DEFAULT_REALM).openTx(certificate, "test");) { tx.getResourceMap().add(tx, newResource); } diff --git a/src/test/java/li/strolch/persistence/postgresql/dao/test/RealmTest.java b/src/test/java/li/strolch/persistence/postgresql/dao/test/RealmTest.java index 47f60b199..78156edf9 100644 --- a/src/test/java/li/strolch/persistence/postgresql/dao/test/RealmTest.java +++ b/src/test/java/li/strolch/persistence/postgresql/dao/test/RealmTest.java @@ -27,6 +27,7 @@ import li.strolch.agent.impl.DataStoreMode; import li.strolch.model.ModelGenerator; import li.strolch.model.Resource; import li.strolch.persistence.api.StrolchTransaction; +import li.strolch.runtime.privilege.PrivilegeHandler; import li.strolch.testbase.runtime.AbstractModelTest; import li.strolch.testbase.runtime.RuntimeMock; @@ -35,6 +36,8 @@ import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; +import ch.eitchnet.privilege.model.Certificate; + public class RealmTest extends AbstractModelTest { public static final String RUNTIME_PATH = "target/realmtest/"; //$NON-NLS-1$ @@ -74,15 +77,18 @@ public class RealmTest extends AbstractModelTest { String expectedId2 = "@realmTestId2"; String type = "Bla"; + PrivilegeHandler privilegeHandler = runtimeMock.getAgent().getContainer().getPrivilegeHandler(); + Certificate certificate = privilegeHandler.authenticate("test", "test".getBytes()); + { StrolchRealm firstRealm = runtimeMock.getRealm("first"); assertEquals(DataStoreMode.TRANSACTIONAL, firstRealm.getMode()); Resource expectedRes1 = ModelGenerator.createResource(expectedId1, "Bla bla", type); - try (StrolchTransaction tx = firstRealm.openTx()) { + try (StrolchTransaction tx = firstRealm.openTx(certificate, "test")) { tx.getResourceMap().add(tx, expectedRes1); } - try (StrolchTransaction tx = firstRealm.openTx()) { + try (StrolchTransaction tx = firstRealm.openTx(certificate, "test")) { Resource res = tx.getResourceMap().getBy(tx, type, expectedId1); assertEquals("Should find object previously added in same realm!", expectedRes1, res); } @@ -92,11 +98,11 @@ public class RealmTest extends AbstractModelTest { StrolchRealm secondRealm = runtimeMock.getRealm("second"); assertEquals(DataStoreMode.TRANSACTIONAL, secondRealm.getMode()); Resource expectedRes2 = ModelGenerator.createResource(expectedId2, "Bla bla", type); - try (StrolchTransaction tx = secondRealm.openTx()) { + try (StrolchTransaction tx = secondRealm.openTx(certificate, "test")) { tx.getResourceMap().add(tx, expectedRes2); } - try (StrolchTransaction tx = secondRealm.openTx()) { + try (StrolchTransaction tx = secondRealm.openTx(certificate, "test")) { Resource res = tx.getResourceMap().getBy(tx, type, expectedId2); assertEquals("Should find object previously added in same realm!", expectedRes2, res); } @@ -104,7 +110,7 @@ public class RealmTest extends AbstractModelTest { { StrolchRealm secondRealm = runtimeMock.getRealm("second"); - try (StrolchTransaction tx = secondRealm.openTx()) { + try (StrolchTransaction tx = secondRealm.openTx(certificate, "test")) { Resource res = tx.getResourceMap().getBy(tx, type, expectedId1); assertNull("Should not find object added in differenct realm!", res); } diff --git a/src/test/resources/cachedruntime/config/PrivilegeConfig.xml b/src/test/resources/cachedruntime/config/PrivilegeConfig.xml new file mode 100644 index 000000000..9d7a227e3 --- /dev/null +++ b/src/test/resources/cachedruntime/config/PrivilegeConfig.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/cachedruntime/config/PrivilegeModel.xml b/src/test/resources/cachedruntime/config/PrivilegeModel.xml new file mode 100644 index 000000000..14af39def --- /dev/null +++ b/src/test/resources/cachedruntime/config/PrivilegeModel.xml @@ -0,0 +1,36 @@ + + + + + + SYSTEM + + agent + + + + Application + Administrator + ENABLED + en_GB + + PrivilegeAdmin + AppUser + + + + + + + + + true + + + + + true + + + + \ No newline at end of file diff --git a/src/test/resources/cachedruntime/config/StrolchConfiguration.xml b/src/test/resources/cachedruntime/config/StrolchConfiguration.xml index b030e7899..733a7bf4b 100644 --- a/src/test/resources/cachedruntime/config/StrolchConfiguration.xml +++ b/src/test/resources/cachedruntime/config/StrolchConfiguration.xml @@ -7,13 +7,23 @@ true + + PrivilegeHandler + li.strolch.runtime.privilege.PrivilegeHandler + li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler + + PrivilegeConfig.xml + + RealmHandler li.strolch.agent.api.RealmHandler li.strolch.agent.impl.DefaultRealmHandler + PrivilegeHandler PersistenceHandler TRANSACTIONAL + true diff --git a/src/test/resources/realmtest/config/PrivilegeConfig.xml b/src/test/resources/realmtest/config/PrivilegeConfig.xml new file mode 100644 index 000000000..9d7a227e3 --- /dev/null +++ b/src/test/resources/realmtest/config/PrivilegeConfig.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/realmtest/config/PrivilegeModel.xml b/src/test/resources/realmtest/config/PrivilegeModel.xml new file mode 100644 index 000000000..14af39def --- /dev/null +++ b/src/test/resources/realmtest/config/PrivilegeModel.xml @@ -0,0 +1,36 @@ + + + + + + SYSTEM + + agent + + + + Application + Administrator + ENABLED + en_GB + + PrivilegeAdmin + AppUser + + + + + + + + + true + + + + + true + + + + \ No newline at end of file diff --git a/src/test/resources/realmtest/config/StrolchConfiguration.xml b/src/test/resources/realmtest/config/StrolchConfiguration.xml index 6367afe64..d80df1c91 100644 --- a/src/test/resources/realmtest/config/StrolchConfiguration.xml +++ b/src/test/resources/realmtest/config/StrolchConfiguration.xml @@ -7,15 +7,26 @@ true + + PrivilegeHandler + li.strolch.runtime.privilege.PrivilegeHandler + li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler + + PrivilegeConfig.xml + + RealmHandler li.strolch.agent.api.RealmHandler li.strolch.agent.impl.DefaultRealmHandler + PrivilegeHandler PersistenceHandler first, second TRANSACTIONAL TRANSACTIONAL + true + true diff --git a/src/test/resources/transactionalruntime/config/PrivilegeConfig.xml b/src/test/resources/transactionalruntime/config/PrivilegeConfig.xml new file mode 100644 index 000000000..9d7a227e3 --- /dev/null +++ b/src/test/resources/transactionalruntime/config/PrivilegeConfig.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/transactionalruntime/config/PrivilegeModel.xml b/src/test/resources/transactionalruntime/config/PrivilegeModel.xml new file mode 100644 index 000000000..14af39def --- /dev/null +++ b/src/test/resources/transactionalruntime/config/PrivilegeModel.xml @@ -0,0 +1,36 @@ + + + + + + SYSTEM + + agent + + + + Application + Administrator + ENABLED + en_GB + + PrivilegeAdmin + AppUser + + + + + + + + + true + + + + + true + + + + \ No newline at end of file diff --git a/src/test/resources/transactionalruntime/config/StrolchConfiguration.xml b/src/test/resources/transactionalruntime/config/StrolchConfiguration.xml index b030e7899..733a7bf4b 100644 --- a/src/test/resources/transactionalruntime/config/StrolchConfiguration.xml +++ b/src/test/resources/transactionalruntime/config/StrolchConfiguration.xml @@ -7,13 +7,23 @@ true + + PrivilegeHandler + li.strolch.runtime.privilege.PrivilegeHandler + li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler + + PrivilegeConfig.xml + + RealmHandler li.strolch.agent.api.RealmHandler li.strolch.agent.impl.DefaultRealmHandler + PrivilegeHandler PersistenceHandler TRANSACTIONAL + true