use of com.b2international.snowowl.core.internal.ResourceDocument in project snow-owl by b2ihealthcare.
the class CodeSystemUpgradeSynchronizationRequest method execute.
@Override
public Boolean execute(RepositoryContext context) {
final String message = String.format("Merge %s into %s", source, codeSystemId);
CodeSystem codeSystem = CodeSystemRequests.prepareGetCodeSystem(codeSystemId.getResourceId()).build().execute(context);
if (codeSystem.getUpgradeOf() == null) {
throw new BadRequestException("Code System '%s' is not an Upgrade Code System. It cannot be synchronized with '%s'.", codeSystemId, source);
}
final String sourceBranchPath = context.service(ResourceURIPathResolver.class).resolve(context, List.of(source)).stream().findFirst().get();
// merge all changes from the source to the current upgrade of branch
final Merge merge = RepositoryRequests.merging().prepareCreate().setSource(sourceBranchPath).setTarget(codeSystem.getBranchPath()).setUserId(context.service(User.class).getUsername()).setCommitComment(message).setSquash(false).build(codeSystem.getToolingId()).getRequest().execute(context);
if (merge.getStatus() != Merge.Status.COMPLETED) {
// report conflicts
ApiError apiError = merge.getApiError();
Collection<MergeConflict> conflicts = merge.getConflicts();
context.log().error("Failed to sync source CodeSystem content to upgrade CodeSystem. Error: {}. Conflicts: {}", apiError.getMessage(), conflicts);
throw new ConflictException("Upgrade code system synchronization can not be performed due to conflicting content errors.").withAdditionalInfo(Map.of("conflicts", conflicts, "mergeError", apiError.getMessage()));
}
if (!codeSystem.getUpgradeOf().equals(source)) {
return new BranchRequest<>(Branch.MAIN_PATH, new ResourceRepositoryCommitRequestBuilder().setBody((tx) -> {
ResourceDocument entry = tx.lookup(codeSystemId.getResourceId(), ResourceDocument.class);
tx.add(ResourceDocument.builder(entry).upgradeOf(source).build());
tx.commit(String.format("Update upgradeOf from '%s' to '%s'", codeSystem.getUpgradeOf(), source));
return Boolean.TRUE;
}).setCommitComment(String.format("Complete upgrade of %s to %s", codeSystem.getUpgradeOf().getResourceId(), codeSystem.getExtensionOf())).build()).execute(context).getResultAs(Boolean.class);
} else {
return Boolean.TRUE;
}
}
use of com.b2international.snowowl.core.internal.ResourceDocument in project snow-owl by b2ihealthcare.
the class BundleDeleteRequest method execute.
@Override
public Boolean execute(TransactionContext context) {
try {
final ResourceDocument bundleToDelete = context.lookup(resourceId, ResourceDocument.class);
updateResourceBundles(context, bundleToDelete);
context.delete(bundleToDelete);
} catch (ComponentNotFoundException e) {
// ignore, probably already deleted
}
return Boolean.TRUE;
}
use of com.b2international.snowowl.core.internal.ResourceDocument in project snow-owl by b2ihealthcare.
the class BaseResourceUpdateRequest method updateBundle.
private boolean updateBundle(TransactionContext context, String resourceId, String oldBundleId, Builder updated) {
if (bundleId == null || bundleId.equals(oldBundleId)) {
return false;
}
final List<String> bundleAncestorIds = getBundleAncestorIds(context, resourceId);
updated.bundleId(bundleId);
updated.bundleAncestorIds(bundleAncestorIds);
// Update bundle ancestor IDs on all descendants of the resource (their bundle ID does not change)
final Iterator<Resource> descendants = ResourceRequests.prepareSearch().filterByBundleAncestorId(resourceId).setLimit(5_000).stream(context).flatMap(Resources::stream).iterator();
final Multimap<String, Resource> resourcesByParentId = Multimaps.index(descendants, Resource::getBundleId);
// Calculate new ancestor ID list for direct children of this resource first
final ImmutableList.Builder<String> ancestorIdsOfParent = ImmutableList.<String>builder().addAll(bundleAncestorIds);
if (!IComponent.ROOT_ID.equals(bundleId)) {
ancestorIdsOfParent.add(bundleId);
}
final Map<String, List<String>> newAncestorIdsByParentId = newHashMap(Map.of(resourceId, ancestorIdsOfParent.build()));
// Start processing ancestor ID lists with the direct children of the resource
final Deque<Map.Entry<String, Collection<Resource>>> toProcess = new ArrayDeque<>();
toProcess.addLast(new AbstractMap.SimpleImmutableEntry<>(resourceId, resourcesByParentId.get(resourceId)));
while (!toProcess.isEmpty()) {
final Entry<String, Collection<Resource>> entry = toProcess.removeFirst();
final String parentId = entry.getKey();
final Collection<Resource> resources = entry.getValue();
/*
* XXX: We will use the same ancestor ID list for all sibling resources. The
* call removes the entry from the map as it will never be read again after this
* iteration.
*/
final List<String> newAncestorIds = newAncestorIdsByParentId.remove(parentId);
for (final Resource current : resources) {
final String id = current.getId();
final ResourceDocument resource = context.lookup(id, ResourceDocument.class);
final ResourceDocument.Builder resourceBuilder = ResourceDocument.builder(resource);
if (!Objects.equals(resource.getBundleAncestorIds(), newAncestorIds)) {
resourceBuilder.bundleAncestorIds(newAncestorIds);
context.update(resource, resourceBuilder.build());
}
final Collection<Resource> next = resourcesByParentId.get(id);
if (!next.isEmpty()) {
/*
* If the current resource has any children, make a note that we have to update
* bundleAncestorIds for them as well. The bundleId for these resources remains
* "id".
*/
final List<String> nextAncestorIds = ImmutableList.<String>builder().addAll(newAncestorIds).add(parentId).build();
newAncestorIdsByParentId.put(id, nextAncestorIds);
toProcess.add(new AbstractMap.SimpleImmutableEntry<>(id, next));
}
}
}
return true;
}
Aggregations