From aa11f8098a7cd221417a3dbc199a31fff07ed92a Mon Sep 17 00:00:00 2001 From: Robert von Burg Date: Sat, 4 Apr 2015 17:53:54 +0200 Subject: [PATCH] [New] Added elementSubType to Audit --- .../persistence/api/AbstractTransaction.java | 16 +++- .../persistence/api/StrolchTransaction.java | 19 ++++- .../DefaultStrolchPrivilegeHandler.java | 4 +- .../runtime/privilege/PrivilegeHandler.java | 3 + .../runtime/query/inmemory/AuditSelector.java | 15 +++- .../query/inmemory/AuditQueryTest.java | 6 +- .../java/li/strolch/model/ModelGenerator.java | 2 + .../java/li/strolch/model/StrolchElement.java | 2 +- .../src/main/java/li/strolch/model/Tags.java | 1 + .../java/li/strolch/model/audit/Audit.java | 81 +++--------------- .../model/audit/AuditFromDomReader.java | 4 + .../model/audit/AuditToDomVisitor.java | 1 + .../strolch/model/audit/ElementSelection.java | 18 +++- .../postgresql/PostgreSqlAuditDao.java | 43 +++++----- .../PostgreSqlAuditQueryVisitor.java | 7 +- .../strolch_db_schema_0.3.0_drop.sql | 8 ++ .../strolch_db_schema_0.3.0_initial.sql | 84 +++++++++++++++++++ .../strolch_db_schema_0.3.0_migration.sql | 12 +++ .../resources/strolch_db_version.properties | 2 +- .../postgresql/dao/test/AuditQueryTest.java | 14 +++- .../model/visitor/ToAuditQueryVisitor.java | 2 +- 21 files changed, 235 insertions(+), 109 deletions(-) create mode 100644 li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_drop.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_initial.sql create mode 100644 li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_migration.sql diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java index 986d6e00f..e77aa15a3 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/AbstractTransaction.java @@ -59,6 +59,7 @@ import li.strolch.model.query.ResourceQuery; import li.strolch.model.query.StrolchQuery; import li.strolch.model.timedstate.StrolchTimedState; import li.strolch.model.timevalue.IValue; +import li.strolch.model.visitor.ElementTypeVisitor; import li.strolch.model.visitor.NoStrategyOrderVisitor; import li.strolch.model.visitor.NoStrategyResourceVisitor; import li.strolch.persistence.inmemory.InMemoryTransaction; @@ -811,19 +812,27 @@ public abstract class AbstractTransaction implements StrolchTransaction { private void auditsFor(List audits, AccessType accessType, String elementType, Set elements) { for (StrolchRootElement element : elements) { - audits.add(auditFrom(accessType, elementType, element.getId())); + audits.add(auditFrom(accessType, element)); } } private void auditsForAudits(List audits, AccessType accessType, String elementType, Set elements) { for (Audit element : elements) { - audits.add(auditFrom(accessType, elementType, element.getId().toString())); + audits.add(auditFrom(accessType, elementType, StringHelper.DASH, element.getId().toString())); } } @Override - public Audit auditFrom(AccessType accessType, String elementType, String id) { + public Audit auditFrom(AccessType accessType, StrolchRootElement element) { + String type = element.accept(new ElementTypeVisitor()); + String subType = element.getType(); + String id = element.getId(); + return auditFrom(accessType, type, subType, id); + } + + @Override + public Audit auditFrom(AccessType accessType, String elementType, String elementSubType, String id) { Audit audit = new Audit(); audit.setId(StrolchAgent.getUniqueIdLong()); @@ -833,6 +842,7 @@ public abstract class AbstractTransaction implements StrolchTransaction { audit.setDate(new Date()); audit.setElementType(elementType); + audit.setElementSubType(elementSubType); audit.setElementAccessed(id); // audit.setNewVersion(); diff --git a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java index a83555593..2e1d51828 100644 --- a/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java +++ b/li.strolch.agent/src/main/java/li/strolch/persistence/api/StrolchTransaction.java @@ -329,13 +329,28 @@ public interface StrolchTransaction extends AutoCloseable { * @param accessType * the type of access * @param elementType - * the element type, i.e. s {@link Tags#RESOURCE}, {@link Tags#ORDER} + * the element type, i.e. {@link Tags#RESOURCE}, {@link Tags#ORDER} + * @param elementType + * the element sub type, e.g. {@link Resource#getType()} * @param id * the id of the element audited * * @return the new audit */ - public Audit auditFrom(AccessType accessType, String elementType, String id); + public Audit auditFrom(AccessType accessType, String elementType, String elementSubType, String id); + + /** + * Helper method to create an {@link Audit} with the given arguments. The audit can then be saved by calling + * {@link AuditTrail#add(StrolchTransaction, Audit)} + * + * @param accessType + * the type of access + * @param element + * the element from which to to create the audit + * + * @return the new audit + */ + public Audit auditFrom(AccessType accessType, StrolchRootElement element); /** *

diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java index 3c8cc3438..94a22c0e8 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/DefaultStrolchPrivilegeHandler.java @@ -119,7 +119,7 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements try (StrolchTransaction tx = realm.openTx(certificate, getClass())) { tx.setSuppressDoNothingLogging(true); tx.setSuppressAudits(true); - Audit audit = tx.auditFrom(AccessType.CREATE, Certificate.class.getSimpleName(), username); + Audit audit = tx.auditFrom(AccessType.CREATE, PRIVILEGE, CERTIFICATE, username); tx.getAuditTrail().add(tx, audit); } return certificate; @@ -148,7 +148,7 @@ public class DefaultStrolchPrivilegeHandler extends StrolchComponent implements try (StrolchTransaction tx = realm.openTx(certificate, getClass())) { tx.setSuppressDoNothingLogging(true); tx.setSuppressAudits(true); - Audit audit = tx.auditFrom(AccessType.DELETE, Certificate.class.getSimpleName(), certificate.getUsername()); + Audit audit = tx.auditFrom(AccessType.DELETE, PRIVILEGE, CERTIFICATE, certificate.getUsername()); tx.getAuditTrail().add(tx, audit); } return invalidateSession; diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java index 0175dc083..a47b50d6a 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/privilege/PrivilegeHandler.java @@ -25,6 +25,9 @@ import ch.eitchnet.privilege.model.PrivilegeContext; */ public interface PrivilegeHandler { + public static final String PRIVILEGE = "Privilege"; //$NON-NLS-1$ + public static final String CERTIFICATE = "Certificate"; //$NON-NLS-1$ + /** * @param username * @param password diff --git a/li.strolch.agent/src/main/java/li/strolch/runtime/query/inmemory/AuditSelector.java b/li.strolch.agent/src/main/java/li/strolch/runtime/query/inmemory/AuditSelector.java index e4e6debaa..37fcb1c0e 100644 --- a/li.strolch.agent/src/main/java/li/strolch/runtime/query/inmemory/AuditSelector.java +++ b/li.strolch.agent/src/main/java/li/strolch/runtime/query/inmemory/AuditSelector.java @@ -46,15 +46,28 @@ public abstract class AuditSelector { } private static class ElementSelector extends AuditSelector { + private StringSelection elementSubTypeSelection; private StringSelection elementAccessedSelection; public ElementSelector(ElementSelection selection) { + this.elementSubTypeSelection = selection.getElementSubTypeSelection(); this.elementAccessedSelection = selection.getElementAccessedSelection(); } @Override public boolean select(Audit audit) { - return this.elementAccessedSelection.matches(audit.getElementAccessed()); + + if (this.elementSubTypeSelection != null) { + if (!this.elementSubTypeSelection.matches(audit.getElementSubType())) + return false; + } + + if (this.elementAccessedSelection != null) { + if (!this.elementAccessedSelection.matches(audit.getElementAccessed())) + return false; + } + + return true; } } diff --git a/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/AuditQueryTest.java b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/AuditQueryTest.java index 9d78bf2e8..3990aa583 100644 --- a/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/AuditQueryTest.java +++ b/li.strolch.agent/src/test/java/li/strolch/runtime/query/inmemory/AuditQueryTest.java @@ -109,15 +109,15 @@ public class AuditQueryTest { performQuery(query, Arrays.asList(1L)); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); - query.element().elementsAccessed(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "crea"); + query.element().elementAccessed(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "crea"); performQuery(query, Arrays.asList(0L, 4L)); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); - query.element().elementsAccessed(StringMatchMode.CONTAINS_CASE_SENSITIVE, "crea"); + query.element().elementAccessed(StringMatchMode.CONTAINS_CASE_SENSITIVE, "crea"); performQuery(query, Arrays. asList()); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); - query.element().elementsAccessed(StringMatchMode.EQUALS_CASE_INSENSITIVE, "create"); + query.element().elementAccessed(StringMatchMode.EQUALS_CASE_INSENSITIVE, "create"); performQuery(query, Arrays.asList(0L, 4L)); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); diff --git a/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java index 0af4d167c..e9e8dbb5f 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java +++ b/li.strolch.model/src/main/java/li/strolch/model/ModelGenerator.java @@ -394,6 +394,7 @@ public class ModelGenerator { String[] firstnames = new String[] { "Bob", "Alice", "Jenny" }; String[] lastnames = new String[] { "Richards", "Kennedy", "Davids" }; String[] types = new String[] { Tags.RESOURCE, Tags.ORDER, Tags.AUDIT }; + String[] subTypes = new String[] { "Ball", "Something", "Foo", "Bar" }; String[] actions = new String[] { "AddResourceService", "UpdateResourceService", "RemoveResourceService", "AddOrderService", "UpdateOrderService", "RemoveOrderService" }; @@ -404,6 +405,7 @@ public class ModelGenerator { audit.setLastname(randomValue(rand, lastnames)); audit.setDate(new Date(rand.nextInt(5000))); audit.setElementType(randomValue(rand, types)); + audit.setElementSubType(randomValue(rand, subTypes)); audit.setElementAccessed(StringHelper.getUniqueId()); audit.setNewVersion(new Date(rand.nextInt(5000))); audit.setAction(randomValue(rand, actions)); diff --git a/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java b/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java index 86a38d089..7328bc4a8 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java +++ b/li.strolch.model/src/main/java/li/strolch/model/StrolchElement.java @@ -97,7 +97,7 @@ public interface StrolchElement extends Serializable, Comparable public StrolchElement getParent(); public StrolchRootElement getRootElement(); - + public boolean isRootElement(); /** diff --git a/li.strolch.model/src/main/java/li/strolch/model/Tags.java b/li.strolch.model/src/main/java/li/strolch/model/Tags.java index b4fb9d22c..2152d0989 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/Tags.java +++ b/li.strolch.model/src/main/java/li/strolch/model/Tags.java @@ -51,6 +51,7 @@ public class Tags { public static final String DATE = "Date"; public static final String ELEMENT_TYPE = "ElementType"; + public static final String ELEMENT_SUB_TYPE = "ElementSubType"; public static final String ELEMENT_ACCESSED = "ElementAccessed"; public static final String NEW_VERSION = "NewVersion"; diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java b/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java index 5e7cb08d2..91d4e9bae 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/Audit.java @@ -58,6 +58,9 @@ public class Audit implements Comparable, Serializable { @XmlAttribute(name = "elementType") private String elementType; + @XmlAttribute(name = "elementSubType") + private String elementSubType; + @XmlAttribute(name = "elementAccessed") private String elementAccessed; @@ -71,152 +74,90 @@ public class Audit implements Comparable, Serializable { @XmlAttribute(name = "accessType") private AccessType accessType; - /** - * @return the id - */ public Long getId() { return this.id; } - /** - * @param id - * the id to set - */ public void setId(long id) { this.id = id; } - /** - * @return the username - */ public String getUsername() { return this.username; } - /** - * @param username - * the username to set - */ public void setUsername(String username) { this.username = username; } - /** - * @return the firstname - */ public String getFirstname() { return this.firstname; } - /** - * @param firstname - * the firstname to set - */ public void setFirstname(String firstname) { this.firstname = firstname; } - /** - * @return the lastname - */ public String getLastname() { return this.lastname; } - /** - * @param lastname - * the lastname to set - */ public void setLastname(String lastname) { this.lastname = lastname; } - /** - * @return the date - */ public Date getDate() { return this.date; } - /** - * @param date - * the date to set - */ public void setDate(Date date) { this.date = date; } - /** - * @return the elementType - */ public String getElementType() { return this.elementType; } - /** - * @param elementType - * the elementType to set - */ public void setElementType(String elementType) { this.elementType = elementType; } - /** - * @return the elementAccessed - */ + public String getElementSubType() { + return elementSubType; + } + + public void setElementSubType(String elementSubType) { + this.elementSubType = elementSubType; + } + public String getElementAccessed() { return this.elementAccessed; } - /** - * @param elementAccessed - * the elementAccessed to set - */ public void setElementAccessed(String elementAccessed) { this.elementAccessed = elementAccessed; } - /** - * @return the newVersion - */ public Date getNewVersion() { return this.newVersion; } - /** - * @param newVersion - * the newVersion to set - */ public void setNewVersion(Date newVersion) { this.newVersion = newVersion; } - /** - * @return the action - */ public String getAction() { return this.action; } - /** - * @param action - * the action to set - */ public void setAction(String action) { this.action = action; } - /** - * @return the accessType - */ public AccessType getAccessType() { return this.accessType; } - /** - * @param accessType - * the accessType to set - */ public void setAccessType(AccessType accessType) { this.accessType = accessType; } diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java index 123d5903c..44e886307 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditFromDomReader.java @@ -65,6 +65,9 @@ public class AuditFromDomReader { case Tags.Audit.ELEMENT_TYPE: audit.setElementType(txtContent); break; + case Tags.Audit.ELEMENT_SUB_TYPE: + audit.setElementSubType(txtContent); + break; case Tags.Audit.ELEMENT_ACCESSED: audit.setElementAccessed(txtContent); break; @@ -90,6 +93,7 @@ public class AuditFromDomReader { DBC.INTERIM.assertNotEmpty("Lastname" + msg, audit.getLastname()); DBC.INTERIM.assertNotNull("Date" + msg, audit.getDate()); DBC.INTERIM.assertNotEmpty("ElementType" + msg, audit.getElementType()); + DBC.INTERIM.assertNotEmpty("ElementSubType" + msg, audit.getElementSubType()); DBC.INTERIM.assertNotEmpty("ElementAccessed" + msg, audit.getElementAccessed()); //DBC.INTERIM.assertNotNull("NewVersion" + msg, audit.getNewVersion()); DBC.INTERIM.assertNotEmpty("Action" + msg, audit.getAction()); diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java index f187cff84..91f43753e 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/AuditToDomVisitor.java @@ -45,6 +45,7 @@ public class AuditToDomVisitor implements AuditVisitor { auditE.appendChild(elem(doc, Tags.Audit.DATE, ISO8601FormatFactory.getInstance().formatDate(audit.getDate()))); auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_TYPE, audit.getElementType())); + auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_SUB_TYPE, audit.getElementSubType())); auditE.appendChild(elem(doc, Tags.Audit.ELEMENT_ACCESSED, audit.getElementAccessed())); if (audit.getNewVersion() != null) diff --git a/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java b/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java index 74b78975b..ad2e3517e 100644 --- a/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java +++ b/li.strolch.model/src/main/java/li/strolch/model/audit/ElementSelection.java @@ -23,13 +23,14 @@ import ch.eitchnet.utils.StringMatchMode; */ public class ElementSelection extends AuditSelection { + private StringSelection elementSubTypeSelection; private StringSelection elementAccessedSelection; public ElementSelection(AuditQuery query) { super(query); } - public ElementSelection elementsAccessed(StringMatchMode matchMode, String... elementsAccessed) { + public ElementSelection elementAccessed(StringMatchMode matchMode, String... elementsAccessed) { this.elementAccessedSelection = new StringSelection(matchMode, elementsAccessed); return this; } @@ -38,10 +39,23 @@ public class ElementSelection extends AuditSelection { return this.elementAccessedSelection; } - public boolean isElementsAccessedWildcard() { + public boolean isElementAccessedWildcard() { return this.elementAccessedSelection == null || this.elementAccessedSelection.isWildCard(); } + public ElementSelection elementSubTypes(StringMatchMode matchMode, String... elementSubTypes) { + this.elementSubTypeSelection = new StringSelection(matchMode, elementSubTypes); + return this; + } + + public StringSelection getElementSubTypeSelection() { + return this.elementSubTypeSelection; + } + + public boolean isElementSubTypesWildcard() { + return this.elementSubTypeSelection == null || this.elementSubTypeSelection.isWildCard(); + } + @Override public void accept(AuditQueryVisitor visitor) { visitor.visit(this); diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java index 7db25ac21..fc0251cd6 100644 --- a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditDao.java @@ -45,14 +45,15 @@ public class PostgreSqlAuditDao implements AuditDao { public static final String ACCESS_TYPE_TYPE = "::access_type"; public static final String ACTION = "action"; public static final String NEW_VERSION = "new_version"; - public static final String ELEMENT_ACCESSED = "element_accessed"; public static final String ELEMENT_TYPE = "element_type"; + public static final String ELEMENT_SUB_TYPE = "element_sub_type"; + public static final String ELEMENT_ACCESSED = "element_accessed"; public static final String DATE = "date"; public static final String LASTNAME = "lastname"; public static final String FIRSTNAME = "firstname"; public static final String USERNAME = "username"; public static final String FIELDS = StringHelper.commaSeparated(ID, USERNAME, FIRSTNAME, LASTNAME, DATE, - ELEMENT_TYPE, ELEMENT_ACCESSED, NEW_VERSION, ACTION, ACCESS_TYPE); + ELEMENT_TYPE, ELEMENT_SUB_TYPE, ELEMENT_ACCESSED, NEW_VERSION, ACTION, ACCESS_TYPE); public static final String TABLE_NAME = "audits"; private PostgreSqlStrolchTransaction tx; @@ -192,7 +193,7 @@ public class PostgreSqlAuditDao implements AuditDao { @Override public void save(Audit audit) { - String sql = "insert into " + TABLE_NAME + " (" + FIELDS + ") values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?::access_type)"; //$NON-NLS-1$ + String sql = "insert into " + TABLE_NAME + " (" + FIELDS + ") values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?::access_type)"; //$NON-NLS-1$ try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) { setAuditFields(audit, preparedStatement); @@ -219,12 +220,13 @@ public class PostgreSqlAuditDao implements AuditDao { @Override public void update(Audit audit) { String sql = "update " + TABLE_NAME + " set " + ID + " = ?, " + USERNAME + " = ?, " + FIRSTNAME + " = ?, " - + LASTNAME + " = ?, " + DATE + " = ?, " + ELEMENT_TYPE + " = ?, " + ELEMENT_ACCESSED + " = ?, " - + NEW_VERSION + " = ?, " + ACTION + " = ?, " + ACCESS_TYPE + " = ?::access_type where " + ID + " = ?"; //$NON-NLS-1$ + + LASTNAME + " = ?, " + DATE + " = ?, " + ELEMENT_TYPE + " = ?, " + ELEMENT_SUB_TYPE + " = ?, " + + ELEMENT_ACCESSED + " = ?, " + NEW_VERSION + " = ?, " + ACTION + " = ?, " + ACCESS_TYPE + + " = ?::access_type where " + ID + " = ?"; try (PreparedStatement preparedStatement = this.tx.getConnection().prepareStatement(sql)) { setAuditFields(audit, preparedStatement); - preparedStatement.setLong(11, audit.getId()); + preparedStatement.setLong(12, audit.getId()); int count = preparedStatement.executeUpdate(); if (count != 1) { @@ -306,10 +308,11 @@ public class PostgreSqlAuditDao implements AuditDao { // 4 lastname = ?, // 5 date = ?, // 6 element_type = ?, - // 7 element_accessed = ?, - // 8 new_version = ?, - // 9 action = ?, - // 10 access_type = ?::access_type + // 7 element_sub_type = ?, + // 8 element_accessed = ?, + // 9 new_version = ?, + // 10 action = ?, + // 11 access_type = ?::access_type ps.setLong(1, audit.getId()); ps.setString(2, audit.getUsername()); @@ -317,15 +320,16 @@ public class PostgreSqlAuditDao implements AuditDao { ps.setString(4, audit.getLastname()); ps.setTimestamp(5, new Timestamp(audit.getDate().getTime()), Calendar.getInstance()); ps.setString(6, audit.getElementType()); - ps.setString(7, audit.getElementAccessed()); + ps.setString(7, audit.getElementSubType()); + ps.setString(8, audit.getElementAccessed()); if (audit.getNewVersion() == null) - ps.setDate(8, null); + ps.setDate(9, null); else - ps.setTimestamp(8, new Timestamp(audit.getNewVersion().getTime()), Calendar.getInstance()); + ps.setTimestamp(9, new Timestamp(audit.getNewVersion().getTime()), Calendar.getInstance()); - ps.setString(9, audit.getAction()); - ps.setString(10, audit.getAccessType().name()); + ps.setString(10, audit.getAction()); + ps.setString(11, audit.getAccessType().name()); } private Audit auditFrom(ResultSet resultSet) throws SQLException { @@ -337,10 +341,11 @@ public class PostgreSqlAuditDao implements AuditDao { audit.setLastname(resultSet.getString(4)); audit.setDate(resultSet.getTimestamp(5)); audit.setElementType(resultSet.getString(6)); - audit.setElementAccessed(resultSet.getString(7)); - audit.setNewVersion(resultSet.getTimestamp(8)); - audit.setAction(resultSet.getString(9)); - audit.setAccessType(AccessType.valueOf(resultSet.getString(10))); + audit.setElementSubType(resultSet.getString(7)); + audit.setElementAccessed(resultSet.getString(8)); + audit.setNewVersion(resultSet.getTimestamp(9)); + audit.setAction(resultSet.getString(10)); + audit.setAccessType(AccessType.valueOf(resultSet.getString(11))); return audit; } } diff --git a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditQueryVisitor.java b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditQueryVisitor.java index 379c40407..e3e90f071 100644 --- a/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditQueryVisitor.java +++ b/li.strolch.persistence.postgresql/src/main/java/li/strolch/persistence/postgresql/PostgreSqlAuditQueryVisitor.java @@ -80,7 +80,12 @@ public class PostgreSqlAuditQueryVisitor implements AuditQueryVisitor { @Override public void visit(ElementSelection selection) { - if (!selection.isElementsAccessedWildcard()) { + if (!selection.isElementSubTypesWildcard()) { + StringSelection sel = selection.getElementSubTypeSelection(); + toSql(PostgreSqlAuditDao.ELEMENT_SUB_TYPE, sel.getMatchMode(), sel.getValues()); + } + + if (!selection.isElementAccessedWildcard()) { StringSelection sel = selection.getElementAccessedSelection(); toSql(PostgreSqlAuditDao.ELEMENT_ACCESSED, sel.getMatchMode(), sel.getValues()); } diff --git a/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_drop.sql b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_drop.sql new file mode 100644 index 000000000..467a2c3ed --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.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/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_initial.sql b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_initial.sql new file mode 100644 index 000000000..cffd6f247 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_initial.sql @@ -0,0 +1,84 @@ + +-- DB_VERSION +CREATE TABLE IF NOT EXISTS db_version ( + id SERIAL PRIMARY KEY, + app varchar(255), + 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_sub_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, app, description, created) +values( + '0.1.0', + 'strolch', + 'Initial schema version', + CURRENT_TIMESTAMP +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.2.0', + 'strolch', + 'Added new table for audits', + CURRENT_TIMESTAMP +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.2.1', + 'strolch', + 'Added new column app to table table version', + CURRENT_TIMESTAMP +); + +INSERT INTO db_version + (version, app, description, created) +values( + '0.3.0', + 'strolch', + 'Added new column element_sub_type to table audits', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_migration.sql b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_migration.sql new file mode 100644 index 000000000..5ac3e2a60 --- /dev/null +++ b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_schema_0.3.0_migration.sql @@ -0,0 +1,12 @@ + +-- DB_VERSION +ALTER TABLE audits ADD COLUMN element_sub_type character varying(255) NOT NULL DEFAULT '-'; + +INSERT INTO db_version + (version, app, description, created) +values( + '0.3.0', + 'strolch', + 'Added new column element_sub_type to table audits', + CURRENT_TIMESTAMP +); diff --git a/li.strolch.persistence.postgresql/src/main/resources/strolch_db_version.properties b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_version.properties index d4c3d1a62..f2218709d 100644 --- a/li.strolch.persistence.postgresql/src/main/resources/strolch_db_version.properties +++ b/li.strolch.persistence.postgresql/src/main/resources/strolch_db_version.properties @@ -1,2 +1,2 @@ # Property file defining what the currently expected version is supposed to be -db_version=0.2.1 \ No newline at end of file +db_version=0.3.0 \ No newline at end of file diff --git a/li.strolch.persistence.postgresql/src/test/java/li/strolch/persistence/postgresql/dao/test/AuditQueryTest.java b/li.strolch.persistence.postgresql/src/test/java/li/strolch/persistence/postgresql/dao/test/AuditQueryTest.java index 0718a2f48..bfb72cc82 100644 --- a/li.strolch.persistence.postgresql/src/test/java/li/strolch/persistence/postgresql/dao/test/AuditQueryTest.java +++ b/li.strolch.persistence.postgresql/src/test/java/li/strolch/persistence/postgresql/dao/test/AuditQueryTest.java @@ -209,15 +209,15 @@ public class AuditQueryTest { performQuery(query, Arrays.asList("1")); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); - query.element().elementsAccessed(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "crea"); + query.element().elementAccessed(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "crea"); performQuery(query, Arrays.asList("0", "4")); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); - query.element().elementsAccessed(StringMatchMode.CONTAINS_CASE_SENSITIVE, "crea"); + query.element().elementAccessed(StringMatchMode.CONTAINS_CASE_SENSITIVE, "crea"); performQuery(query, Arrays. asList()); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); - query.element().elementsAccessed(StringMatchMode.EQUALS_CASE_INSENSITIVE, "create"); + query.element().elementAccessed(StringMatchMode.EQUALS_CASE_INSENSITIVE, "create"); performQuery(query, Arrays.asList("0", "4")); query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); @@ -243,6 +243,14 @@ public class AuditQueryTest { query.identity().firstnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "enn") .lastnames(StringMatchMode.CONTAINS_CASE_INSENSITIVE, "kennedy"); performQuery(query, Arrays.asList("0", "1", "2", "3", "4")); + + query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); + query.element().elementSubTypes(StringMatchMode.EQUALS_CASE_SENSITIVE, "Foo"); + performQuery(query, Arrays.asList("0", "1", "2", "3", "4")); + + query = new AuditQuery(Tags.AUDIT, new DateRange().from(past, true).to(future, true)); + query.element().elementSubTypes(StringMatchMode.EQUALS_CASE_SENSITIVE, "Bar"); + performQuery(query, Arrays.asList()); } private void performQuery(AuditQuery query, List expected) throws SQLException { diff --git a/li.strolch.rest/src/main/java/li/strolch/rest/model/visitor/ToAuditQueryVisitor.java b/li.strolch.rest/src/main/java/li/strolch/rest/model/visitor/ToAuditQueryVisitor.java index 6ff194110..324e306e9 100644 --- a/li.strolch.rest/src/main/java/li/strolch/rest/model/visitor/ToAuditQueryVisitor.java +++ b/li.strolch.rest/src/main/java/li/strolch/rest/model/visitor/ToAuditQueryVisitor.java @@ -35,7 +35,7 @@ public class ToAuditQueryVisitor { // element Id String elementId = query.getElementId(); if (StringHelper.isNotEmpty(elementId)) { - auditQuery.element().elementsAccessed(StringMatchMode.ci(), elementId); + auditQuery.element().elementAccessed(StringMatchMode.ci(), elementId); } // action