mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-02-05 22:29:11 +01:00
Add update steps for namespaces
This adds a new update step API dedicated to handle namespace related data. Pushed-by: Rene Pfeuffer<rene.pfeuffer@cloudogu.com> Co-authored-by: René Pfeuffer<rene.pfeuffer@cloudogu.com> Committed-by: René Pfeuffer<rene.pfeuffer@cloudogu.com>
This commit is contained in:
@@ -61,6 +61,7 @@ import sonia.scm.store.ConfigurationStoreFactory;
|
||||
import sonia.scm.store.DataStoreFactory;
|
||||
import sonia.scm.store.DefaultBlobDirectoryAccess;
|
||||
import sonia.scm.store.FileBlobStoreFactory;
|
||||
import sonia.scm.store.FileNamespaceUpdateIterator;
|
||||
import sonia.scm.store.FileRepositoryUpdateIterator;
|
||||
import sonia.scm.store.FileStoreUpdateStepUtilFactory;
|
||||
import sonia.scm.store.JAXBConfigurationEntryStoreFactory;
|
||||
@@ -68,6 +69,7 @@ import sonia.scm.store.JAXBConfigurationStoreFactory;
|
||||
import sonia.scm.store.JAXBDataStoreFactory;
|
||||
import sonia.scm.store.JAXBPropertyFileAccess;
|
||||
import sonia.scm.update.BlobDirectoryAccess;
|
||||
import sonia.scm.update.NamespaceUpdateIterator;
|
||||
import sonia.scm.update.PropertyFileAccess;
|
||||
import sonia.scm.update.RepositoryUpdateIterator;
|
||||
import sonia.scm.update.StoreUpdateStepUtilFactory;
|
||||
@@ -124,6 +126,7 @@ public class BootstrapModule extends AbstractModule {
|
||||
bind(PropertyFileAccess.class, JAXBPropertyFileAccess.class);
|
||||
bind(BlobDirectoryAccess.class, DefaultBlobDirectoryAccess.class);
|
||||
bind(RepositoryUpdateIterator.class, FileRepositoryUpdateIterator.class);
|
||||
bind(NamespaceUpdateIterator.class, FileNamespaceUpdateIterator.class);
|
||||
bind(StoreUpdateStepUtilFactory.class, FileStoreUpdateStepUtilFactory.class);
|
||||
bind(new TypeLiteral<UpdateStepRepositoryMetadataAccess<Path>>() {}).to(new TypeLiteral<MetadataStore>() {});
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ package sonia.scm.lifecycle.modules;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
import sonia.scm.migration.NamespaceUpdateStep;
|
||||
import sonia.scm.migration.RepositoryUpdateStep;
|
||||
import sonia.scm.migration.UpdateStep;
|
||||
import sonia.scm.plugin.PluginLoader;
|
||||
@@ -41,7 +42,8 @@ public class UpdateStepModule extends AbstractModule {
|
||||
@Override
|
||||
protected void configure() {
|
||||
Multibinder<UpdateStep> updateStepBinder = Multibinder.newSetBinder(binder(), UpdateStep.class);
|
||||
Multibinder<RepositoryUpdateStep> repositoryUdateStepBinder = Multibinder.newSetBinder(binder(), RepositoryUpdateStep.class);
|
||||
Multibinder<RepositoryUpdateStep> repositoryUpdateStepBinder = Multibinder.newSetBinder(binder(), RepositoryUpdateStep.class);
|
||||
Multibinder<NamespaceUpdateStep> namespaceUpdateStepBinder = Multibinder.newSetBinder(binder(), NamespaceUpdateStep.class);
|
||||
pluginLoader
|
||||
.getExtensionProcessor()
|
||||
.byExtensionPoint(UpdateStep.class)
|
||||
@@ -49,6 +51,10 @@ public class UpdateStepModule extends AbstractModule {
|
||||
pluginLoader
|
||||
.getExtensionProcessor()
|
||||
.byExtensionPoint(RepositoryUpdateStep.class)
|
||||
.forEach(stepClass -> repositoryUdateStepBinder.addBinding().to(stepClass));
|
||||
.forEach(stepClass -> repositoryUpdateStepBinder.addBinding().to(stepClass));
|
||||
pluginLoader
|
||||
.getExtensionProcessor()
|
||||
.byExtensionPoint(NamespaceUpdateStep.class)
|
||||
.forEach(stepClass -> namespaceUpdateStepBinder.addBinding().to(stepClass));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ package sonia.scm.update;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.migration.NamespaceUpdateContext;
|
||||
import sonia.scm.migration.NamespaceUpdateStep;
|
||||
import sonia.scm.migration.RepositoryUpdateContext;
|
||||
import sonia.scm.migration.RepositoryUpdateStep;
|
||||
import sonia.scm.migration.UpdateException;
|
||||
@@ -46,28 +48,33 @@ public class UpdateEngine {
|
||||
|
||||
public static final Logger LOG = LoggerFactory.getLogger(UpdateEngine.class);
|
||||
|
||||
|
||||
private final List<UpdateStepWrapper> steps;
|
||||
private final RepositoryUpdateIterator repositoryUpdateIterator;
|
||||
private final NamespaceUpdateIterator namespaceUpdateIterator;
|
||||
private final UpdateStepStore updateStepStore;
|
||||
|
||||
@Inject
|
||||
public UpdateEngine(
|
||||
Set<UpdateStep> globalSteps,
|
||||
Set<RepositoryUpdateStep> repositorySteps,
|
||||
Set<NamespaceUpdateStep> namespaceSteps,
|
||||
RepositoryUpdateIterator repositoryUpdateIterator,
|
||||
UpdateStepStore updateStepStore) {
|
||||
NamespaceUpdateIterator namespaceUpdateIterator, UpdateStepStore updateStepStore) {
|
||||
this.repositoryUpdateIterator = repositoryUpdateIterator;
|
||||
this.namespaceUpdateIterator = namespaceUpdateIterator;
|
||||
this.updateStepStore = updateStepStore;
|
||||
this.steps = sortSteps(globalSteps, repositorySteps);
|
||||
this.steps = sortSteps(globalSteps, repositorySteps, namespaceSteps);
|
||||
}
|
||||
|
||||
private List<UpdateStepWrapper> sortSteps(Set<UpdateStep> globalSteps, Set<RepositoryUpdateStep> repositorySteps) {
|
||||
private List<UpdateStepWrapper> sortSteps(Set<UpdateStep> globalSteps, Set<RepositoryUpdateStep> repositorySteps, Set<NamespaceUpdateStep> namespaceSteps) {
|
||||
LOG.trace("sorting available update steps:");
|
||||
List<UpdateStepWrapper> sortedSteps =
|
||||
concat(
|
||||
globalSteps.stream().filter(this::notRunYet).map(GlobalUpdateStepWrapper::new),
|
||||
repositorySteps.stream().map(RepositoryUpdateStepWrapper::new))
|
||||
concat(
|
||||
globalSteps.stream().filter(this::notRunYet).map(GlobalUpdateStepWrapper::new),
|
||||
repositorySteps.stream().map(RepositoryUpdateStepWrapper::new)),
|
||||
namespaceSteps.stream().map(NamespaceUpdateStepWrapper::new)
|
||||
)
|
||||
.sorted(
|
||||
Comparator
|
||||
.comparing(UpdateStepWrapper::getTargetVersion)
|
||||
@@ -248,4 +255,52 @@ public class UpdateEngine {
|
||||
return updateStepStore.notRunYet(repositoryId, delegate);
|
||||
}
|
||||
}
|
||||
|
||||
private class NamespaceUpdateStepWrapper extends UpdateStepWrapper {
|
||||
|
||||
private final NamespaceUpdateStep delegate;
|
||||
|
||||
public NamespaceUpdateStepWrapper(NamespaceUpdateStep delegate) {
|
||||
super(delegate);
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGlobalUpdateStep() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isCoreUpdate() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
void doUpdate() {
|
||||
namespaceUpdateIterator.updateEachNamespace(this::doUpdate);
|
||||
}
|
||||
|
||||
@Override
|
||||
void doUpdate(String namespace) throws Exception {
|
||||
if (notRunYet(namespace)) {
|
||||
LOG.info("running update step for type {} and version {} (class {}) for namespace {}",
|
||||
delegate.getAffectedDataType(),
|
||||
delegate.getTargetVersion(),
|
||||
delegate.getClass().getName(),
|
||||
namespace
|
||||
);
|
||||
delegate.doUpdate(new NamespaceUpdateContext(namespace));
|
||||
updateStepStore.storeExecutedUpdate(namespace, delegate);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean notRunYet(String namespace) {
|
||||
LOG.trace("checking whether to run update step for type {} and version {} on namespace {}",
|
||||
delegate.getAffectedDataType(),
|
||||
delegate.getTargetVersion(),
|
||||
namespace
|
||||
);
|
||||
return updateStepStore.notRunYet(namespace, delegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ package sonia.scm.update;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.migration.NamespaceUpdateStep;
|
||||
import sonia.scm.migration.RepositoryUpdateStep;
|
||||
import sonia.scm.migration.UpdateStep;
|
||||
import sonia.scm.migration.UpdateStepTarget;
|
||||
@@ -52,6 +53,11 @@ class UpdateStepStore {
|
||||
storeNewVersion(store, updateStep);
|
||||
}
|
||||
|
||||
void storeExecutedUpdate(String namespace, NamespaceUpdateStep updateStep) {
|
||||
ConfigurationEntryStore<UpdateVersionInfo> store = createNamespaceStore(namespace);
|
||||
storeNewVersion(store, updateStep);
|
||||
}
|
||||
|
||||
void storeExecutedUpdate(UpdateStep updateStep) {
|
||||
ConfigurationEntryStore<UpdateVersionInfo> store = createGlobalStore();
|
||||
storeNewVersion(store, updateStep);
|
||||
@@ -65,6 +71,10 @@ class UpdateStepStore {
|
||||
return notRunYet(createRepositoryStore(repositoryId), updateStep);
|
||||
}
|
||||
|
||||
boolean notRunYet(String namespace, NamespaceUpdateStep updateStep) {
|
||||
return notRunYet(createNamespaceStore(namespace), updateStep);
|
||||
}
|
||||
|
||||
private void storeNewVersion(ConfigurationEntryStore<UpdateVersionInfo> store, UpdateStepTarget updateStep) {
|
||||
UpdateVersionInfo newVersionInfo = new UpdateVersionInfo(updateStep.getTargetVersion().getParsedVersion());
|
||||
store.put(updateStep.getAffectedDataType(), newVersionInfo);
|
||||
@@ -99,4 +109,12 @@ class UpdateStepStore {
|
||||
.forRepository(repositoryId)
|
||||
.build();
|
||||
}
|
||||
|
||||
private ConfigurationEntryStore<UpdateVersionInfo> createNamespaceStore(String namespace) {
|
||||
return storeFactory
|
||||
.withType(UpdateVersionInfo.class)
|
||||
.withName(STORE_NAME)
|
||||
.forNamespace(namespace)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user