下面列出了com.google.common.base.Equivalence.Wrapper#org.sonatype.nexus.repository.Repository 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Find all GAVs that qualify for deletion.
*/
@VisibleForTesting
Set<GAV> findSnapshotCandidates(final StorageTx tx, final Repository repository)
{
log.info(PROGRESS, "Searching for GAVS with snapshots that qualify for deletion on repository '{}'",
repository.getName());
final Bucket bucket = tx.findBucket(repository);
final OResultSet<ODocument> result = tx.getDb().command(new OSQLSynchQuery<>(GAVS_WITH_SNAPSHOTS))
.execute(AttachedEntityHelper.id(bucket));
return result.stream().map((doc) -> {
String group = doc.field(P_GROUP, String.class);
String name = doc.field(P_NAME, String.class);
String baseVersion = doc.field("baseVersion", String.class);
Integer count = doc.field("cnt", Integer.class);
return new GAV(group, name, baseVersion, count);
}).collect(Collectors.toSet());
}
/**
* Get {@link Content} wrapping the NPM Package root for the {@link Context} of the current request
* to a Group Repository.
*
* @param responses {@link Map} of {@link Repository}s in a given group and the {@link Response}
* for the associated {@link Repository}
* @param context {@link Context} of the current request to a Group Repository
* @return Content
* @throws IOException if unable to load package root
*/
@Nullable
public NpmContent getFromCache(final Map<Repository, Response> responses, final Context context) throws IOException
{
Asset packageRootAsset = getPackageRootAssetFromCache(context);
if (isNull(packageRootAsset)) {
return null;
}
NpmContent npmContent = toContent(getRepository(), packageRootAsset);
npmContent.fieldMatchers(rewriteTarballUrlMatcher(getRepository(), packageRootAsset.name()));
npmContent.missingBlobInputStreamSupplier(
(missingBlobException) -> buildMergedPackageRootOnMissingBlob(responses, context, missingBlobException));
return !isStale(npmContent) ? npmContent : null;
}
@Override
public boolean assetWithComponentExists(
final Repository repository,
final String path,
final String group,
final String name)
{
return findAssetByName(repository, path)
.map(Asset::componentId)
.flatMap(componentId -> {
try (StorageTx tx = repository.facet(StorageFacet.class).txSupplier().get()) {
tx.begin();
return Optional.ofNullable(tx.findComponent(componentId));
}
})
.filter(component -> Objects.equals(component.group(), group))
.filter(component -> Objects.equals(component.name(), name))
.isPresent();
}
@Override
public void afterMove(final List<Map<String, String>> components, final Repository destination) {
destination.facet(StorageFacet.class).txSupplier();
UnitOfWork.begin(destination.facet(StorageFacet.class).txSupplier());
try {
AptHostedFacet hostedFacet = destination.facet(AptHostedFacet.class);
hostedFacet.rebuildIndexes();
}
catch (IOException e) {
log.error("Failed to update metadata, repository: {}", destination.getName(), e);
throw new UncheckedIOException(e);
}
finally {
UnitOfWork.end();
}
}
/**
* Parses an incoming "npm publish" or "npm unpublish" request, returning the results. Note that you should probably
* call this from within a try-with-resources block to manage the lifecycle of any temp blobs created during the
* operation.
*/
public NpmPublishRequest parsePublish(final Repository repository, final Payload payload) throws IOException {
checkNotNull(repository);
checkNotNull(payload);
StorageFacet storageFacet = repository.facet(StorageFacet.class);
try (TempBlob tempBlob = storageFacet.createTempBlob(payload, NpmFacetUtils.HASH_ALGORITHMS)) {
try {
return parseNpmPublish(storageFacet, tempBlob, UTF_8);
}
catch (JsonParseException e) {
// fallback
if (e.getMessage().contains("Invalid UTF-8")) {
// try again, but assume ISO8859-1 encoding now, that is illegal for JSON
return parseNpmPublish(storageFacet, tempBlob, ISO_8859_1);
}
throw new InvalidContentException("Invalid JSON input", e);
}
}
}
/**
* Publishes MI index into {@code target}, sourced from repository's own CMA structures.
*/
public static void publishHostedIndex(final Repository repository,
final DuplicateDetectionStrategy<Record> duplicateDetectionStrategy)
throws IOException
{
checkNotNull(repository);
Transactional.operation.throwing(IOException.class).call(
() -> {
final StorageTx tx = UnitOfWork.currentTx();
try (Maven2WritableResourceHandler resourceHandler = new Maven2WritableResourceHandler(repository)) {
try (IndexWriter indexWriter = new IndexWriter(resourceHandler, repository.getName(), false)) {
indexWriter.writeChunk(
transform(
decorate(
filter(getHostedRecords(tx, repository), duplicateDetectionStrategy),
repository.getName()
),
RECORD_COMPACTOR::apply
).iterator()
);
}
}
return null;
}
);
}
@Test
public void updateProxy() throws Exception {
repos.createHelmProxy(PROXY_NAME, "http://example.com");
AbstractRepositoryApiRequest request = createProxyRequest(false);
Response response = put(getUpdateRepositoryPathUrl(ProxyType.NAME, PROXY_NAME), request);
assertEquals(Status.NO_CONTENT.getStatusCode(), response.getStatus());
Repository repository = repositoryManager.get(request.getName());
assertNotNull(repository);
assertThat(repository.getConfiguration().attributes("storage")
.get("strictContentTypeValidation"),
is(false));
repositoryManager.delete(PROXY_NAME);
}
private List<Repository> subjectHasAnyContentSelectorAccessTo(final Subject subject,
final List<Repository> repositories)
{
List<String> repositoryNames = repositories.stream().map(r -> r.getName()).collect(Collectors.toList());
List<String> formats = repositories.stream().map(r -> r.getFormat().getValue()).distinct()
.collect(Collectors.toList());
List<SelectorConfiguration> selectors = selectorManager.browseActive(repositoryNames, formats);
if (selectors.isEmpty()) {
return Collections.emptyList();
}
List<Repository> permittedRepositories = new ArrayList<>();
for (Repository repository : repositories) {
Permission[] permissions = selectors.stream()
.map(s -> new RepositoryContentSelectorPermission(s, repository, singletonList(BROWSE)))
.toArray(Permission[]::new);
if (securityHelper.anyPermitted(subject, permissions)) {
permittedRepositories.add(repository);
}
}
return permittedRepositories;
}
@Test
public void whenTypeDoesNotMatchShouldNotRepair() {
underTest = new RepairMetadataComponentForTest(repositoryManager, assetEntityAdapter, type, format)
{
@Override
protected void doRepairRepository(final Repository repository) {
throw new UnsupportedOperationException();
}
};
when(repository.getType()).thenReturn(new ProxyType());
try {
underTest.repairRepository(repository);
}
catch (Exception e) {
fail("repair should not have been attempted");
}
}
@Nonnull
@Override
public Response handle(@Nonnull final Context context) throws Exception {
State state = context.getAttributes().require(TokenMatcher.State.class);
Repository repository = context.getRepository();
log.debug("[getPackage] repository: {} tokens: {}", repository.getName(), state.getTokens());
NpmPackageId packageId = packageId(state);
Content content = repository.facet(NpmHostedFacet.class)
.getDistTags(packageId);
if (content != null) {
return NpmResponses.ok(content);
}
else {
return NpmResponses.packageNotFound(packageId);
}
}
/**
* Parse a multipart-form submission creating file uploads in the blob store of the repository. Reminder, callers must
* call {@code close} on {@code TempBlobs} returned from this method.
*/
public BlobStoreMultipartForm parse(final Repository repository, final HttpServletRequest request)
throws FileUploadException
{
BlobStoreMultipartForm multipartForm = new BlobStoreMultipartForm();
TempBlobServletFileUpload upload = new TempBlobServletFileUpload(repository, multipartForm);
upload.parseRequest(request);
// ExtJs results in fields with the upload name for some reason
multipartForm.getFiles().keySet().forEach(assetName -> multipartForm.getFormFields().remove(assetName));
String token = multipartForm.getFormFields().remove(AntiCsrfHelper.ANTI_CSRF_TOKEN_NAME);
antiCsrfHelper.requireValidToken(request, token);
return multipartForm;
}
@Override
@Nullable
public Component findComponent(final StorageTx tx,
final Repository repository,
final String arch,
final String name,
final String version)
{
Iterable<Component> components = tx.findComponents(
Query.builder()
.where(P_NAME).eq(name)
.and(P_GROUP).eq(arch)
.and(P_VERSION).eq(version)
.build(),
singletonList(repository)
);
if (components.iterator().hasNext()) {
return components.iterator().next();
}
return null;
}
/**
* Construct a new repository from configuration.
*/
private Repository newRepository(final Configuration configuration) throws Exception {
String recipeName = configuration.getRecipeName();
Recipe recipe = recipe(recipeName);
log.debug("Using recipe: [{}] {}", recipeName, recipe);
Repository repository = factory.create(recipe.getType(), recipe.getFormat());
// attach mandatory facets
repository.attach(configFacet.get());
// apply recipe to repository
recipe.apply(repository);
// verify required facets
repository.facet(ViewFacet.class);
// ensure configuration sanity, once all facets are attached
repository.validate(configuration);
// initialize repository
repository.init(configuration);
return repository;
}
@Override
public void writeWithoutValidation(
final Repository repository,
final String path,
final Payload payload) throws IOException
{
final MavenFacet mavenFacet = repository.facet(MavenFacet.class);
final StorageFacet storageFacet = repository.facet(StorageFacet.class);
final MavenPath mavenPath = mavenFacet.getMavenPathParser().parsePath(path);
UnitOfWork.begin(repository.facet(StorageFacet.class).txSupplier());
try {
try (TempBlob tempBlob = storageFacet.createTempBlob(payload, HashType.ALGORITHMS)) {
mavenFacet.put(mavenPath, tempBlob, MavenMimeRulesSource.METADATA_TYPE, new AttributesMap());
}
}
finally {
UnitOfWork.end();
}
}
@Override
public void verifyHashesExistAndCorrect(final Repository repository, final String path) throws Exception {
final MavenFacet mavenFacet = repository.facet(MavenFacet.class);
final MavenPath mavenPath = mavenFacet.getMavenPathParser().parsePath(path);
UnitOfWork.begin(repository.facet(StorageFacet.class).txSupplier());
try {
final Content content = mavenFacet.get(mavenPath);
assertThat(content, notNullValue());
final Map<HashAlgorithm, HashCode> hashCodes =
content.getAttributes().require(Content.CONTENT_HASH_CODES_MAP, Content.T_CONTENT_HASH_CODES_MAP);
for (HashType hashType : HashType.values()) {
final Content contentHash = mavenFacet.get(mavenPath.hash(hashType));
final String storageHash = hashCodes.get(hashType.getHashAlgorithm()).toString();
assertThat(storageHash, notNullValue());
try (InputStream is = contentHash.openInputStream()) {
final String mavenHash = CharStreams.toString(new InputStreamReader(is, StandardCharsets.UTF_8));
assertThat(storageHash, equalTo(mavenHash));
}
}
}
finally {
UnitOfWork.end();
}
}
@Test
public void testAdapt_proxyRepository() throws Exception {
Repository repository = createRepository(new ProxyType(), LayoutPolicy.STRICT, VersionPolicy.MIXED);
MavenProxyApiRepository proxyRepository = (MavenProxyApiRepository) underTest.adapt(repository);
assertRepository(proxyRepository, "proxy", true);
assertThat(proxyRepository.getMaven().getLayoutPolicy(), is("STRICT"));
assertThat(proxyRepository.getMaven().getVersionPolicy(), is("MIXED"));
// Check fields are populated, actual values validated with SimpleApiRepositoryAdapterTest
assertThat(proxyRepository.getCleanup(), nullValue());
assertThat(proxyRepository.getHttpClient(), notNullValue());
assertThat(proxyRepository.getNegativeCache(), notNullValue());
assertThat(proxyRepository.getProxy(), notNullValue());
assertThat(proxyRepository.getStorage(), notNullValue());
}
@VisibleForTesting
Context maybeCopyContextAttributes(final Repository repository,
final Request request,
final Context existingContext)
{
Context context = new Context(repository, request);
copyLocalContextAttributes(existingContext, context);
return context;
}
/**
* Builds a packages.json file as a {@code Content} instance containing the actual JSON for the given providers.
*/
private Content buildPackagesJson(final Repository repository, final Set<String> names) throws IOException {
Map<String, Object> packagesJson = new LinkedHashMap<>();
packagesJson.put(PROVIDERS_URL_KEY, repository.getUrl() + PACKAGE_JSON_PATH);
packagesJson.put(PROVIDERS_KEY, names.stream()
.collect(Collectors.toMap((each) -> each, (each) -> singletonMap(SHA256_KEY, null))));
return new Content(new StringPayload(mapper.writeValueAsString(packagesJson), ContentTypes.APPLICATION_JSON));
}
/**
* Track repository.
*/
private void track(final Repository repository) {
// configure security
securityContributor.add(repository);
log.debug("Tracking: {}", repository);
repositories.put(repository.getName(), repository);
}
@Override
public BrowseResult<Asset> browseComponentAssets(final Repository repository, final Component component)
{
checkNotNull(repository);
checkNotNull(component);
try (StorageTx storageTx = repository.facet(StorageFacet.class).txSupplier().get()) {
storageTx.begin();
return browseComponentAssetsHelper(storageTx, repository, component);
}
}
private List<Bucket> getBuckets(final StorageTx storageTx, final Iterable<Repository> repositories) {
checkNotNull(storageTx);
checkNotNull(repositories);
Iterable<Bucket> buckets = storageTx.findBuckets(repositories);
if (buckets == null) {
return Collections.emptyList();
}
return Lists.newArrayList(buckets);
}
public TempBlob removeMirrorUrlFromArtifactsXml(
final TempBlob artifact,
final Repository repository,
final String extension) throws IOException
{
return transformXmlMetadata(artifact, repository, ARTIFACTS_XML, extension, this::streamXmlToWriterAndRemoveAbsoluteUrls);
}
private Repository mockRepository(final Format format, final Type type, final Asset... assets) {
Repository repository = mock(Repository.class);
when(repository.getFormat()).thenReturn(format);
when(repository.getType()).thenReturn(type);
StorageFacet facet = mock(StorageFacet.class);
when(repository.facet(StorageFacet.class)).thenReturn(facet);
StorageTx storageTx = mock(StorageTx.class);
when(facet.txSupplier()).thenReturn(() -> storageTx);
when(storageTx.browseAssets(any(Bucket.class))).thenReturn(Arrays.asList(assets));
return repository;
}
private static Component findComponent(
final Repository repository,
final String namespace,
final String name,
final String version)
{
return repository.facet(ContentFacet.class).components().name(name).namespace(namespace).version(version).find()
.orElseThrow(() -> new ComponentNotFoundException(repository, namespace, name, version));
}
private void responseViaGroupProduces(final int upstreamStatus, final int downstreamStatus) throws Exception {
Server server = Server.withPort(0).serve("/*").withBehaviours(Behaviours.error(upstreamStatus)).start();
try {
Repository proxy = repos.createRawProxy("raw-test-proxy-" + upstreamStatus + "-" + downstreamStatus,
server.getUrl().toExternalForm());
Repository group = repos.createRawGroup("raw-test-group-" + upstreamStatus + "-" + downstreamStatus,
proxy.getName());
proxyClient = rawClient(group);
assertThat(status(proxyClient.get(TEST_PATH)), is(downstreamStatus));
}
finally {
server.stop();
}
}
@Test
public void testUserCanBrowseRepositories() {
when(securityHelper.anyPermitted(eq(subject), any(RepositoryContentSelectorPermission.class))).then(i -> {
RepositoryContentSelectorPermission p = (RepositoryContentSelectorPermission) i.getArguments()[1];
return REPOSITORY_NAME_2.equals(p.getName());
});
List<Repository> permittedRepositories = underTest.userCanBrowseRepositories(repository, repository1, repository2);
assertThat(permittedRepositories, contains(repository, repository2));
// Iterable version
permittedRepositories = underTest.userCanBrowseRepositories(Arrays.asList(repository, repository1, repository2));
assertThat(permittedRepositories, contains(repository, repository2));
}
@Override
public UploadResponse handle(final Repository repository, final ComponentUpload upload) throws IOException {
checkNotNull(repository);
checkNotNull(upload);
return doUpload(repository, upload);
}
private void verifyUserAccessOf(final Function<Repository, Boolean> accessCheck,
final String repositoryPermissionAction)
{
BiFunction<Boolean, Boolean, Boolean> userCanAccessRepositoryWhen =
(hasRepositoryPermission, hasSelectorPermission) -> {
setUpRepositoryPermission(hasRepositoryPermission, repositoryPermissionAction);
setUpSelectorPermission(hasSelectorPermission);
return accessCheck.apply(repository);
};
assertTrue(userCanAccessRepositoryWhen.apply(HAS_REPOSITORY_PERMISSION, !HAS_SELECTOR_PERMISSION));
assertTrue(userCanAccessRepositoryWhen.apply(!HAS_REPOSITORY_PERMISSION, HAS_SELECTOR_PERMISSION));
assertTrue(userCanAccessRepositoryWhen.apply(HAS_REPOSITORY_PERMISSION, HAS_SELECTOR_PERMISSION));
assertFalse(userCanAccessRepositoryWhen.apply(!HAS_REPOSITORY_PERMISSION, !HAS_SELECTOR_PERMISSION));
}
@Test
public void testGetGroups_repositoryContainedInMultipleGroupsWhichAlsoContainEachOther() {
Repository repo = mockRepository("repo");
Repository group1 = mockGroupRepository("group1", repo);
Repository group2 = mockGroupRepository("group2", repo);
Repository group3 = mockGroupRepository("group3", group1);
Repository group4 = mockGroupRepository("group4", group3);
Repository group5 = mockGroupRepository("group5", group4);
//putting in reverse order just to prove out the expected sorting
when(repositoryManager.browse()).thenReturn(Arrays.asList(group5, group4, group3, group2, group1, repo));
List<String> groups = underTest.getGroups("repo");
assertThat(groups, contains("group1", "group2", "group3", "group4", "group5"));
}
private <T extends MetadataNode<?>> T getById(final ORID orid,
final Repository repository,
final MetadataNodeEntityAdapter<T> adapter)
{
String sql = format("SELECT FROM %s WHERE contentAuth(@this.name, @this.format, :browsedRepository) == true", orid);
Map<String, Object> params = ImmutableMap.of("browsedRepository", repository.getName());
try (StorageTx storageTx = repository.facet(StorageFacet.class).txSupplier().get()) {
storageTx.begin();
return stream(storageTx.browse(sql, params).spliterator(), false)
.map(adapter::readEntity).findFirst().orElse(null);
}
}