下面列出了com.amazonaws.services.s3.model.BucketLifecycleConfiguration.Rule#org.sonatype.nexus.blobstore.api.BlobStoreConfiguration 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Subscribe
@AllowConcurrentEvents
public void on(final BlobStoreEvent event) {
if (isRecording()) {
BlobStore blobStore = event.getBlobStore();
BlobStoreConfiguration configuration = blobStore.getBlobStoreConfiguration();
AuditData data = new AuditData();
data.setDomain(DOMAIN);
data.setType(type(event.getClass()));
data.setContext(configuration.getName());
Map<String, Object> attributes = data.getAttributes();
attributes.put("name", configuration.getName());
attributes.put("type", configuration.getType());
record(data);
}
}
@Before
public void setUp() {
Blob restoredBlob = mockBlob(RESTORED_BLOB_ID);
Blob copiedBlob = mockBlob(COPIED_BLOB_ID);
when(blobStore.create(blobData, headers, null)).thenAnswer(this::newBlob);
when(blobStore.create(blobData, headers, RESTORED_BLOB_ID)).thenReturn(restoredBlob);
when(blobStore.create(sourceFile, headers, TEST_BLOB_SIZE, TEST_BLOB_HASH)).thenAnswer(this::newBlob);
when(blobStore.copy(EXISTING_BLOB_ID, headers)).thenReturn(copiedBlob);
when(blobStore.exists(any())).thenReturn(true);
when(blobStore.get(any())).thenAnswer(this::getBlob);
BlobStoreConfiguration storeConfiguration = mock(BlobStoreConfiguration.class);
when(storeConfiguration.getName()).thenReturn("test-blob-store");
when(blobStore.getBlobStoreConfiguration()).thenReturn(storeConfiguration);
}
public BlobStoreConfiguration newConfiguration(final String name, final String bucketName,
@Nullable final File credentialFile) {
BlobStoreConfiguration configuration = blobStoreManager.newConfiguration();
configuration.setName(name);
configuration.setType("Google Cloud Storage");
NestedAttributesMap configMap = configuration.attributes("google cloud storage");
configMap.set("bucket", bucketName);
configMap.set("location", "us-central1");
if (credentialFile != null) {
configMap.set("credential_file", credentialFile.getAbsolutePath());
}
NestedAttributesMap quotaMap = configuration.attributes(BlobStoreQuotaSupport.ROOT_KEY);
quotaMap.set(BlobStoreQuotaSupport.TYPE_KEY, SpaceUsedQuota.ID);
quotaMap.set(BlobStoreQuotaSupport.LIMIT_KEY, 512000L);
return configuration;
}
private void validateOverlappingBucketWithConfiguration(final BlobStoreConfiguration newConfig, // NOSONAR
final BlobStoreConfiguration existingConfig) {
String newName = newConfig.getName();
String newBucket = newConfig.attributes(CONFIG_KEY).get(BUCKET_KEY, String.class, "");
String newPrefix = newConfig.attributes(CONFIG_KEY).get(BUCKET_PREFIX_KEY, String.class, "");
String newEndpoint = newConfig.attributes(CONFIG_KEY).get(ENDPOINT_KEY, String.class, "");
if (!existingConfig.getName().equals(newName) && existingConfig.getType().equals(S3BlobStore.TYPE)) {
String existingBucket = existingConfig.attributes(CONFIG_KEY).get(BUCKET_KEY, String.class, "");
String existingPrefix = existingConfig.attributes(CONFIG_KEY).get(BUCKET_PREFIX_KEY, String.class, "");
String existingEndpoint = existingConfig.attributes(CONFIG_KEY).get(ENDPOINT_KEY, String.class, "");
if (newBucket.equals(existingBucket) &&
newEndpoint.equals(existingEndpoint) &&
prefixesOverlap(existingPrefix, newPrefix)) {
String message = format("Blob Store '%s' is already using bucket '%s'", existingConfig.getName(),
existingBucket);
if (!newPrefix.isEmpty() || !existingPrefix.isEmpty()) {
message = message + format(" with prefix '%s'", existingPrefix);
}
if (!newEndpoint.isEmpty() || !existingEndpoint.isEmpty()) {
message = message + format(" on endpoint '%s'", existingEndpoint);
}
throw new ValidationException(message);
}
}
}
private S3Encrypter getEncrypter(final BlobStoreConfiguration blobStoreConfig) {
Optional<String> encryptionType = ofNullable(
blobStoreConfig.attributes(CONFIG_KEY).get(ENCRYPTION_TYPE, String.class));
return encryptionType.map(id -> {
if (S3ManagedEncrypter.ID.equals(id)) {
return new S3ManagedEncrypter();
}
else if (KMSEncrypter.ID.equals(id)) {
Optional<String> key = ofNullable(
blobStoreConfig.attributes(CONFIG_KEY).get(ENCRYPTION_KEY, String.class));
return new KMSEncrypter(key);
}
else if (NoEncrypter.ID.equals(id)) {
return NoEncrypter.INSTANCE;
}
else {
throw new IllegalStateException("Failed to find encrypter for id:" + id);
}
}).orElse(NoEncrypter.INSTANCE);
}
private BlobStoreConfiguration getBlobStoreConfiguration(final String name) {
if (!blobStoreManager.exists(name)) {
BlobStoreResourceUtil.throwBlobStoreNotFoundException();
}
BlobStoreConfiguration configuration = blobStoreManager.get(name).getBlobStoreConfiguration();
if (!configuration.getType().equals(FileBlobStore.TYPE)) {
throw new WebApplicationMessageException(
BAD_REQUEST,
"\"Unable to read non-file blob store configuration (type was " + configuration.getType() + ")\"",
APPLICATION_JSON
);
}
return configuration;
}
@Before
public void setUp() throws Exception {
Path root = util.createTempDir().toPath();
Path content = root.resolve("content");
when(nodeAccess.getId()).thenReturn(UUID.randomUUID().toString());
when(dryRunPrefix.get()).thenReturn("");
ApplicationDirectories applicationDirectories = mock(ApplicationDirectories.class);
when(applicationDirectories.getWorkDirectory(anyString())).thenReturn(root.toFile());
final BlobStoreConfiguration config = new MockBlobStoreConfiguration();
config.attributes(FileBlobStore.CONFIG_KEY).set(FileBlobStore.PATH_KEY, root.toString());
metricsStore = spy(
new FileBlobStoreMetricsStore(new PeriodicJobServiceImpl(), nodeAccess, quotaService, QUOTA_CHECK_INTERVAL,
fileOperations));
this.underTest = new FileBlobStore(content,
new DefaultBlobIdLocationResolver(),
new SimpleFileOperations(),
metricsStore,
config,
applicationDirectories, nodeAccess, dryRunPrefix);
underTest.start();
}
@Before
public void setUp() throws Exception {
when(nodeAccess.getId()).thenReturn(UUID.randomUUID().toString());
when(nodeAccess.isOldestNode()).thenReturn(true);
when(dryRunPrefix.get()).thenReturn("");
ApplicationDirectories applicationDirectories = mock(ApplicationDirectories.class);
blobStoreDirectory = util.createTempDir().toPath();
contentDirectory = blobStoreDirectory.resolve("content");
when(applicationDirectories.getWorkDirectory(anyString())).thenReturn(blobStoreDirectory.toFile());
fileOperations = spy(new SimpleFileOperations());
metricsStore = new FileBlobStoreMetricsStore(new PeriodicJobServiceImpl(), nodeAccess, quotaService,
QUOTA_CHECK_INTERVAL, fileOperations);
blobIdResolver = new DefaultBlobIdLocationResolver();
final BlobStoreConfiguration config = new MockBlobStoreConfiguration();
config.attributes(FileBlobStore.CONFIG_KEY).set(FileBlobStore.PATH_KEY, blobStoreDirectory.toString());
underTest = new FileBlobStore(blobIdResolver,
fileOperations,
applicationDirectories,
metricsStore, nodeAccess, dryRunPrefix);
underTest.init(config);
underTest.start();
}
@Override
public void validateConfig(final BlobStoreConfiguration config) {
super.validateConfig(config);
validateEnabled();
String name = config.getName();
String fillPolicy = config.attributes(CONFIG_KEY).get(FILL_POLICY_KEY, String.class);
if (StringUtils.isBlank(fillPolicy)) {
throw new ValidationErrorsException("Blob store group requires a fill policy configuration");
}
List<String> memberNames = config.attributes(CONFIG_KEY).get(MEMBERS_KEY, List.class);
validateNotEmptyOrSelfReferencing(name, memberNames);
validateEligibleMembers(name, memberNames);
validateOnlyEmptyOrNotWritableExistingMembersRemoved(name, memberNames);
}
private void validateEligibleMembers(final String name, final List<String> memberNames) {
for (String memberName : memberNames) {
BlobStore member = blobStoreManager.get(memberName);
if (!member.isGroupable()) {
BlobStoreConfiguration memberConfig = member.getBlobStoreConfiguration();
throw new ValidationErrorsException(
format("Blob Store '%s' is of type '%s' and is not eligible to be a group member", memberName,
memberConfig.getType()));
}
// target member may not be a member of a different group
Predicate<String> sameGroup = name::equals;
blobStoreManager.getParent(memberName).filter(sameGroup.negate()).ifPresent(groupName -> {
throw new ValidationErrorsException(
format("Blob Store '%s' is already a member of Blob Store Group '%s'", memberName, groupName));
});
// target member may not be set as repository storage
int repoCount = blobStoreUtil.usageCount(memberName);
if (repoCount > 0) {
throw new ValidationErrorsException(format(
"Blob Store '%s' is set as storage for %s repositories and is not eligible to be a group member",
memberName, repoCount));
}
}
}
private void validateOnlyEmptyOrNotWritableExistingMembersRemoved(final String name, final List<String> memberNames) {
BlobStore blobStore = blobStoreManager.get(name);
if (blobStore != null) {
BlobStoreConfiguration currentConfiguration = blobStore.getBlobStoreConfiguration();
if (currentConfiguration != null && currentConfiguration.getType().equals(BlobStoreGroup.TYPE)) {
for (String existingMemberName : memberNames(currentConfiguration)) {
if (!memberNames.contains(existingMemberName)) {
BlobStore existingMember = blobStoreManager.get(existingMemberName);
if (existingMember.isWritable() || !existingMember.isEmpty()) {
throw new ValidationErrorsException(
format("Blob Store '%s' cannot be removed from Blob Store Group '%s', " +
"use 'Admin - Remove a member from a blob store group' task instead",
existingMemberName, name));
}
}
}
}
}
}
Datastore create(final BlobStoreConfiguration configuration) throws Exception {
DatastoreOptions.Builder builder = DatastoreOptions.newBuilder().setTransportOptions(transportOptions());
String credentialFile = configuration.attributes(CONFIG_KEY).get(CREDENTIAL_FILE_KEY, String.class);
if (StringUtils.hasText(credentialFile)) {
ServiceAccountCredentials credentials = ServiceAccountCredentials.fromStream(new FileInputStream(credentialFile));
logger.debug("loaded {} from {} for Google Datastore client", credentials, credentialFile);
builder.setCredentials(credentials);
builder.setProjectId(getProjectId(credentialFile));
}
return builder.build().getService();
}
Storage create(final BlobStoreConfiguration configuration) throws Exception {
StorageOptions.Builder builder = StorageOptions.newBuilder().setTransportOptions(transportOptions());
String credentialFile = configuration.attributes(CONFIG_KEY).get(CREDENTIAL_FILE_KEY, String.class);
if (StringUtils.hasText(credentialFile)) {
ServiceAccountCredentials credentials = ServiceAccountCredentials.fromStream(new FileInputStream(credentialFile));
logger.debug("loaded {} from {} for Google storage client", credentials, credentialFile);
builder.setCredentials(credentials);
builder.setProjectId(getProjectId(credentialFile));
}
return builder.build().getService();
}
@GET
@RequiresAuthentication
@Path("/{name}")
@RequiresPermissions("nexus:blobstores:read")
@Override
public GoogleCloudBlobstoreApiModel get(@PathParam("name") final String name) {
BlobStore blobStore = blobStoreManager.get(name);
if (blobStore == null) {
return null;
}
BlobStoreConfiguration config = confirmType(blobStore.getBlobStoreConfiguration());
return new GoogleCloudBlobstoreApiModel(config);
}
@Override
@Guarded(by = STARTED)
public void update(final BlobStoreConfiguration configuration) {
checkBlobStoreConfiguration(configuration);
inTxRetry(databaseInstance).run(db -> entityAdapter.update(db, (OrientBlobStoreConfiguration) configuration));
}
/**
* @param config the configuration to be updated
* @param blobstoreApiModel the source of new values
*/
void merge(BlobStoreConfiguration config, GoogleCloudBlobstoreApiModel blobstoreApiModel) {
config.setName(blobstoreApiModel.getName());
NestedAttributesMap bucket = config.attributes(CONFIG_KEY);
bucket.set(BUCKET_KEY, blobstoreApiModel.getBucketName());
bucket.set(LOCATION_KEY, blobstoreApiModel.getRegion());
if (blobstoreApiModel.getSoftQuota() != null ) {
NestedAttributesMap softQuota = config.attributes(ROOT_KEY);
softQuota.set(TYPE_KEY, checkNotNull(blobstoreApiModel.getSoftQuota().getType()));
final Long softQuotaLimit = checkNotNull(blobstoreApiModel.getSoftQuota().getLimit());
softQuota.set(LIMIT_KEY, softQuotaLimit * ONE_MILLION);
}
}
GoogleCloudBlobstoreApiModel(BlobStoreConfiguration configuration) {
this.name = configuration.getName();
this.bucketName = configuration.attributes(CONFIG_KEY).get(BUCKET_KEY, String.class);
this.region = configuration.attributes(CONFIG_KEY).get(LOCATION_KEY, String.class);
NestedAttributesMap softQuotaAttributes = configuration.attributes(ROOT_KEY);
if (softQuotaAttributes != null) {
BlobStoreApiSoftQuota softQuota = new BlobStoreApiSoftQuota();
softQuota.setLimit(configuration.attributes(ROOT_KEY).get(LIMIT_KEY, Long.class));
softQuota.setType(configuration.attributes(ROOT_KEY).get(TYPE_KEY, String.class));
this.softQuota = softQuota;
}
}
DeletedBlobIndex(final GoogleCloudDatastoreFactory factory, final BlobStoreConfiguration blobStoreConfiguration)
throws Exception {
this.gcsDatastore = factory.create(blobStoreConfiguration);
this.namespace = NAMESPACE_PREFIX + safe(blobStoreConfiguration.getName());
// this key factory will be used to add/remove blobIds from within the DELETED_BLOBS kind
this.deletedBlobsKeyFactory = gcsDatastore.newKeyFactory()
.addAncestors(NXRM_ROOT)
.setNamespace(namespace)
.setKind(DELETED_BLOBS);
}
@Test(expected = GoogleCloudProjectException.class)
public void failToCreate() throws Exception {
BlobStoreConfiguration configuration = newConfiguration("DeploymentFailsForFirestoreNativeIT", bucketName,
firestoreNativeConfiguration);
// expect specific exception to be thrown
blobStoreManager.create(configuration);
}
@Override
public long blobStoreUsageCount(final String blobStoreName) {
long count = 0;
for (BlobStore otherBlobStore : stores.values()) {
BlobStoreConfiguration otherBlobStoreConfig = otherBlobStore.getBlobStoreConfiguration();
BlobStoreDescriptor otherBlobStoreDescriptor = blobStoreDescriptors.get(otherBlobStoreConfig.getType());
if (otherBlobStoreDescriptor.configHasDependencyOn(otherBlobStoreConfig, blobStoreName)) {
count += 1;
}
}
return count;
}
@Override
public void init(final BlobStoreConfiguration configuration) {
this.blobStoreConfiguration = configuration;
try {
this.s3 = amazonS3Factory.create(configuration);
if (!s3.doesBucketExist(getConfiguredBucket())) {
s3.createBucket(getConfiguredBucket());
if (getConfiguredExpirationInDays()>=0) {
addBucketLifecycleConfiguration(null);
}
} else {
if (getConfiguredExpirationInDays()>=0) {
// bucket exists, we should test that the correct lifecycle config is present
BucketLifecycleConfiguration lifecycleConfiguration = s3.getBucketLifecycleConfiguration(getConfiguredBucket());
if (!isExpirationLifecycleConfigurationPresent(lifecycleConfiguration)) {
addBucketLifecycleConfiguration(lifecycleConfiguration);
}
}
}
setConfiguredBucket(getConfiguredBucket());
}
catch (Exception e) {
throw new BlobStoreException("Unable to initialize blob store bucket: " + getConfiguredBucket(), e, null);
}
}
public BlobStore createFile(String name) throws Exception {
BlobStoreConfiguration config = blobStoreManagerProvider.get().newConfiguration();
config.setName(name);
config.setType(FileBlobStore.TYPE);
config.attributes(FileBlobStore.CONFIG_KEY).set(PATH_KEY, name);
BlobStore blobStore = blobStoreManagerProvider.get().create(config);
blobStoreNames.add(name);
return blobStore;
}
public BlobStore createGroup(String name, String... members) throws Exception {
BlobStoreConfiguration config = blobStoreManagerProvider.get().newConfiguration();
config.setName(name);
config.setType(BlobStoreGroup.TYPE);
config.attributes(BlobStoreGroup.CONFIG_KEY).set(BlobStoreGroup.MEMBERS_KEY, asList(members));
config.attributes(BlobStoreGroup.CONFIG_KEY).set(BlobStoreGroup.FILL_POLICY_KEY, WriteToFirstMemberFillPolicy.TYPE);
BlobStore blobStore = blobStoreManagerProvider.get().create(config);
blobStoreGroupNames.add(name);
return blobStore;
}
private static BlobStoreApiSoftQuota createSoftQuota(final BlobStoreConfiguration configuration) {
final NestedAttributesMap softQuotaAttributes = configuration.attributes(ROOT_KEY);
if (!softQuotaAttributes.isEmpty()) {
final BlobStoreApiSoftQuota blobStoreApiSoftQuota = new BlobStoreApiSoftQuota();
final String quotaType = getValue(softQuotaAttributes, TYPE_KEY);
final String quotaLimit = getValue(softQuotaAttributes, LIMIT_KEY);
if (nonNull(quotaType) && nonNull(quotaLimit)) {
blobStoreApiSoftQuota.setType(quotaType);
blobStoreApiSoftQuota.setLimit(parseLong(quotaLimit) / ONE_MILLION);
return blobStoreApiSoftQuota;
}
}
return null;
}
@Transactional
@Override
public Optional<BlobStoreConfiguration> findParent(final String name) {
return dao().findCandidateParents(name).stream()
.filter(config -> memberNames(config).contains(name))
.findFirst();
}
@POST
@Override
@RequiresAuthentication
@RequiresPermissions("nexus:blobstores:create")
public Response createBlobStore(@Valid final S3BlobStoreApiModel request) throws Exception {
final BlobStoreConfiguration blobStoreConfiguration = MODEL_MAPPER.apply(blobStoreManager.newConfiguration(), request);
blobStoreManager.create(blobStoreConfiguration);
return status(CREATED).build();
}
private BlobStoreConfiguration ensureBlobStoreTypeIsS3(BlobStoreConfiguration configuration) {
final String type = configuration.getType();
if (!equalsIgnoreCase(TYPE, type)) {
throw new WebApplicationMessageException(BAD_REQUEST,
String.format(NOT_AN_S3_BLOB_STORE_MSG_FORMAT, configuration.getName()), APPLICATION_JSON);
}
return configuration;
}
private boolean existingBlobStoreIsNotS3(final String blobStoreName) {
return !ofNullable(blobStoreManager.get(blobStoreName))
.map(BlobStore::getBlobStoreConfiguration)
.map(BlobStoreConfiguration::getType)
.filter(type -> equalsIgnoreCase(TYPE, type))
.isPresent();
}
@Override
@Guarded(by = STARTED)
public void create(final BlobStoreConfiguration configuration) {
checkBlobStoreConfiguration(configuration);
inTxRetry(databaseInstance).run(db -> entityAdapter.addEntity(db, (OrientBlobStoreConfiguration) configuration));
}
private boolean isExpirationLifecycleConfigurationPresent(final BucketLifecycleConfiguration lifecycleConfiguration,
final BlobStoreConfiguration blobStoreConfiguration) {
String bucketPrefix = getBucketPrefix(blobStoreConfiguration);
int expirationInDays = getConfiguredExpirationInDays(blobStoreConfiguration);
return lifecycleConfiguration != null &&
lifecycleConfiguration.getRules() != null &&
lifecycleConfiguration.getRules().stream()
.filter(r -> r.getExpirationInDays() == expirationInDays)
.anyMatch(r -> isDeletedTagPredicate(r.getFilter().getPredicate(), bucketPrefix));
}