@Test
  public void canLogMultipleLifecycleTransitionsInSameTx() throws ClientException {
    // generate events
    DocumentModel doc = repo.createDocumentModel("/", "a-file", "File");
    doc = repo.createDocument(doc);
    String initialLifeCycle = doc.getCurrentLifeCycleState();
    doc.followTransition(LifeCycleConstants.DELETE_TRANSITION);
    String deletedLifeCycle = doc.getCurrentLifeCycleState();
    doc.followTransition(LifeCycleConstants.UNDELETE_TRANSITION);
    String undeletedLifeCycle = doc.getCurrentLifeCycleState();
    TransactionHelper.commitOrRollbackTransaction();
    Framework.getLocalService(EventService.class).waitForAsyncCompletion();

    // test audit trail
    AuditReader reader = Framework.getLocalService(AuditReader.class);
    List<LogEntry> trail = reader.getLogEntriesFor(doc.getId());

    assertThat(trail, notNullValue());
    assertThat(trail.size(), is(3));

    boolean seenDocCreated = false;
    boolean seenDocDeleted = false;
    boolean seenDocUndeleted = false;

    for (LogEntry entry : trail) {
      String lifeCycle = entry.getDocLifeCycle();
      String id = entry.getEventId();
      if (DocumentEventTypes.DOCUMENT_CREATED.equals(id)) {
        if (initialLifeCycle.equals(lifeCycle)) {
          seenDocCreated = true;
        }
      } else if (LifeCycleConstants.TRANSITION_EVENT.equals(id)) {
        if (undeletedLifeCycle.equals(lifeCycle)) {
          seenDocUndeleted = true;
        } else if (deletedLifeCycle.equals(lifeCycle)) {
          seenDocDeleted = true;
        }
      }
    }

    assertThat(seenDocUndeleted, is(true));
    assertThat(seenDocDeleted, is(true));
    assertThat(seenDocCreated, is(true));
  }
Beispiel #2
0
  @SuppressWarnings({"unchecked", "boxing"})
  public static AdditionalDocumentAuditParams getAuditParamsForUUID(
      String uuid, CoreSession session) {

    AdditionalDocumentAuditParams result = null;
    IdRef ref = new IdRef(uuid);
    if (session.exists(ref)) {
      DocumentModel doc = session.getDocument(ref);

      String targetUUID = null;

      if (doc.isProxy() || doc.isVersion()) {
        SourceDocumentResolver resolver = new SourceDocumentResolver(session, doc);
        resolver.runUnrestricted();
        if (resolver.sourceDocument != null) {
          targetUUID = resolver.sourceDocument.getId();

          // now get from Audit Logs the creation date of
          // the version / proxy
          AuditReader reader = Framework.getLocalService(AuditReader.class);
          FilterMapEntry filter = new FilterMapEntry();
          filter.setColumnName("eventId");
          filter.setOperator("=");
          filter.setQueryParameterName("eventId");
          filter.setObject(DocumentEventTypes.DOCUMENT_CREATED);
          Map<String, FilterMapEntry> filters = new HashMap<String, FilterMapEntry>();
          filters.put("eventId", filter);
          List<LogEntry> entries = reader.getLogEntriesFor(uuid, filters, false);

          if (entries != null && entries.size() > 0) {
            result = new AdditionalDocumentAuditParams();
            result.maxDate = entries.get(0).getEventDate();
            result.targetUUID = targetUUID;
            result.eventId = entries.get(0).getId();
          } else {
            // we have no entry in audit log to get the maxDate
            // fallback to repository timestamp
            // this code is here only for compatibility
            // so that it works before version events were added to
            // the audit log
            if (doc.getPropertyValue("dc:modified") != null) {
              result = new AdditionalDocumentAuditParams();
              Calendar estimatedDate = ((Calendar) doc.getPropertyValue("dc:modified"));

              // We can not directly use the repo timestamp
              // because Audit and VCS can be in separated DB
              // => try to find the matching TS in Audit
              StringBuilder queryString = new StringBuilder();
              queryString.append("from LogEntry log where log.docUUID in (");
              queryString.append("'" + targetUUID + "'");
              if (doc.isVersion()) {
                DocumentModelList proxies = session.getProxies(doc.getRef(), null);
                for (DocumentModel proxy : proxies) {
                  queryString.append(",'" + proxy.getId() + "'");
                }
              }
              queryString.append(",'" + doc.getId() + "'");
              queryString.append(") AND log.eventId IN (");
              queryString.append("'" + DocumentEventTypes.DOCUMENT_CREATED + "'");
              queryString.append(",'" + DocumentEventTypes.DOCUMENT_CHECKEDIN + "'");
              queryString.append(") AND log.eventDate >= :minDate ");
              queryString.append(" order by log.eventId asc");

              estimatedDate.add(Calendar.MILLISECOND, -500);
              Map<String, Object> params = new HashMap<String, Object>();
              params.put("minDate", estimatedDate.getTime());

              List<LogEntry> dateEntries =
                  (List<LogEntry>) reader.nativeQuery(queryString.toString(), params, 0, 20);
              if (dateEntries.size() > 0) {
                result.targetUUID = targetUUID;
                Calendar maxDate = new GregorianCalendar();
                maxDate.setTime(dateEntries.get(0).getEventDate());
                maxDate.add(Calendar.MILLISECOND, -500);
                result.maxDate = maxDate.getTime();
              } else {
                // no other choice : use the VCS TS
                // results may be truncated in some DB config
                result.targetUUID = targetUUID;
                result.maxDate = ((Calendar) doc.getPropertyValue("dc:modified")).getTime();
              }
            }
          }
        }
      }
    }
    return result;
  }