@Test public void retrieveSingleRevisionTest() { VersionedEntity entity = new VersionedEntity(); entity.setTest("test1"); store.save(entity); flushCache(); List<Revision> revisions = historicStore.getRevisions(entity.getId(), new Params()); assertThat(revisions, hasSize(1)); Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(1)); RevisionItem item = revision.getItems().iterator().next(); assertThat(item.getEntityId(), is(entity.getId())); assertThat(item.getOperation(), is(RevisionType.ADD)); VersionedEntity result = historicStore.findAtRevision(entity.getId(), revision.getId()); assertThat(result.getId(), is(entity.getId())); assertThat(result.getTest(), is(entity.getTest())); }
public static RevisionTypeDto convert(RevisionType source) { if(source == null) { return null; } switch (source) { case ADD: return RevisionTypeDto.ADD; case MOD: return RevisionTypeDto.MOD; case DEL: return RevisionTypeDto.DEL; default: throw new IllegalArgumentException("source"); } }
private void assertProperObjectsReturned(final Object[] revisionObject, final ProductDetailsEntity pde) { Assert.assertEquals(3, revisionObject.length); Assert.assertTrue(ProductDetailsEntity.class.isInstance(revisionObject[0])); Assert.assertTrue(DefaultRevisionEntity.class.isInstance(revisionObject[1])); Assert.assertTrue(RevisionType.class.isInstance(revisionObject[2])); final ProductDetailsEntity pd = (ProductDetailsEntity) revisionObject[0]; final RevisionType rt = (RevisionType) revisionObject[2]; Assert.assertEquals(RevisionType.ADD, rt); Assert.assertEquals(pde.getStoreName(), pd.getStoreName()); Assert.assertEquals(pde.getExpirationDate(), pd.getExpirationDate()); Assert.assertEquals(pde.getActive(), pd.getActive()); Assert.assertEquals(pde.getWasChecked(), pd.getWasChecked()); }
@Override public void entityChanged(Class entityClass, String entityName, Serializable entityId, RevisionType revisionType, Object revisionEntity) { Revision revision = (Revision) revisionEntity; if (revision.getItems() == null) { revision.setItems(new HashSet<>()); } revision.getItems().add(new RevisionItem((String)entityId, revisionType)); }
@Test public void multipleInstancesTest() { VersionedEntity entity1 = new VersionedEntity(); entity1.setTest("test1"); VersionedEntity entity2 = new VersionedEntity(); entity2.setTest("test2"); store.save(asSet(entity1, entity2)); flushCache(); List<Revision> revisions = historicStore.getRevisions(entity1.getId(), new Params()); assertThat(revisions, hasSize(1)); Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(2)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity1.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity2.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); VersionedEntity result = historicStore.findAtRevision(entity1.getId(), revision.getId()); assertThat(result.getId(), is(entity1.getId())); assertThat(result.getTest(), is(entity1.getTest())); result = historicStore.findAtRevision(entity2.getId(), revision.getId()); assertThat(result.getId(), is(entity2.getId())); assertThat(result.getTest(), is(entity2.getTest())); }
@Override public void entityChanged(@SuppressWarnings("rawtypes") Class entityClass, String entityName, Serializable entityId, RevisionType revisionType, Object revisionEntity) { String type = entityClass.getName(); Byte rt = revisionType.getRepresentation(); ((RevisionInfoEntity) revisionEntity).addModifiedEntityType(type, rt, (RevisionInfoEntity) revisionEntity); }
public void printRevisions(List<Object[]> revisions) { for (Object[] revision : revisions) { final Project project = (Project) revision[0]; final DefaultRevisionEntity revisionEntity = (DefaultRevisionEntity) revision[1]; final RevisionType revisionType = (RevisionType) revision[2]; System.out.println(); System.out.println(project.toString()); System.out.println(revisionEntity.toString()); System.out.println("REVISION TYPE: " + revisionType.name()); System.out.println(); } }
@Test public void retrieveMultipleRevisionTest() { VersionedEntity entity = new VersionedEntity(); entity.setTest("test1"); store.save(entity); flushCache(); entity.setTest("test2"); store.save(entity); flushCache(); Params params = new Params(); params.setOrder(Order.ASC); List<Revision> revisions = historicStore.getRevisions(entity.getId(), params); assertThat(revisions, hasSize(2)); Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); RevisionItem item = revision.getItems().iterator().next(); assertThat(item.getEntityId(), is(entity.getId())); assertThat(item.getOperation(), is(RevisionType.ADD)); VersionedEntity result = historicStore.findAtRevision(entity.getId(), revision.getId()); assertThat(result.getId(), is(entity.getId())); assertThat(result.getTest(), is("test1")); // second revision revision = revisions.get(1); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); item = revision.getItems().iterator().next(); assertThat(item.getEntityId(), is(entity.getId())); assertThat(item.getOperation(), is(RevisionType.MOD)); result = historicStore.findAtRevision(entity.getId(), revision.getId()); assertThat(result.getId(), is(entity.getId())); assertThat(result.getTest(), is("test2")); }
@Test public void deleteTest() { VersionedEntity entity = new VersionedEntity(); entity.setTest("test1"); store.save(entity); flushCache(); store.delete(entity); flushCache(); Params params = new Params(); params.setOrder(Order.ASC); List<Revision> revisions = historicStore.getRevisions(entity.getId(), params); assertThat(revisions, hasSize(2)); Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); RevisionItem item = revision.getItems().iterator().next(); assertThat(item.getEntityId(), is(entity.getId())); assertThat(item.getOperation(), is(RevisionType.ADD)); VersionedEntity result = historicStore.findAtRevision(entity.getId(), revision.getId()); assertThat(result.getId(), is(entity.getId())); assertThat(result.getTest(), is("test1")); // second revision revision = revisions.get(1); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); item = revision.getItems().iterator().next(); assertThat(item.getEntityId(), is(entity.getId())); assertThat(item.getOperation(), is(RevisionType.DEL)); result = historicStore.findAtRevision(entity.getId(), revision.getId()); assertThat(result, is(nullValue())); }
@Test public void multipleInstancesSeparateTest() { VersionedEntity entity1 = new VersionedEntity(); entity1.setTest("test1"); store.save(entity1); flushCache(); VersionedEntity entity2 = new VersionedEntity(); entity2.setTest("test2"); store.save(entity2); flushCache(); List<Revision> revisions = historicStore.getRevisions(entity1.getId(), new Params()); assertThat(revisions, hasSize(1)); Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(1)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity1.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); VersionedEntity result = historicStore.findAtRevision(entity1.getId(), revision.getId()); assertThat(result.getId(), is(entity1.getId())); assertThat(result.getTest(), is(entity1.getTest())); result = historicStore.findAtRevision(entity2.getId(), revision.getId()); assertThat(result, is(nullValue())); revisions = historicStore.getRevisions(entity2.getId(), new Params()); assertThat(revisions, hasSize(1)); revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(1)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity2.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); result = historicStore.findAtRevision(entity1.getId(), revision.getId()); assertThat(result.getId(), is(entity1.getId())); assertThat(result.getTest(), is(entity1.getTest())); result = historicStore.findAtRevision(entity2.getId(), revision.getId()); assertThat(result.getId(), is(entity2.getId())); assertThat(result.getTest(), is(entity2.getTest())); }
@Test public void multipleInstancesSeparateDeleteTest() { VersionedEntity entity1 = new VersionedEntity(); entity1.setTest("test1"); store.save(entity1); flushCache(); VersionedEntity entity2 = new VersionedEntity(); entity2.setTest("test2"); store.save(entity2); store.delete(entity1); flushCache(); Params params = new Params(); params.setOrder(Order.ASC); // first object List<Revision> revisions = historicStore.getRevisions(entity1.getId(), params); assertThat(revisions, hasSize(2)); // first revision ADD Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(1)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity1.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); VersionedEntity result = historicStore.findAtRevision(entity1.getId(), revision.getId()); assertThat(result.getId(), is(entity1.getId())); assertThat(result.getTest(), is(entity1.getTest())); // second revision DEL revision = revisions.get(1); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(2)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity1.getId())), hasProperty("operation", is(RevisionType.DEL)) ))); result = historicStore.findAtRevision(entity1.getId(), revision.getId()); assertThat(result, is(nullValue())); // second object revisions = historicStore.getRevisions(entity2.getId(), params); assertThat(revisions, hasSize(1)); revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(2)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity1.getId())), hasProperty("operation", is(RevisionType.DEL)) ))); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity2.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); result = historicStore.findAtRevision(entity1.getId(), revision.getId()); assertThat(result, is(nullValue())); result = historicStore.findAtRevision(entity2.getId(), revision.getId()); assertThat(result.getId(), is(entity2.getId())); assertThat(result.getTest(), is(entity2.getTest())); }
@Test public void singleDepTest() { VersionedDepEntity depEntity = new VersionedDepEntity(); depEntity.setValue("value1"); VersionedEntity entity = new VersionedEntity(); entity.setTest("test1"); entity.setDeps(asSet(depEntity)); store.save(entity); flushCache(); List<Revision> revisions = historicStore.getRevisions(entity.getId(), new Params()); assertThat(revisions, hasSize(1)); Revision revision = revisions.get(0); assertThat(revision.getId(), is(notNullValue())); assertThat(revision.getCreated(), is(notNullValue())); assertThat(revision.getItems(), hasSize(3)); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(depEntity.getId())), hasProperty("operation", is(RevisionType.ADD)) ))); // @JoinColumn creates own item for the parent entity assertThat(revision.getItems(), hasItem(allOf( hasProperty("entityId", is(entity.getId())), hasProperty("operation", is(RevisionType.MOD)) ))); VersionedEntity result = historicStore.findAtRevision(entity.getId(), revision.getId()); assertThat(result.getId(), is(entity.getId())); assertThat(result.getTest(), is(entity.getTest())); assertThat(result.getDeps(), hasItem(allOf( hasProperty("id", is(depEntity.getId())), hasProperty("value", is(depEntity.getValue())) ))); }
public AuditQueryResult(T entity, CustomRevisionEntity revision, RevisionType type) { this.entity = entity; this.revision = revision; this.type = type; }
public RevisionType getType() { return type; }
public CustomerHistory(Customer customer, Number revision, RevisionType revisionType) { this.customer = customer; this.revision = revision; this.revisionType = revisionType; }
public RevisionType getRevisionType() { return revisionType; }
/** * Get all products that need to be shown to the checker for approval. * * @return a list of Object[]. Each element will be an Object[3] array with * the following items: Object[0] - the {@link ProductEntity} at a * revision ( greater or equal than the one given as parameter) * Object[1] a {@link DefaultRevisionEntity} Object[2] a * {@link RevisionType} object containing information about the * revision */ @Transactional public List<Object[]> getAllProductsWaitingForApproval() { /** * Get all distinct {@link ProductEntity} objects where the wasChecked * property is false order by modified descending */ final AuditQuery query = this.getAuditReader() .createQuery() .forRevisionsOfEntity(ProductEntity.class, false, true) .addOrder(AuditEntity.property("modified") .desc()) .add(AuditEntity.revisionNumber() .maximize() .computeAggregationInInstanceContext()) .add(AuditEntity.property("wasChecked") .eq(Boolean.FALSE)) .add(AuditEntity.revisionType() .ne(RevisionType.DEL)); final List<Object[]> resultList = query.getResultList(); final List<Object[]> result = new ArrayList<>(); /** * for each "changed" object found in the db we need to check if there * is a newer revision of it in which the {@link ProductEntity} was * approved (wasChecked = true) because we do not need to retrieve * already checked objects to the checker. */ for (final Object[] change : resultList) { final ProductEntity pe = (ProductEntity) change[0]; final AuditQuery queryForWasCheckedTrue = this.getAuditReader() .createQuery() .forRevisionsOfEntity(ProductEntity.class, false, true) .addOrder(AuditEntity.property("modified") .desc()) .add(AuditEntity.id() .eq(pe.getId())) .add(AuditEntity.property("wasChecked") .eq(Boolean.TRUE)); if (pe.getModified() != null) { queryForWasCheckedTrue.add(AuditEntity.property("modified") .gt(pe.getModified())); } try { final Object[] trueWasChecked = (Object[]) queryForWasCheckedTrue.getSingleResult(); } catch (final NoResultException ex) { // there is no newer revision where the current product has // wasChecked property == true result.add(change); } } return result; }
/** * Retrieve the active products that need to be checked * * @return a list of {@link ProductDTO} objects */ @RequestMapping(value = "/checker", method = RequestMethod.GET, produces = "application/json") public List<ProductDTO> getAllActiveProductsForChecker() { /** Retrieve a list of products which need checker approval */ final List<Object[]> productChanges = this.productDao.getAllProductsWaitingForApproval(); final List<ProductDTO> results = new ArrayList<ProductDTO>(); for (final Object[] revision : productChanges) { final ProductDTO dto = new ProductDTO(); if (revision.length > 2 && ProductEntity.class.isInstance(revision[0])) { /** get the current value for the {@link ProductDetailsEntity} */ final ProductEntity currentValue = (ProductEntity) revision[0]; if (RevisionType.class.isInstance(revision[2])) { // get the {@link RevisionType} of the current change final RevisionType rt = (RevisionType) revision[2]; dto.setOperation(rt.name()); // get the {@link DefaultRevisionEntity} and retrieve the // revision date final DefaultRevisionEntity revEntity = (DefaultRevisionEntity) revision[1]; final Date revDate = revEntity.getRevisionDate(); dto.setRevision(revDate.getTime()); // get all product details associated with the current // product at the given revision dto.setProductDetails(this.getAllProductDetailsForProductAtRevision(currentValue.getId(), revDate.getTime())); // if the revision type was 'MOD', search for the previous // value of the product to construct the product dto if (rt == RevisionType.MOD) { final ProductEntity previousValue = this.productDao.getPreviousStateForProduct(currentValue.getId(), revEntity.getId()); dto.setInitial(previousValue); dto.setChanges(currentValue); } else { dto.setChanges(currentValue); } } results.add(dto); } } return results; }
/** * Retrieve all {@link ProductDetailsDTO} related to the given product at * the given revision * * @param prodId * the id of the {@link ProductEntity} * @param revisionDateAsLong * the timestamp of the revision as long * @return a list of {@link ProductDetailsDTO} */ private List<ProductDetailsDTO> getAllProductDetailsForProductAtRevision(final Long prodId, final Long revisionDateAsLong) { /** * retrieve the information about related product details from the * {@link ProductDetailsDAO} */ final List<Object[]> changes = this.productDetailsDao.getAllProductDetailsForProductAtRevision(prodId, new Date(revisionDateAsLong)); final List<ProductDetailsDTO> results = new ArrayList<ProductDetailsDTO>(); for (final Object[] revision : changes) { final ProductDetailsDTO dto = new ProductDetailsDTO(); if (revision.length > 2 && ProductDetailsEntity.class.isInstance(revision[0])) { /** get the current value for the {@link ProductDetailsEntity} */ final ProductDetailsEntity currentValue = (ProductDetailsEntity) revision[0]; if (currentValue != null) { currentValue.setFkProduct(prodId); } if (RevisionType.class.isInstance(revision[2])) { // get the {@link RevisionType} of the current change final RevisionType rt = (RevisionType) revision[2]; dto.setOperation(rt.name()); // if the revision type was 'MOD' get the previous value of // the entity to be able to construct the DTO if (rt == RevisionType.MOD) { final DefaultRevisionEntity dre = (DefaultRevisionEntity) revision[1]; final ProductDetailsEntity previousValue = this.productDetailsDao.getPreviousStateForProductDetails(currentValue.getId(), dre.getId()); if (previousValue != null) { previousValue.setFkProduct(prodId); } dto.setInitial(previousValue); dto.setChanges(currentValue); } else { dto.setChanges(currentValue); } } results.add(dto); } } return results; }
@Override public void entityChanged(Class entityClass, String entityName, Serializable entityId, RevisionType revisionType, Object revisionEntity) { // do nothing -- here purely to demonstrate capabilities }
/** * looking for initial revision of entity(for first database insert). * * @param auditReader * envers reader implementation * @param persistentClass * something that extends {@link AbstractPersistentEntity} * @param uniqueIdentifier * primary key of entity * @return revision number */ public static Number initialRevision(AuditReader auditReader, Class<? extends IBO> persistentClass, long uniqueIdentifier) { return (Number) auditReader.createQuery() .forRevisionsOfEntity(persistentClass, true, true) .add(AuditEntity.id().eq(uniqueIdentifier)) .add(AuditEntity.revisionType().eq(RevisionType.ADD)) .addProjection(AuditEntity.revisionNumber().min()) .getSingleResult(); }
/** * looking for latest modify revision of entity(for latest database * update/delete). * * @param auditReader * envers reader implementation * @param persistentClass * something that extends {@link AbstractPersistentEntity} * @param uniqueIdentifier * primary key of entity * @return revision number */ public static Number latestModifyRevision(AuditReader auditReader, Class<? extends IBO> persistentClass, long uniqueIdentifier) { return (Number) auditReader .createQuery() .forRevisionsOfEntity(persistentClass, true, true) .add(AuditEntity.id().eq(uniqueIdentifier)) .add(AuditEntity.revisionType() .in(new RevisionType[] { RevisionType.MOD, RevisionType.DEL })) .addProjection(AuditEntity.revisionNumber().max()) .getSingleResult(); }