Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ public Optional<AuditEntryIssue> getAuditEntryIssue(String changeId) {
if (changeId == null || changeId.trim().isEmpty()) {
throw new IllegalArgumentException("Change ID is required");
}
return opsClient.getAuditIssueByChange(changeId.trim());
return opsClient.getAuditIssueByChangeId(changeId.trim());
}

private OpsClient createOpsClient() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public List<AuditEntry> getAuditHistory() {
}

@Override
public List<AuditEntry> getSnapshotList() {
public List<AuditEntry> getAuditSnapshot() {
throw new UnsupportedOperationException("getSnapshotList still not implemented for cloud edition");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.flamingock.internal.core.builder.ops;

import io.flamingock.internal.common.core.audit.AuditEntry;
package io.flamingock.internal.common.core.audit;

import java.util.List;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,27 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.flamingock.internal.core.builder.ops;
package io.flamingock.internal.common.core.audit;

import io.flamingock.internal.common.core.audit.issue.AuditEntryIssue;
import io.flamingock.internal.common.core.recovery.FixResult;
import io.flamingock.internal.common.core.recovery.Resolution;

import java.util.List;
import java.util.Optional;

public interface AuditIssueManager {
/**
* Get detailed information about a specific change that has issues.
* This includes full audit history, error messages, and execution attempts.
*
* @param changeId the change ID to inspect
* @return detailed issue information including all audit entries, error details, etc.
*/
Optional<AuditEntryIssue> getAuditIssueByChange(String changeId);

public interface AuditIssueReader {
/**
* Get only entries with issues
* @return List of audit entries with problems/issues
*/
List<AuditEntryIssue> getAuditIssues();

/**
* Resolves an audit issue for the given change by marking it as
* either {@link Resolution#APPLIED} or {@link Resolution#ROLLED_BACK}.
* Get detailed information about a specific change that has issues.
* This includes full audit history, error messages, and execution attempts.
*
* @param changeId the change identifier
* @param resolution how the issue should be resolved
* @return result of the fix operation
* @param changeId the change ID to inspect
* @return detailed issue information including all audit entries, error details, etc.
*/
FixResult fixAuditIssue(String changeId, Resolution resolution);
Optional<AuditEntryIssue> getAuditIssueByChangeId(String changeId);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright 2025 Flamingock (https://www.flamingock.io)
*
* 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 io.flamingock.internal.common.core.audit;

import io.flamingock.internal.common.core.recovery.FixResult;
import io.flamingock.internal.common.core.recovery.Resolution;

public interface AuditIssueResolver extends AuditIssueReader {


/**
* Resolves an audit issue for the given change by marking it as
* either {@link Resolution#APPLIED} or {@link Resolution#ROLLED_BACK}.
*
* @param changeId the change identifier
* @param resolution how the issue should be resolved
* @return result of the fix operation
*/
FixResult fixAuditIssue(String changeId, Resolution resolution);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,20 @@
import io.flamingock.internal.common.core.audit.issue.AuditEntryIssueFactory;
import io.flamingock.internal.common.core.audit.issue.NonIssue;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public interface AuditReader {
public interface AuditReader extends AuditHistoryReader, AuditIssueReader {

List<AuditEntry> getAuditHistory();

default List<AuditEntry> getSnapshotList() {
default List<AuditEntry> getAuditSnapshot() {
AuditSnapshotBuilder builder = new AuditSnapshotBuilder();
getAuditHistory().forEach(builder::addEntry);
return builder.buildList();
}

default List<AuditEntryIssue> getAuditIssues() {
return getSnapshotList()
return getAuditSnapshot()
.stream()
.map(AuditEntryIssueFactory::getIssue)
.filter(issue -> !(issue instanceof NonIssue))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright 2025 Flamingock (https://www.flamingock.io)
*
* 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 io.flamingock.internal.common.core.audit;

public enum AuditReaderType {
MONGOCK
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.flamingock.internal.core.builder.ops;

import io.flamingock.internal.common.core.audit.AuditEntry;
package io.flamingock.internal.common.core.audit;

import java.time.LocalDateTime;
import java.util.List;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
package io.flamingock.internal.core.builder.ops;

import io.flamingock.internal.common.core.audit.AuditEntry;
import io.flamingock.internal.common.core.audit.AuditHistoryReader;
import io.flamingock.internal.common.core.audit.AuditIssueResolver;
import io.flamingock.internal.common.core.audit.AuditSnapshotReader;
import io.flamingock.internal.common.core.audit.issue.AuditEntryIssue;
import io.flamingock.internal.common.core.recovery.FixResult;
import io.flamingock.internal.common.core.recovery.Resolution;
Expand All @@ -31,7 +34,7 @@
import java.util.Optional;
import java.util.stream.Collectors;

public class OpsClient implements AuditSnapshotReader, AuditHistoryReader, AuditIssueManager {
public class OpsClient implements AuditSnapshotReader, AuditHistoryReader, AuditIssueResolver {
private final Logger logger = FlamingockLoggerFactory.getLogger("OpsClient");

private final AuditPersistence auditPersistence;
Expand All @@ -48,20 +51,20 @@ public List<AuditEntry> getAuditHistory() {
@Override
public List<AuditEntry> getAuditSnapshot() {
logger.debug("Getting audit entries snapshot (latest per change)");
return auditPersistence.getSnapshotList();
return auditPersistence.getAuditSnapshot();
}

@Override
public List<AuditEntry> getAuditSnapshotSince(LocalDateTime since) {
logger.debug("Getting audit entries since: {}", since);
return auditPersistence.getSnapshotList()
return auditPersistence.getAuditSnapshot()
.stream()
.filter(auditEntry -> !auditEntry.getCreatedAt().isBefore(since))
.collect(Collectors.toList());
}

@Override
public Optional<AuditEntryIssue> getAuditIssueByChange(String changeId) {
public Optional<AuditEntryIssue> getAuditIssueByChangeId(String changeId) {
logger.debug("Getting issue details for changeId: {}", changeId);
return auditPersistence.getAuditIssueByChangeId(changeId);
}
Expand All @@ -77,7 +80,7 @@ public List<AuditEntryIssue> getAuditIssues() {
public FixResult fixAuditIssue(String changeId, Resolution resolution) {
logger.debug("Change[{}] marked as {}", changeId, resolution);

Optional<AuditEntryIssue> auditIssue = getAuditIssueByChange(changeId);
Optional<AuditEntryIssue> auditIssue = getAuditIssueByChangeId(changeId);
if (!auditIssue.isPresent()) {
return FixResult.NO_ISSUE_FOUND;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
*/
package io.flamingock.internal.core.targets;

import io.flamingock.internal.common.core.audit.AuditHistoryReader;
import io.flamingock.internal.common.core.audit.AuditReaderType;
import io.flamingock.internal.common.core.context.ContextInitializable;
import io.flamingock.internal.core.runtime.ExecutionRuntime;
import io.flamingock.internal.core.targets.mark.NoOpTargetSystemAuditMarker;
import io.flamingock.internal.core.targets.mark.TargetSystemAuditMarker;
import io.flamingock.internal.core.transaction.TransactionWrapper;
import io.flamingock.internal.util.constants.CommunityPersistenceConstants;

import java.util.Optional;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -98,4 +101,33 @@ public TargetSystemAuditMarker getOnGoingTaskStatusRepository() {
*/
abstract public TransactionWrapper getTxWrapper();

/**
* Returns an audit history reader for importing audit entries from external migration sources.
* <p>
* This method enables Flamingock to import audit history from legacy migration tools or other
* Flamingock installations, preventing re-execution of already-applied changes. The returned
* reader provides access to historical audit entries that can be written to Flamingock's audit store.
* <p>
* Common use cases include:
* <ul>
* <li><strong>Mongock migration</strong>: Import Mongock change history when migrating from Mongock to Flamingock</li>
* <li><strong>Community to Cloud migration</strong>: Import audit history from local database to Flamingock Cloud backend</li>
* <li><strong>Future extensibility</strong>: Support for other migration tools (Liquibase, Flyway, etc.)</li>
* </ul>
* <p>
* The default implementation returns {@code Optional.empty()}, indicating no audit reader is available.
* Target system implementations should override this method to provide database-specific readers when
* migration support is needed.
*
* @param type the type of audit reader to retrieve (e.g., {@link AuditReaderType#MONGOCK})
* @return an {@link Optional} containing the audit history reader if supported for the given type,
* or {@link Optional#empty()} if this target system does not support audit reading for the specified type
* @see AuditHistoryReader
* @see AuditReaderType
* @see io.flamingock.importer.ImporterAdapter
*/
public Optional<AuditHistoryReader> getAuditAuditReader(AuditReaderType type) {
return Optional.empty();
}

}
Loading