/** * Method that actually performs group GET. Override if needed. */ protected Response doGet(@Nonnull final Context context, @Nonnull final DispatchedRepositories dispatched) throws Exception { final GroupFacet groupFacet = context.getRepository().facet(GroupFacet.class); return getFirst(context, groupFacet.members(), dispatched); }
/** * Returns stream of all non-group repositories reachable from the given repository. */ private static Stream<Repository> members(final Repository repository) { return repository.facet(GroupFacet.class).leafMembers().stream(); }
private void removeRepositoryFromAllGroups(final Repository repositoryToRemove) throws Exception { for (Repository group : repositories.values()) { Optional<GroupFacet> groupFacet = group.optionalFacet(GroupFacet.class); if (groupFacet.isPresent() && groupFacet.get().member(repositoryToRemove)) { removeRepositoryFromGroup(repositoryToRemove, group); } } }
private List<Repository> allMembers(final Repository repository) { if (groupType.equals(repository.getType())) { return repository.facet(GroupFacet.class).allMembers(); } else { return Collections.singletonList(repository); } }
/** * Invalidates the group caches for given repository. */ public static void invalidateGroupCaches(final Repository repository) { checkNotNull(repository); checkArgument(GroupType.NAME.equals(repository.getType().getValue())); GroupFacet groupFacet = repository.facet(GroupFacet.class); groupFacet.invalidateGroupCaches(); }
private Asset getAssetById(final Repository repository, final EntityId assetId) { Optional<GroupFacet> optionalGroupFacet = repository.optionalFacet(GroupFacet.class); List<Repository> members = optionalGroupFacet.isPresent() ? optionalGroupFacet.get().allMembers() : Collections.singletonList(repository); return Transactional.operation.withDb(repository.facet(StorageFacet.class).txSupplier()).call(() -> { StorageTx tx = UnitOfWork.currentTx(); Asset candidate = tx.findAsset(assetId); if (candidate != null) { final String asssetBucketRepositoryName = bucketStore.getById(candidate.bucketId()).getRepositoryName(); if (members.stream().anyMatch(repo -> repo.getName().equals(asssetBucketRepositoryName))) { return candidate; } } return null; }); }
private boolean containsGroup(Repository root, String repositoryName, Set<Repository> checkedGroups) { return root.facet(GroupFacet.class).members().stream().anyMatch((repository) -> { return checkedGroups.add(repository) && (repository.getName().equals(repositoryName) || (groupType.equals(repository.getType()) && containsGroup(repository, repositoryName, checkedGroups))); }); }
@VisibleForTesting Map<String, List<String>> getRepoToContainedGroupMap(List<Repository> repositories) { Map<String, List<String>> repoToContainedGroupMap = new HashMap<>(); for (Repository repository : repositories) { List<String> groupNames = new ArrayList<>(); groupNames.add(repository.getName()); groupNames.addAll(repositories.stream().filter(groupRepository -> { Optional<GroupFacet> groupFacet = groupRepository.optionalFacet(GroupFacet.class); return groupFacet.isPresent() && groupFacet.get().leafMembers().stream() .anyMatch(leafMember -> repository.getName().equals(leafMember.getName())); }).map(groupRepository -> groupRepository.getName()).collect(Collectors.toSet())); repoToContainedGroupMap.put(repository.getName(), groupNames); } return repoToContainedGroupMap; }
private void findContainingGroups(final String name, final SortedMap<Integer, List<String>> groupNamesByLevel, final int level) { final List<String> newContainingGroups = new ArrayList<>(); //find any groups that directly contain the desired repository name (and make sure to only include each name //once to save processing time) repositories.values().stream().filter(repository -> repository.optionalFacet(GroupFacet.class).filter(groupFacet -> groupFacet.member(name)).isPresent() && groupNamesByLevel.values().stream().noneMatch(repoNames -> repoNames.contains(repository.getName()))) .forEach(repository -> newContainingGroups.add(repository.getName())); List<String> groupNames = groupNamesByLevel.computeIfAbsent(level, newLevel -> new ArrayList<>()); groupNames.addAll(newContainingGroups); //now process each group we found and check if any groups contain it newContainingGroups.forEach( newName -> findContainingGroups(newName, groupNamesByLevel, level + 1)); }
/** * Searches the member repositories, returning the merged response for all contacted member repositories that returned * a valid search response. */ private NpmSearchResponse searchMembers(final Context context, final DispatchedRepositories dispatched, final Parameters parameters) throws Exception { // preserve original from and size for repeated queries int from = npmSearchParameterExtractor.extractFrom(parameters); int size = npmSearchParameterExtractor.extractSize(parameters); // if the text is empty, then we override the original parameters to return a full set from each upstream source // we could make multiple queries to make this more efficient, but this is the simplest implementation for now parameters.replace("from", "0"); parameters.replace("size", Integer.toString(v1SearchMaxResults)); // sort all the merged results by normalized search score, then build the result responses to send back GroupFacet groupFacet = context.getRepository().facet(GroupFacet.class); Set<Entry<Repository, Response>> entries = getAll(context, groupFacet.members(), dispatched).entrySet(); List<NpmSearchResponseObject> mergedResponses = mergeAndNormalizeResponses(entries); mergedResponses.sort(comparingDouble(NpmSearchResponseObject::getSearchScore).reversed()); List<NpmSearchResponseObject> mergedResponseObjects = mergedResponses.stream() .skip(from) .limit(size) .collect(toList()); return npmSearchResponseFactory.buildResponseForObjects(mergedResponseObjects); }
private List<Repository> getRepositories(final Repository repository) { checkNotNull(repository); if (groupType.equals(repository.getType())) { return repository.facet(GroupFacet.class).leafMembers(); } return ImmutableList.of(repository); }
@Subscribe @AllowConcurrentEvents public void on(final NpmSearchIndexInvalidatedEvent event) { if (facet(GroupFacet.class).member(event.getRepository())) { invalidateCachedSearchIndex(); } }
@Override protected final Response doGet(@Nonnull final Context context, @Nonnull final GroupHandler.DispatchedRepositories dispatched) throws Exception { Repository repository = context.getRepository(); GroupFacet groupFacet = repository.facet(GroupFacet.class); makeUnconditional(context.getRequest()); Map<Repository, Response> responses; try { responses = getAll(context, groupFacet.members(), dispatched); } finally { makeConditional(context.getRequest()); } List<Payload> payloads = responses.values().stream() .filter(response -> response.getStatus().getCode() == HttpStatus.OK && response.getPayload() != null) .map(Response::getPayload) .collect(Collectors.toList()); if (payloads.isEmpty()) { return notFoundResponse(context); } return HttpResponses.ok(merge(repository, payloads)); }
@Override public List<Repository> leafMembers() { Set<Repository> leafMembers = new LinkedHashSet<>(); for (Repository repository : members()) { if (groupType.equals(repository.getType())) { leafMembers.addAll(repository.facet(GroupFacet.class).leafMembers()); } else { leafMembers.add(repository); } } return new ArrayList<>(leafMembers); }
@Override protected void execute(final Repository repository) { if (hasBeenProcessed(repository)) { log.debug("Skipping repository '{}'; it has already been processed"); return; } if (isGroupRepository(repository)) { markProcessed(repository); // nothing to do for the group itself repository.facet(GroupFacet.class).members().stream().filter(this::appliesTo).forEach(this::execute); } else { log.info("Executing removal of snapshots on repository '{}'", repository.getName()); TaskConfiguration config = getConfiguration(); RemoveSnapshotsConfig removeSnapshotsConfig = new RemoveSnapshotsConfig( config.getInteger(MINIMUM_SNAPSHOT_RETAINED_COUNT, 1), config.getInteger(SNAPSHOT_RETENTION_DAYS, 30), config.getBoolean(REMOVE_IF_RELEASED, false), config.getInteger(GRACE_PERIOD, -1)); repository.facet(RemoveSnapshotsFacet.class).removeSnapshots(removeSnapshotsConfig); markProcessed(repository); } }
@Override public void contribute(final BoolQueryBuilder query, final String type, final String value) { if (value == null) { return; } Repository repository = repositoryManager.get(value); if (repository != null) { Optional<GroupFacet> groupFacet = repository.optionalFacet(GroupFacet.class); if (groupFacet.isPresent()) { List<Repository> members = groupFacet.get().leafMembers(); query.must(QueryBuilders.termsQuery(type, members.stream().map(Repository::getName).toArray(String[]::new))); return; } } super.contribute(query, type, value); } }
@Override protected Content buildIndex(final StorageTx tx, final Path path) throws IOException { final List<Repository> members = facet(GroupFacet.class).leafMembers(); final Closer closer = Closer.create(); try {
@Override public void publishIndex() throws IOException { UnitOfWork.begin(getRepository().facet(StorageFacet.class).txSupplier()); try (DuplicateDetectionStrategy<Record> strategy = duplicateDetectionStrategyProvider.get()) { List<Repository> leafMembers = facet(GroupFacet.class).leafMembers(); ArrayList<String> withoutIndex = new ArrayList<>(); for (Iterator<Repository> ri = leafMembers.iterator(); ri.hasNext(); ) { Repository repository = ri.next(); if (repository.facet(MavenIndexFacet.class).lastPublished() == null) { withoutIndex.add(repository.getName()); ri.remove(); } } if (!withoutIndex.isEmpty()) { log.info("Following members of group {} have no index, will not participate in merged index: {}", getRepository().getName(), withoutIndex ); } MavenIndexPublisher.publishMergedIndex(getRepository(), leafMembers, strategy); } finally { UnitOfWork.end(); } } }
List<Repository> previewRepositories; if (repositories.size() == 1 && groupType.equals(repository.getType())) { previewRepositories = repository.facet(GroupFacet.class).leafMembers();