http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/ExtensionService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/ExtensionService.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/ExtensionService.java new file mode 100644 index 0000000..3ab8a07 --- /dev/null +++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/ExtensionService.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.registry.service.extension; + +import org.apache.nifi.registry.bucket.Bucket; +import org.apache.nifi.registry.extension.ExtensionBundle; +import org.apache.nifi.registry.extension.ExtensionBundleType; +import org.apache.nifi.registry.extension.ExtensionBundleVersion; +import org.apache.nifi.registry.extension.ExtensionBundleVersionMetadata; +import org.apache.nifi.registry.extension.repo.ExtensionRepoArtifact; +import org.apache.nifi.registry.extension.repo.ExtensionRepoBucket; +import org.apache.nifi.registry.extension.repo.ExtensionRepoGroup; +import org.apache.nifi.registry.extension.repo.ExtensionRepoVersionSummary; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.List; +import java.util.Set; +import java.util.SortedSet; + +public interface ExtensionService { + + /** + * Creates a version of an extension bundle. + * + * The InputStream is expected to contain the binary contents of a bundle in the format specified by bundleType. + * + * The metadata will be extracted from the bundle and used to determine if this is a new version of an existing bundle, + * or it will create a new bundle and this as the first version if one doesn't already exist. + * + * @param bucketIdentifier the bucket id + * @param bundleType the type of bundle + * @param inputStream the binary content of the bundle + * @param clientSha256 the SHA-256 hex supplied by the client + * @return the ExtensionBundleVersion representing all of the information about the bundle + * @throws IOException if an error occurs processing the InputStream + */ + ExtensionBundleVersion createExtensionBundleVersion(String bucketIdentifier, ExtensionBundleType bundleType, + InputStream inputStream, String clientSha256) throws IOException; + + /** + * Retrieves the extension bundles in the given buckets. + * + * @param bucketIdentifiers the bucket identifiers + * @return the bundles in the given buckets + */ + List<ExtensionBundle> getExtensionBundles(Set<String> bucketIdentifiers); + + /** + * Retrieves the extension bundles in the given bucket. + * + * @param bucketIdentifier the bucket identifier + * @return the bundles in the given bucket + */ + List<ExtensionBundle> getExtensionBundlesByBucket(String bucketIdentifier); + + /** + * Retrieve the extension bundle with the given id. + * + * @param extensionBundleIdentifier the extension bundle id + * @return the bundle + */ + ExtensionBundle getExtensionBundle(String extensionBundleIdentifier); + + /** + * Deletes the given extension bundle and all it's versions. + * + * @param extensionBundle the extension bundle to delete + * @return the deleted bundle + */ + ExtensionBundle deleteExtensionBundle(ExtensionBundle extensionBundle); + + /** + * Retrieves the versions of the given extension bundle. + * + * @param extensionBundleIdentifier the extension bundle id + * @return the sorted set of versions for the given bundle + */ + SortedSet<ExtensionBundleVersionMetadata> getExtensionBundleVersions(String extensionBundleIdentifier); + + /** + * Retrieves the full ExtensionBundleVersion object, including version metadata, bundle metadata, and bucket metadata. + * + * @param versionCoordinate the coordinate of the version + * @return the extension bundle version + */ + ExtensionBundleVersion getExtensionBundleVersion(ExtensionBundleVersionCoordinate versionCoordinate); + + /** + * Writes the binary content of the extension bundle version to the given OutputStream. + * + * @param extensionBundleVersion the version to write the content for + * @param out the output stream to write to + */ + void writeExtensionBundleVersionContent(ExtensionBundleVersion extensionBundleVersion, OutputStream out); + + /** + * Deletes the given version of the extension bundle. + * + * @param bundleVersion the version to delete + * @return the deleted extension bundle version + */ + ExtensionBundleVersion deleteExtensionBundleVersion(ExtensionBundleVersion bundleVersion); + + // ----- Extension Repo Methods ----- + + SortedSet<ExtensionRepoBucket> getExtensionRepoBuckets(Set<String> bucketIds); + + SortedSet<ExtensionRepoGroup> getExtensionRepoGroups(Bucket bucket); + + SortedSet<ExtensionRepoArtifact> getExtensionRepoArtifacts(Bucket bucket, String groupId); + + SortedSet<ExtensionRepoVersionSummary> getExtensionRepoVersions(Bucket bucket, String groupId, String artifactId); + +}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/StandardExtensionService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/StandardExtensionService.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/StandardExtensionService.java new file mode 100644 index 0000000..e737b75 --- /dev/null +++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/extension/StandardExtensionService.java @@ -0,0 +1,620 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.registry.service.extension; + +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.Validate; +import org.apache.nifi.registry.bucket.Bucket; +import org.apache.nifi.registry.db.entity.BucketEntity; +import org.apache.nifi.registry.db.entity.ExtensionBundleEntity; +import org.apache.nifi.registry.db.entity.ExtensionBundleEntityType; +import org.apache.nifi.registry.db.entity.ExtensionBundleVersionDependencyEntity; +import org.apache.nifi.registry.db.entity.ExtensionBundleVersionEntity; +import org.apache.nifi.registry.exception.ResourceNotFoundException; +import org.apache.nifi.registry.extension.BundleCoordinate; +import org.apache.nifi.registry.extension.BundleDetails; +import org.apache.nifi.registry.extension.BundleExtractor; +import org.apache.nifi.registry.extension.ExtensionBundle; +import org.apache.nifi.registry.extension.ExtensionBundleContext; +import org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider; +import org.apache.nifi.registry.extension.ExtensionBundleType; +import org.apache.nifi.registry.extension.ExtensionBundleVersion; +import org.apache.nifi.registry.extension.ExtensionBundleVersionDependency; +import org.apache.nifi.registry.extension.ExtensionBundleVersionMetadata; +import org.apache.nifi.registry.extension.repo.ExtensionRepoArtifact; +import org.apache.nifi.registry.extension.repo.ExtensionRepoBucket; +import org.apache.nifi.registry.extension.repo.ExtensionRepoGroup; +import org.apache.nifi.registry.extension.repo.ExtensionRepoVersionSummary; +import org.apache.nifi.registry.properties.NiFiRegistryProperties; +import org.apache.nifi.registry.provider.extension.StandardExtensionBundleContext; +import org.apache.nifi.registry.security.authorization.user.NiFiUserUtils; +import org.apache.nifi.registry.service.DataModelMapper; +import org.apache.nifi.registry.service.MetadataService; +import org.apache.nifi.registry.util.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import javax.validation.ConstraintViolation; +import javax.validation.ConstraintViolationException; +import javax.validation.Validator; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.security.DigestInputStream; +import java.security.MessageDigest; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedSet; +import java.util.TreeSet; +import java.util.UUID; +import java.util.stream.Collectors; + +@Service +public class StandardExtensionService implements ExtensionService { + + private static final Logger LOGGER = LoggerFactory.getLogger(StandardExtensionService.class); + + private final MetadataService metadataService; + private final Map<ExtensionBundleType, BundleExtractor> extractors; + private final ExtensionBundlePersistenceProvider bundlePersistenceProvider; + private final Validator validator; + private final File extensionsWorkingDir; + + @Autowired + public StandardExtensionService(final MetadataService metadataService, + final Map<ExtensionBundleType, BundleExtractor> extractors, + final ExtensionBundlePersistenceProvider bundlePersistenceProvider, + final Validator validator, + final NiFiRegistryProperties properties) { + this.metadataService = metadataService; + this.extractors = extractors; + this.bundlePersistenceProvider = bundlePersistenceProvider; + this.validator = validator; + this.extensionsWorkingDir = properties.getExtensionsWorkingDirectory(); + Validate.notNull(this.metadataService); + Validate.notNull(this.extractors); + Validate.notNull(this.bundlePersistenceProvider); + Validate.notNull(this.validator); + Validate.notNull(this.extensionsWorkingDir); + } + + private <T> void validate(T t, String invalidMessage) { + final Set<ConstraintViolation<T>> violations = validator.validate(t); + if (violations.size() > 0) { + throw new ConstraintViolationException(invalidMessage, violations); + } + } + + @Override + public ExtensionBundleVersion createExtensionBundleVersion(final String bucketIdentifier, final ExtensionBundleType bundleType, + final InputStream inputStream, final String clientSha256) throws IOException { + if (StringUtils.isBlank(bucketIdentifier)) { + throw new IllegalArgumentException("Bucket identifier cannot be null or blank"); + } + + if (bundleType == null) { + throw new IllegalArgumentException("Bundle type cannot be null"); + } + + if (inputStream == null) { + throw new IllegalArgumentException("Extension bundle input stream cannot be null"); + } + + if (!extractors.containsKey(bundleType)) { + throw new IllegalArgumentException("No metadata extractor is registered for bundle-type: " + bundleType); + } + + // ensure the bucket exists + final BucketEntity existingBucket = metadataService.getBucketById(bucketIdentifier); + if (existingBucket == null) { + LOGGER.warn("The specified bucket id [{}] does not exist.", bucketIdentifier); + throw new ResourceNotFoundException("The specified bucket ID does not exist in this registry."); + } + + // ensure the extensions directory exists and we can read and write to it + FileUtils.ensureDirectoryExistAndCanReadAndWrite(extensionsWorkingDir); + + final String extensionWorkingFilename = UUID.randomUUID().toString(); + final File extensionWorkingFile = new File(extensionsWorkingDir, extensionWorkingFilename); + LOGGER.debug("Writing bundle contents to working directory at {}", new Object[]{extensionWorkingFile.getAbsolutePath()}); + + try { + // write the contents of the input stream to a temporary file in the extensions working directory + final MessageDigest sha256Digest = DigestUtils.getSha256Digest(); + try (final DigestInputStream digestInputStream = new DigestInputStream(inputStream, sha256Digest); + final OutputStream out = new FileOutputStream(extensionWorkingFile)) { + IOUtils.copy(digestInputStream, out); + } + + // get the hex of the SHA-256 computed by the server and compare to the client provided SHA-256, if one was provided + final String sha256Hex = Hex.encodeHexString(sha256Digest.digest()); + final boolean sha256Supplied = !StringUtils.isBlank(clientSha256); + if (sha256Supplied && !sha256Hex.equalsIgnoreCase(clientSha256)) { + LOGGER.error("Client provided SHA-256 of '{}', but server calculated '{}'", new Object[]{clientSha256, sha256Hex}); + throw new IllegalStateException("The SHA-256 of the received extension bundle does not match the SHA-256 provided by the client"); + } + + // extract the details of the bundle from the temp file in the working directory + final BundleDetails bundleDetails; + try (final InputStream in = new FileInputStream(extensionWorkingFile)) { + final BundleExtractor extractor = extractors.get(bundleType); + bundleDetails = extractor.extract(in); + } + + final BundleCoordinate bundleCoordinate = bundleDetails.getBundleCoordinate(); + final Set<BundleCoordinate> dependencyCoordinates = bundleDetails.getDependencyBundleCoordinates(); + + final String groupId = bundleCoordinate.getGroupId(); + final String artifactId = bundleCoordinate.getArtifactId(); + final String version = bundleCoordinate.getVersion(); + LOGGER.debug("Extracted bundle details - '{}' - '{}' - '{}'", new Object[]{groupId, artifactId, version}); + + // a bundle with the same group, artifact, and version can exist in multiple buckets, but only if it contains the same binary content, + // we can determine that by comparing the SHA-256 digest of the incoming bundle against existing bundles with the same group, artifact, version + final List<ExtensionBundleVersionEntity> allExistingVersions = metadataService.getExtensionBundleVersionsGlobal(groupId, artifactId, version); + for (final ExtensionBundleVersionEntity existingVersionEntity : allExistingVersions) { + if (!existingVersionEntity.getSha256Hex().equals(sha256Hex)) { + throw new IllegalStateException("Found existing extension bundle with same group, artifact, and version, but different SHA-256 check-sum"); + } + } + + // get the existing extension bundle entity, or create a new one if one does not exist in the bucket with the group + artifact + final long currentTime = System.currentTimeMillis(); + final ExtensionBundleEntity extensionBundle = getOrCreateExtensionBundle(bucketIdentifier, groupId, artifactId, bundleType, currentTime); + + // ensure there isn't already a version of the bundle with the same version + final ExtensionBundleVersionEntity existingVersion = metadataService.getExtensionBundleVersion(bucketIdentifier, groupId, artifactId, version); + if (existingVersion != null) { + LOGGER.warn("The specified version [{}] already exists for extension bundle [{}].", new Object[]{version, extensionBundle.getId()}); + throw new IllegalStateException("The specified version already exists for the given extension bundle"); + } + + // create the version metadata instance and validate it has all the required fields + final String userIdentity = NiFiUserUtils.getNiFiUserIdentity(); + final ExtensionBundleVersionMetadata versionMetadata = new ExtensionBundleVersionMetadata(); + versionMetadata.setId(UUID.randomUUID().toString()); + versionMetadata.setExtensionBundleId(extensionBundle.getId()); + versionMetadata.setBucketId(bucketIdentifier); + versionMetadata.setVersion(version); + versionMetadata.setTimestamp(currentTime); + versionMetadata.setAuthor(userIdentity); + versionMetadata.setSha256(sha256Hex); + versionMetadata.setSha256Supplied(sha256Supplied); + + validate(versionMetadata, "Cannot create extension bundle version"); + + // create the version dependency instances and validate they have the required fields + final Set<ExtensionBundleVersionDependency> versionDependencies = new HashSet<>(); + for (final BundleCoordinate dependencyCoordinate : dependencyCoordinates) { + final ExtensionBundleVersionDependency versionDependency = new ExtensionBundleVersionDependency(); + versionDependency.setGroupId(dependencyCoordinate.getGroupId()); + versionDependency.setArtifactId(dependencyCoordinate.getArtifactId()); + versionDependency.setVersion(dependencyCoordinate.getVersion()); + + validate(versionDependency, "Cannot create extension bundle version dependency"); + versionDependencies.add(versionDependency); + } + + // create the bundle version in the metadata db + final ExtensionBundleVersionEntity versionEntity = DataModelMapper.map(versionMetadata); + metadataService.createExtensionBundleVersion(versionEntity); + + // create the bundle version dependencies in the metadata db + for (final ExtensionBundleVersionDependency versionDependency : versionDependencies) { + final ExtensionBundleVersionDependencyEntity versionDependencyEntity = DataModelMapper.map(versionDependency); + versionDependencyEntity.setId(UUID.randomUUID().toString()); + versionDependencyEntity.setExtensionBundleVersionId(versionEntity.getId()); + metadataService.createDependency(versionDependencyEntity); + } + + // persist the content of the bundle to the persistence provider + final ExtensionBundleContext context = new StandardExtensionBundleContext.Builder() + .bundleType(getProviderBundleType(bundleType)) + .bucketId(existingBucket.getId()) + .bucketName(existingBucket.getName()) + .bundleId(extensionBundle.getId()) + .bundleGroupId(extensionBundle.getGroupId()) + .bundleArtifactId(extensionBundle.getArtifactId()) + .bundleVersion(versionMetadata.getVersion()) + .author(versionMetadata.getAuthor()) + .timestamp(versionMetadata.getTimestamp()) + .build(); + + try (final InputStream in = new FileInputStream(extensionWorkingFile); + final InputStream bufIn = new BufferedInputStream(in)) { + bundlePersistenceProvider.saveBundleVersion(context, bufIn); + LOGGER.debug("Bundle saved to persistence provider - '{}' - '{}' - '{}'", + new Object[]{groupId, artifactId, version}); + } + + // get the updated extension bundle so it contains the correct version count + final ExtensionBundleEntity updatedBundle = metadataService.getExtensionBundle(bucketIdentifier, groupId, artifactId); + + // create the full ExtensionBundleVersion instance to return + final ExtensionBundleVersion extensionBundleVersion = new ExtensionBundleVersion(); + extensionBundleVersion.setVersionMetadata(versionMetadata); + extensionBundleVersion.setExtensionBundle(DataModelMapper.map(existingBucket, updatedBundle)); + extensionBundleVersion.setBucket(DataModelMapper.map(existingBucket)); + extensionBundleVersion.setDependencies(versionDependencies); + return extensionBundleVersion; + + } finally { + if (extensionWorkingFile.exists()) { + try { + extensionWorkingFile.delete(); + } catch (Exception e) { + LOGGER.warn("Error removing temporary extension bundle file at {}", + new Object[]{extensionWorkingFile.getAbsolutePath()}); + } + } + } + } + + private ExtensionBundleEntity getOrCreateExtensionBundle(final String bucketId, final String groupId, + final String artifactId, final ExtensionBundleType bundleType, + final long currentTime) { + ExtensionBundleEntity existingBundleEntity = metadataService.getExtensionBundle(bucketId, groupId, artifactId); + if (existingBundleEntity == null) { + final ExtensionBundle bundle = new ExtensionBundle(); + bundle.setIdentifier(UUID.randomUUID().toString()); + bundle.setBucketIdentifier(bucketId); + bundle.setName(groupId + ":" + artifactId); + bundle.setGroupId(groupId); + bundle.setArtifactId(artifactId); + bundle.setBundleType(bundleType); + bundle.setCreatedTimestamp(currentTime); + bundle.setModifiedTimestamp(currentTime); + + validate(bundle, "Cannot create extension bundle"); + existingBundleEntity = metadataService.createExtensionBundle(DataModelMapper.map(bundle)); + } else { + final ExtensionBundleEntityType bundleEntityType = DataModelMapper.map(bundleType); + if (bundleEntityType != existingBundleEntity.getBundleType()) { + throw new IllegalStateException("A bundle already exists with the same group id and artifact id, but a different bundle type"); + } + } + + return existingBundleEntity; + } + + private ExtensionBundleContext.BundleType getProviderBundleType(final ExtensionBundleType bundleType) { + switch (bundleType) { + case NIFI_NAR: + return ExtensionBundleContext.BundleType.NIFI_NAR; + case MINIFI_CPP: + return ExtensionBundleContext.BundleType.MINIFI_CPP; + default: + throw new IllegalArgumentException("Unknown bundle type: " + bundleType.toString()); + } + } + + @Override + public List<ExtensionBundle> getExtensionBundles(Set<String> bucketIdentifiers) { + if (bucketIdentifiers == null) { + throw new IllegalArgumentException("Bucket identifiers cannot be null"); + } + + final List<ExtensionBundleEntity> bundleEntities = metadataService.getExtensionBundles(bucketIdentifiers); + return bundleEntities.stream().map(b -> DataModelMapper.map(null, b)).collect(Collectors.toList()); + } + + @Override + public List<ExtensionBundle> getExtensionBundlesByBucket(final String bucketIdentifier) { + if (StringUtils.isBlank(bucketIdentifier)) { + throw new IllegalArgumentException("Bucket identifier cannot be null or blank"); + } + + // ensure the bucket exists + final BucketEntity existingBucket = metadataService.getBucketById(bucketIdentifier); + if (existingBucket == null) { + LOGGER.warn("The specified bucket id [{}] does not exist.", bucketIdentifier); + throw new ResourceNotFoundException("The specified bucket ID does not exist in this registry."); + } + + final List<ExtensionBundleEntity> bundleEntities = metadataService.getExtensionBundlesByBucket(bucketIdentifier); + return bundleEntities.stream().map(b -> DataModelMapper.map(existingBucket, b)).collect(Collectors.toList()); + } + + @Override + public ExtensionBundle getExtensionBundle(final String extensionBundleIdentifier) { + if (StringUtils.isBlank(extensionBundleIdentifier)) { + throw new IllegalArgumentException("Extension bundle identifier cannot be null or blank"); + } + + final ExtensionBundleEntity existingBundle = metadataService.getExtensionBundle(extensionBundleIdentifier); + if (existingBundle == null) { + LOGGER.warn("The specified extension bundle id [{}] does not exist.", extensionBundleIdentifier); + throw new ResourceNotFoundException("The specified extension bundle ID does not exist."); + } + + final BucketEntity existingBucket = metadataService.getBucketById(existingBundle.getBucketId()); + return DataModelMapper.map(existingBucket, existingBundle); + } + + @Override + public ExtensionBundle deleteExtensionBundle(final ExtensionBundle extensionBundle) { + if (extensionBundle == null) { + throw new IllegalArgumentException("Extension bundle cannot be null"); + } + + // delete the bundle from the database + metadataService.deleteExtensionBundle(extensionBundle.getIdentifier()); + + // delete all content associated with the bundle in the persistence provider + bundlePersistenceProvider.deleteAllBundleVersions( + extensionBundle.getBucketIdentifier(), + extensionBundle.getBucketName(), + extensionBundle.getGroupId(), + extensionBundle.getArtifactId()); + + return extensionBundle; + } + + @Override + public SortedSet<ExtensionBundleVersionMetadata> getExtensionBundleVersions(final String extensionBundleIdentifier) { + if (StringUtils.isBlank(extensionBundleIdentifier)) { + throw new IllegalArgumentException("Extension bundle identifier cannot be null or blank"); + } + + // ensure the bundle exists + final ExtensionBundleEntity existingBundle = metadataService.getExtensionBundle(extensionBundleIdentifier); + if (existingBundle == null) { + LOGGER.warn("The specified extension bundle id [{}] does not exist.", extensionBundleIdentifier); + throw new ResourceNotFoundException("The specified extension bundle ID does not exist in this bucket."); + } + + return getExtensionBundleVersionsSet(existingBundle); + } + + private SortedSet<ExtensionBundleVersionMetadata> getExtensionBundleVersionsSet(ExtensionBundleEntity existingBundle) { + final SortedSet<ExtensionBundleVersionMetadata> sortedVersions = new TreeSet<>(Collections.reverseOrder()); + + final List<ExtensionBundleVersionEntity> existingVersions = metadataService.getExtensionBundleVersions(existingBundle.getId()); + if (existingVersions != null) { + final BucketEntity existingBucket = metadataService.getBucketById(existingBundle.getBucketId()); + existingVersions.stream().forEach(s -> sortedVersions.add(DataModelMapper.map(existingBucket, s))); + } + + return sortedVersions; + } + + @Override + public ExtensionBundleVersion getExtensionBundleVersion(ExtensionBundleVersionCoordinate versionCoordinate) { + if (versionCoordinate == null) { + throw new IllegalArgumentException("Extension bundle version coordinate cannot be null"); + } + + // ensure the bucket exists + final BucketEntity existingBucket = metadataService.getBucketById(versionCoordinate.getBucketId()); + if (existingBucket == null) { + LOGGER.warn("The specified bucket id [{}] does not exist.", versionCoordinate.getBucketId()); + throw new ResourceNotFoundException("The specified bucket ID does not exist in this registry."); + } + + // ensure the bundle exists + final ExtensionBundleEntity existingBundle = metadataService.getExtensionBundle( + versionCoordinate.getBucketId(), + versionCoordinate.getGroupId(), + versionCoordinate.getArtifactId()); + + if (existingBundle == null) { + LOGGER.warn("The specified extension bundle [{}] does not exist.", versionCoordinate.toString()); + throw new ResourceNotFoundException("The specified extension bundle does not exist in this bucket."); + } + + //ensure the version of the bundle exists + final ExtensionBundleVersionEntity existingVersion = metadataService.getExtensionBundleVersion( + versionCoordinate.getBucketId(), + versionCoordinate.getGroupId(), + versionCoordinate.getArtifactId(), + versionCoordinate.getVersion()); + + if (existingVersion == null) { + LOGGER.warn("The specified extension bundle version [{}] does not exist.", versionCoordinate.toString()); + throw new ResourceNotFoundException("The specified extension bundle version does not exist in this bucket."); + } + + // get the dependencies for the bundle version + final List<ExtensionBundleVersionDependencyEntity> existingVersionDependencies = metadataService + .getDependenciesForBundleVersion(existingVersion.getId()); + + // convert the dependency db entities + final Set<ExtensionBundleVersionDependency> dependencies = existingVersionDependencies.stream() + .map(d -> DataModelMapper.map(d)) + .collect(Collectors.toSet()); + + // create the full ExtensionBundleVersion instance to return + final ExtensionBundleVersion extensionBundleVersion = new ExtensionBundleVersion(); + extensionBundleVersion.setVersionMetadata(DataModelMapper.map(existingBucket, existingVersion)); + extensionBundleVersion.setExtensionBundle(DataModelMapper.map(existingBucket, existingBundle)); + extensionBundleVersion.setBucket(DataModelMapper.map(existingBucket)); + extensionBundleVersion.setDependencies(dependencies); + return extensionBundleVersion; + } + + @Override + public void writeExtensionBundleVersionContent(final ExtensionBundleVersion bundleVersion, final OutputStream out) { + // get the content from the persistence provider and write it to the output stream + final ExtensionBundleContext context = getExtensionBundleContext(bundleVersion); + bundlePersistenceProvider.getBundleVersion(context, out); + } + + @Override + public ExtensionBundleVersion deleteExtensionBundleVersion(final ExtensionBundleVersion bundleVersion) { + if (bundleVersion == null) { + throw new IllegalArgumentException("Extension bundle version cannot be null"); + } + + // delete from the metadata db + final String extensionBundleVersionId = bundleVersion.getVersionMetadata().getId(); + metadataService.deleteExtensionBundleVersion(extensionBundleVersionId); + + // delete content associated with the bundle version in the persistence provider + final ExtensionBundleContext context = new StandardExtensionBundleContext.Builder() + .bundleType(getProviderBundleType(bundleVersion.getExtensionBundle().getBundleType())) + .bucketId(bundleVersion.getBucket().getIdentifier()) + .bucketName(bundleVersion.getBucket().getName()) + .bundleId(bundleVersion.getExtensionBundle().getIdentifier()) + .bundleGroupId(bundleVersion.getExtensionBundle().getGroupId()) + .bundleArtifactId(bundleVersion.getExtensionBundle().getArtifactId()) + .bundleVersion(bundleVersion.getVersionMetadata().getVersion()) + .author(bundleVersion.getVersionMetadata().getAuthor()) + .timestamp(bundleVersion.getVersionMetadata().getTimestamp()) + .build(); + + bundlePersistenceProvider.deleteBundleVersion(context); + + return bundleVersion; + } + + // ------ Extension Repository Methods ------- + + @Override + public SortedSet<ExtensionRepoBucket> getExtensionRepoBuckets(final Set<String> bucketIds) { + if (bucketIds == null) { + throw new IllegalArgumentException("Bucket ids cannot be null"); + } + + if (bucketIds.isEmpty()) { + return new TreeSet<>(); + } + + final SortedSet<ExtensionRepoBucket> repoBuckets = new TreeSet<>(); + + final List<BucketEntity> buckets = metadataService.getBuckets(bucketIds); + buckets.forEach(b -> { + final ExtensionRepoBucket repoBucket = new ExtensionRepoBucket(); + repoBucket.setBucketName(b.getName()); + repoBuckets.add(repoBucket); + }); + + return repoBuckets; + } + + @Override + public SortedSet<ExtensionRepoGroup> getExtensionRepoGroups(final Bucket bucket) { + if (bucket == null) { + throw new IllegalArgumentException("Bucket cannot be null"); + } + + final SortedSet<ExtensionRepoGroup> repoGroups = new TreeSet<>(); + + final List<ExtensionBundleEntity> bundleEntities = metadataService.getExtensionBundlesByBucket(bucket.getIdentifier()); + bundleEntities.forEach(b -> { + final ExtensionRepoGroup repoGroup = new ExtensionRepoGroup(); + repoGroup.setBucketName(bucket.getName()); + repoGroup.setGroupId(b.getGroupId()); + repoGroups.add(repoGroup); + }); + + return repoGroups; + } + + @Override + public SortedSet<ExtensionRepoArtifact> getExtensionRepoArtifacts(final Bucket bucket, final String groupId) { + if (bucket == null) { + throw new IllegalArgumentException("Bucket cannot be null"); + } + + if (StringUtils.isBlank(groupId)) { + throw new IllegalArgumentException("Group id cannot be null or blank"); + } + + final SortedSet<ExtensionRepoArtifact> repoArtifacts = new TreeSet<>(); + + final List<ExtensionBundleEntity> bundleEntities = metadataService.getExtensionBundlesByBucketAndGroup(bucket.getIdentifier(), groupId); + bundleEntities.forEach(b -> { + final ExtensionRepoArtifact repoArtifact = new ExtensionRepoArtifact(); + repoArtifact.setBucketName(bucket.getName()); + repoArtifact.setGroupId(b.getGroupId()); + repoArtifact.setArtifactId(b.getArtifactId()); + repoArtifacts.add(repoArtifact); + }); + + return repoArtifacts; + } + + @Override + public SortedSet<ExtensionRepoVersionSummary> getExtensionRepoVersions(final Bucket bucket, final String groupId, final String artifactId) { + if (bucket == null) { + throw new IllegalArgumentException("Bucket cannot be null"); + } + + if (StringUtils.isBlank(groupId)) { + throw new IllegalArgumentException("Group id cannot be null or blank"); + } + + if (StringUtils.isBlank(artifactId)) { + throw new IllegalArgumentException("Artifact id cannot be null or blank"); + } + + final SortedSet<ExtensionRepoVersionSummary> repoVersions = new TreeSet<>(); + + final List<ExtensionBundleVersionEntity> versionEntities = metadataService.getExtensionBundleVersions(bucket.getIdentifier(), groupId, artifactId); + if (!versionEntities.isEmpty()) { + final ExtensionBundleEntity bundleEntity = metadataService.getExtensionBundle(bucket.getIdentifier(), groupId, artifactId); + if (bundleEntity == null) { + // should never happen if the list of versions is not empty, but just in case + throw new ResourceNotFoundException("The specified extension bundle does not exist in this bucket"); + } + + versionEntities.forEach(v -> { + final ExtensionRepoVersionSummary repoVersion = new ExtensionRepoVersionSummary(); + repoVersion.setBucketName(bucket.getName()); + repoVersion.setGroupId(bundleEntity.getGroupId()); + repoVersion.setArtifactId(bundleEntity.getArtifactId()); + repoVersion.setVersion(v.getVersion()); + repoVersions.add(repoVersion); + }); + } + + return repoVersions; + } + + // ------ Helper Methods ------- + + private ExtensionBundleContext getExtensionBundleContext(final ExtensionBundleVersion bundleVersion) { + return getExtensionBundleContext(bundleVersion.getBucket(), bundleVersion.getExtensionBundle(), bundleVersion.getVersionMetadata()); + } + + private ExtensionBundleContext getExtensionBundleContext(final Bucket bucket, final ExtensionBundle bundle, + final ExtensionBundleVersionMetadata bundleVersionMetadata) { + return new StandardExtensionBundleContext.Builder() + .bundleType(getProviderBundleType(bundle.getBundleType())) + .bucketId(bucket.getIdentifier()) + .bucketName(bucket.getName()) + .bundleId(bundle.getIdentifier()) + .bundleGroupId(bundle.getGroupId()) + .bundleArtifactId(bundle.getArtifactId()) + .bundleVersion(bundleVersionMetadata.getVersion()) + .author(bundleVersionMetadata.getAuthor()) + .timestamp(bundleVersionMetadata.getTimestamp()) + .build(); + } +} http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/main/resources/META-INF/services/org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/main/resources/META-INF/services/org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider b/nifi-registry-core/nifi-registry-framework/src/main/resources/META-INF/services/org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider new file mode 100644 index 0000000..00dcbb8 --- /dev/null +++ b/nifi-registry-core/nifi-registry-framework/src/main/resources/META-INF/services/org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider @@ -0,0 +1,15 @@ +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +org.apache.nifi.registry.provider.extension.FileSystemExtensionBundlePersistenceProvider \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V3__AddExtensions.sql ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V3__AddExtensions.sql b/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V3__AddExtensions.sql new file mode 100644 index 0000000..da66cd1 --- /dev/null +++ b/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V3__AddExtensions.sql @@ -0,0 +1,71 @@ +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +CREATE TABLE EXTENSION_BUNDLE ( + ID VARCHAR(50) NOT NULL, + BUCKET_ID VARCHAR(50) NOT NULL, + BUNDLE_TYPE VARCHAR(200) NOT NULL, + GROUP_ID VARCHAR(500) NOT NULL, + ARTIFACT_ID VARCHAR(500) NOT NULL, + CONSTRAINT PK__EXTENSION_BUNDLE_ID PRIMARY KEY (ID), + CONSTRAINT FK__EXTENSION_BUNDLE_BUCKET_ITEM_ID FOREIGN KEY (ID) REFERENCES BUCKET_ITEM(ID) ON DELETE CASCADE, + CONSTRAINT FK__EXTENSION_BUNDLE_BUCKET_ID FOREIGN KEY(BUCKET_ID) REFERENCES BUCKET(ID) ON DELETE CASCADE, + CONSTRAINT UNIQUE__EXTENSION_BUNDLE_BUCKET_GROUP_ARTIFACT UNIQUE (BUCKET_ID, GROUP_ID, ARTIFACT_ID) +); + +CREATE TABLE EXTENSION_BUNDLE_VERSION ( + ID VARCHAR(50) NOT NULL, + EXTENSION_BUNDLE_ID VARCHAR(50) NOT NULL, + VERSION VARCHAR(100) NOT NULL, + CREATED TIMESTAMP NOT NULL, + CREATED_BY VARCHAR(4096) NOT NULL, + DESCRIPTION TEXT, + SHA_256_HEX VARCHAR(512) NOT NULL, + SHA_256_SUPPLIED INT NOT NULL, + CONSTRAINT PK__EXTENSION_BUNDLE_VERSION_ID PRIMARY KEY (ID), + CONSTRAINT FK__EXTENSION_BUNDLE_VERSION_EXTENSION_BUNDLE_ID FOREIGN KEY (EXTENSION_BUNDLE_ID) REFERENCES EXTENSION_BUNDLE(ID) ON DELETE CASCADE, + CONSTRAINT UNIQUE__EXTENSION_BUNDLE_VERSION_EXTENSION_BUNDLE_ID_VERSION UNIQUE (EXTENSION_BUNDLE_ID, VERSION) +); + +CREATE TABLE EXTENSION_BUNDLE_VERSION_DEPENDENCY ( + ID VARCHAR(50) NOT NULL, + EXTENSION_BUNDLE_VERSION_ID VARCHAR(50) NOT NULL, + GROUP_ID VARCHAR(500) NOT NULL, + ARTIFACT_ID VARCHAR(500) NOT NULL, + VERSION VARCHAR(100) NOT NULL, + CONSTRAINT PK__EXTENSION_BUNDLE_VERSION_DEPENDENCY_ID PRIMARY KEY (ID), + CONSTRAINT FK__EXTENSION_BUNDLE_VERSION_DEPENDENCY_EXTENSION_BUNDLE_VERSION_ID FOREIGN KEY (EXTENSION_BUNDLE_VERSION_ID) REFERENCES EXTENSION_BUNDLE_VERSION(ID) ON DELETE CASCADE, + CONSTRAINT UNIQUE__EXTENSION_BUNDLE_VERSION_DEPENDENCY_BUNDLE_ID_GROUP_ARTIFACT_VERSION UNIQUE (EXTENSION_BUNDLE_VERSION_ID, GROUP_ID, ARTIFACT_ID, VERSION) +); + +CREATE TABLE EXTENSION ( + ID VARCHAR(50) NOT NULL, + EXTENSION_BUNDLE_VERSION_ID VARCHAR(50) NOT NULL, + TYPE VARCHAR(500) NOT NULL, + TYPE_DESCRIPTION TEXT NOT NULL, + IS_RESTRICTED INT NOT NULL, + CATEGORY VARCHAR(100) NOT NULL, + TAGS TEXT, + CONSTRAINT PK__EXTENSION_ID PRIMARY KEY (ID), + CONSTRAINT FK__EXTENSION_EXTENSION_BUNDLE_VERSION_ID FOREIGN KEY (EXTENSION_BUNDLE_VERSION_ID) REFERENCES EXTENSION_BUNDLE_VERSION(ID) ON DELETE CASCADE, + CONSTRAINT UNIQUE__EXTENSION_EXTENSION_BUNDLE_VERSION_ID_AND_TYPE UNIQUE (EXTENSION_BUNDLE_VERSION_ID, TYPE) +); + +CREATE TABLE EXTENSION_TAG ( + EXTENSION_ID VARCHAR(50) NOT NULL, + TAG VARCHAR(200) NOT NULL, + CONSTRAINT PK__EXTENSION_TAG_EXTENSION_ID_AND_TAG PRIMARY KEY (EXTENSION_ID, TAG), + CONSTRAINT FK__EXTENSION_TAG_EXTENSION_ID FOREIGN KEY (EXTENSION_ID) REFERENCES EXTENSION(ID) ON DELETE CASCADE +); \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V4__AddCascadeOnDelete.sql ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V4__AddCascadeOnDelete.sql b/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V4__AddCascadeOnDelete.sql new file mode 100644 index 0000000..5b0e6c6 --- /dev/null +++ b/nifi-registry-core/nifi-registry-framework/src/main/resources/db/migration/V4__AddCascadeOnDelete.sql @@ -0,0 +1,23 @@ +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +ALTER TABLE BUCKET_ITEM DROP CONSTRAINT FK__BUCKET_ITEM_BUCKET_ID; +ALTER TABLE BUCKET_ITEM ADD CONSTRAINT FK__BUCKET_ITEM_BUCKET_ID FOREIGN KEY (BUCKET_ID) REFERENCES BUCKET(ID) ON DELETE CASCADE; + +ALTER TABLE FLOW DROP CONSTRAINT FK__FLOW_BUCKET_ITEM_ID; +ALTER TABLE FLOW ADD CONSTRAINT FK__FLOW_BUCKET_ITEM_ID FOREIGN KEY (ID) REFERENCES BUCKET_ITEM(ID) ON DELETE CASCADE; + +ALTER TABLE FLOW_SNAPSHOT DROP CONSTRAINT FK__FLOW_SNAPSHOT_FLOW_ID; +ALTER TABLE FLOW_SNAPSHOT ADD CONSTRAINT FK__FLOW_SNAPSHOT_FLOW_ID FOREIGN KEY (FLOW_ID) REFERENCES FLOW(ID) ON DELETE CASCADE; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/main/xsd/providers.xsd ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/main/xsd/providers.xsd b/nifi-registry-core/nifi-registry-framework/src/main/xsd/providers.xsd index ce82dcc..4e9f5d1 100644 --- a/nifi-registry-core/nifi-registry-framework/src/main/xsd/providers.xsd +++ b/nifi-registry-core/nifi-registry-framework/src/main/xsd/providers.xsd @@ -44,6 +44,7 @@ <xs:sequence> <xs:element name="flowPersistenceProvider" type="Provider" minOccurs="1" maxOccurs="1" /> <xs:element name="eventHookProvider" type="Provider" minOccurs="0" maxOccurs="unbounded" /> + <xs:element name="extensionBundlePersistenceProvider" type="Provider" minOccurs="1" maxOccurs="1" /> </xs:sequence> </xs:complexType> </xs:element> http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java index 35ba757..a2bacd4 100644 --- a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java +++ b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java @@ -19,6 +19,12 @@ package org.apache.nifi.registry.db; import org.apache.nifi.registry.db.entity.BucketEntity; import org.apache.nifi.registry.db.entity.BucketItemEntity; import org.apache.nifi.registry.db.entity.BucketItemEntityType; +import org.apache.nifi.registry.db.entity.ExtensionBundleEntity; +import org.apache.nifi.registry.db.entity.ExtensionBundleEntityType; +import org.apache.nifi.registry.db.entity.ExtensionBundleVersionDependencyEntity; +import org.apache.nifi.registry.db.entity.ExtensionBundleVersionEntity; +import org.apache.nifi.registry.db.entity.ExtensionEntity; +import org.apache.nifi.registry.db.entity.ExtensionEntityCategory; import org.apache.nifi.registry.db.entity.FlowEntity; import org.apache.nifi.registry.db.entity.FlowSnapshotEntity; import org.apache.nifi.registry.service.MetadataService; @@ -30,9 +36,11 @@ import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.List; +import java.util.Set; import java.util.UUID; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -383,4 +391,448 @@ public class TestDatabaseMetadataService extends DatabaseBaseTest { assertNull(deletedEntity); } + //----------------- Extension Bundles --------------------------------- + + @Test + public void testGetExtensionBundleById() { + final ExtensionBundleEntity entity = metadataService.getExtensionBundle("eb1"); + assertNotNull(entity); + + assertEquals("eb1", entity.getId()); + assertEquals("nifi-example-processors-nar", entity.getName()); + assertEquals("Example processors bundle", entity.getDescription()); + assertNotNull(entity.getCreated()); + assertNotNull(entity.getModified()); + assertEquals(BucketItemEntityType.EXTENSION_BUNDLE, entity.getType()); + assertEquals("3", entity.getBucketId()); + + assertEquals(ExtensionBundleEntityType.NIFI_NAR, entity.getBundleType()); + + assertEquals("org.apache.nifi", entity.getGroupId()); + assertEquals("nifi-example-processors-nar", entity.getArtifactId()); + } + + @Test + public void testGetExtensionBundleDoesNotExist() { + final ExtensionBundleEntity entity = metadataService.getExtensionBundle("does-not-exist"); + assertNull(entity); + } + + @Test + public void testGetExtensionBundleByGroupArtifact() { + final String bucketId = "3"; + final String group = "org.apache.nifi"; + final String artifact = "nifi-example-service-api-nar"; + + final ExtensionBundleEntity entity = metadataService.getExtensionBundle(bucketId, group, artifact); + assertNotNull(entity); + assertEquals(bucketId, entity.getBucketId()); + + assertEquals(group, entity.getGroupId()); + assertEquals(artifact, entity.getArtifactId()); + } + + @Test + public void testGetExtensionBundleByGroupArtifactDoesNotExist() { + final String bucketId = "3"; + final String group = "org.apache.nifi"; + final String artifact = "does-not-exist"; + + final ExtensionBundleEntity entity = metadataService.getExtensionBundle(bucketId, group, artifact); + assertNull(entity); + } + + @Test + public void testGetExtensionBundles() { + final Set<String> bucketIds = new HashSet<>(); + bucketIds.add("1"); + bucketIds.add("2"); + bucketIds.add("3"); + + final List<ExtensionBundleEntity> bundles = metadataService.getExtensionBundles(bucketIds); + assertNotNull(bundles); + assertEquals(3, bundles.size()); + + bundles.forEach(b -> { + assertTrue(b.getVersionCount() > 0); + assertNotNull(b.getBucketName()); + }); + } + + @Test + public void testGetExtensionBundlesByBucket() { + final List<ExtensionBundleEntity> bundles = metadataService.getExtensionBundlesByBucket("3"); + assertNotNull(bundles); + assertEquals(3, bundles.size()); + + final List<ExtensionBundleEntity> bundles2 = metadataService.getExtensionBundlesByBucket("6"); + assertNotNull(bundles2); + assertEquals(0, bundles2.size()); + } + + @Test + public void testGetExtensionBundlesByBucketAndGroup() { + final List<ExtensionBundleEntity> bundles = metadataService.getExtensionBundlesByBucketAndGroup("3", "org.apache.nifi"); + assertNotNull(bundles); + assertEquals(3, bundles.size()); + + final List<ExtensionBundleEntity> bundles2 = metadataService.getExtensionBundlesByBucketAndGroup("3", "does-not-exist"); + assertNotNull(bundles2); + assertEquals(0, bundles2.size()); + } + + @Test + public void testCreateExtensionBundle() { + final ExtensionBundleEntity entity = new ExtensionBundleEntity(); + entity.setId(UUID.randomUUID().toString()); + entity.setBucketId("3"); + entity.setName("nifi-foo-nar"); + entity.setDescription("This is foo nar"); + entity.setCreated(new Date()); + entity.setModified(new Date()); + entity.setGroupId("org.apache.nifi"); + entity.setArtifactId("nifi-foo-nar"); + entity.setBundleType(ExtensionBundleEntityType.NIFI_NAR); + + final ExtensionBundleEntity createdEntity = metadataService.createExtensionBundle(entity); + assertNotNull(createdEntity); + + final List<ExtensionBundleEntity> bundles = metadataService.getExtensionBundlesByBucket("3"); + assertNotNull(bundles); + assertEquals(4, bundles.size()); + } + + @Test + public void testDeleteExtensionBundle() { + final List<ExtensionBundleEntity> bundles = metadataService.getExtensionBundlesByBucket("3"); + assertNotNull(bundles); + assertEquals(3, bundles.size()); + + final ExtensionBundleEntity existingBundle = bundles.get(0); + metadataService.deleteExtensionBundle(existingBundle); + + final ExtensionBundleEntity deletedBundle = metadataService.getExtensionBundle(existingBundle.getId()); + assertNull(deletedBundle); + + final List<ExtensionBundleEntity> bundlesAfterDelete = metadataService.getExtensionBundlesByBucket("3"); + assertNotNull(bundlesAfterDelete); + assertEquals(2, bundlesAfterDelete.size()); + } + + @Test + public void testDeleteBucketWithExtensionBundles() { + final List<ExtensionBundleEntity> bundles = metadataService.getExtensionBundlesByBucket("3"); + assertNotNull(bundles); + assertEquals(3, bundles.size()); + + final BucketEntity bucket = metadataService.getBucketById("3"); + assertNotNull(bucket); + metadataService.deleteBucket(bucket); + + final List<ExtensionBundleEntity> bundlesAfterDelete = metadataService.getExtensionBundlesByBucket("3"); + assertNotNull(bundlesAfterDelete); + assertEquals(0, bundlesAfterDelete.size()); + } + + //----------------- Extension Bundle Versions --------------------------------- + + @Test + public void testCreateExtensionBundleVersion() { + final ExtensionBundleVersionEntity bundleVersion = new ExtensionBundleVersionEntity(); + bundleVersion.setId(UUID.randomUUID().toString()); + bundleVersion.setExtensionBundleId("eb1"); + bundleVersion.setVersion("1.1.0"); + bundleVersion.setCreated(new Date()); + bundleVersion.setCreatedBy("user2"); + bundleVersion.setDescription("This is v1.1.0"); + bundleVersion.setSha256Hex("123456789"); + bundleVersion.setSha256Supplied(false); + + metadataService.createExtensionBundleVersion(bundleVersion); + + final ExtensionBundleVersionEntity createdBundleVersion = metadataService.getExtensionBundleVersion("eb1", "1.1.0"); + assertNotNull(createdBundleVersion); + assertEquals(bundleVersion.getId(), createdBundleVersion.getId()); + assertFalse(bundleVersion.getSha256Supplied()); + } + + @Test + public void testGetExtensionBundleVersionByBundleIdAndVersion() { + final ExtensionBundleVersionEntity bundleVersion = metadataService.getExtensionBundleVersion("eb1", "1.0.0"); + assertNotNull(bundleVersion); + assertEquals("eb1-v1", bundleVersion.getId()); + assertEquals("eb1", bundleVersion.getExtensionBundleId()); + assertEquals("1.0.0", bundleVersion.getVersion()); + assertNotNull(bundleVersion.getCreated()); + assertEquals("user1", bundleVersion.getCreatedBy()); + assertEquals("First version of eb1", bundleVersion.getDescription()); + assertTrue(bundleVersion.getSha256Supplied()); + } + + @Test + public void testGetExtensionBundleVersionByBundleIdAndVersionDoesNotExist() { + final ExtensionBundleVersionEntity bundleVersion = metadataService.getExtensionBundleVersion("does-not-exist", "1.0.0"); + assertNull(bundleVersion); + } + + @Test + public void testGetExtensionBundleVersionByBucketGroupArtifactVersion() { + final String bucketId = "3"; + final String groupId = "org.apache.nifi"; + final String artifactId = "nifi-example-processors-nar"; + final String version = "1.0.0"; + + final ExtensionBundleVersionEntity bundleVersion = metadataService.getExtensionBundleVersion(bucketId, groupId, artifactId, version); + assertNotNull(bundleVersion); + assertEquals("eb1-v1", bundleVersion.getId()); + assertTrue(bundleVersion.getSha256Supplied()); + } + + @Test + public void testGetExtensionBundleVersionByBucketGroupArtifactVersionWhenDoesNotExist() { + final String bucketId = "3"; + final String groupId = "org.apache.nifi"; + final String artifactId = "nifi-example-processors-nar"; + final String version = "FOO"; + + final ExtensionBundleVersionEntity bundleVersion = metadataService.getExtensionBundleVersion(bucketId, groupId, artifactId, version); + assertNull(bundleVersion); + } + + @Test + public void testGetExtensionBundleVersionsByBundleId() { + final List<ExtensionBundleVersionEntity> bundleVersions = metadataService.getExtensionBundleVersions("eb1"); + assertNotNull(bundleVersions); + assertEquals(1, bundleVersions.size()); + + final ExtensionBundleVersionEntity bundleVersion = bundleVersions.get(0); + assertEquals("eb1", bundleVersion.getExtensionBundleId()); + } + + @Test + public void testGetExtensionBundleVersionsByBundleIdWhenDoesNotExist() { + final List<ExtensionBundleVersionEntity> bundleVersions = metadataService.getExtensionBundleVersions("does-not-exist"); + assertNotNull(bundleVersions); + assertEquals(0, bundleVersions.size()); + } + + @Test + public void testGetExtensionBundleVersionsByBucketGroupArtifact() { + final String bucketId = "3"; + final String groupId = "org.apache.nifi"; + final String artifactId = "nifi-example-processors-nar"; + + final List<ExtensionBundleVersionEntity> bundleVersions = metadataService.getExtensionBundleVersions(bucketId, groupId, artifactId); + assertNotNull(bundleVersions); + assertEquals(1, bundleVersions.size()); + + final ExtensionBundleVersionEntity bundleVersion = bundleVersions.get(0); + assertEquals("eb1-v1", bundleVersion.getId()); + } + + @Test + public void testGetExtensionBundleVersionsByBucketGroupArtifactWhenDoesNotExist() { + final String bucketId = "3"; + final String groupId = "org.apache.nifi"; + final String artifactId = "does-not-exist"; + + final List<ExtensionBundleVersionEntity> bundleVersions = metadataService.getExtensionBundleVersions(bucketId, groupId, artifactId); + assertNotNull(bundleVersions); + assertEquals(0, bundleVersions.size()); + } + + @Test + public void testGetExtensionBundleVersionsGlobal() { + final String groupId = "org.apache.nifi"; + final String artifactId = "nifi-example-processors-nar"; + final String version = "1.0.0"; + + final List<ExtensionBundleVersionEntity> bundleVersions = metadataService.getExtensionBundleVersionsGlobal(groupId, artifactId, version); + assertNotNull(bundleVersions); + assertEquals(1, bundleVersions.size()); + + final ExtensionBundleVersionEntity bundleVersion = bundleVersions.get(0); + assertEquals("eb1-v1", bundleVersion.getId()); + } + + @Test + public void testDeleteExtensionBundleVersion() { + final ExtensionBundleVersionEntity bundleVersion = metadataService.getExtensionBundleVersion("eb1", "1.0.0"); + assertNotNull(bundleVersion); + + metadataService.deleteExtensionBundleVersion(bundleVersion); + + final ExtensionBundleVersionEntity deletedBundleVersion = metadataService.getExtensionBundleVersion("eb1", "1.0.0"); + assertNull(deletedBundleVersion); + } + + // ---------- Extension Bundle Version Dependencies ------------ + + @Test + public void testCreateExtensionBundleVersionDependency() { + final ExtensionBundleVersionEntity versionEntity = metadataService.getExtensionBundleVersion("eb1", "1.0.0"); + assertNotNull(versionEntity); + + final List<ExtensionBundleVersionDependencyEntity> dependencies = metadataService.getDependenciesForBundleVersion(versionEntity.getId()); + assertNotNull(dependencies); + assertEquals(1, dependencies.size()); + + final ExtensionBundleVersionDependencyEntity dependencyEntity = new ExtensionBundleVersionDependencyEntity(); + dependencyEntity.setId(UUID.randomUUID().toString()); + dependencyEntity.setExtensionBundleVersionId(versionEntity.getId()); + dependencyEntity.setGroupId("com.foo"); + dependencyEntity.setArtifactId("foo-nar"); + dependencyEntity.setVersion("1.1.1"); + + metadataService.createDependency(dependencyEntity); + + final List<ExtensionBundleVersionDependencyEntity> dependencies2 = metadataService.getDependenciesForBundleVersion(versionEntity.getId()); + assertNotNull(dependencies2); + assertEquals(2, dependencies2.size()); + } + + @Test + public void testGetExtensionBundleVersionDependencies() { + final List<ExtensionBundleVersionDependencyEntity> dependencies = metadataService.getDependenciesForBundleVersion("eb1-v1"); + assertNotNull(dependencies); + assertEquals(1, dependencies.size()); + + final ExtensionBundleVersionDependencyEntity dependency = dependencies.get(0); + assertEquals("eb1-v1-dep1", dependency.getId()); + assertEquals("eb1-v1", dependency.getExtensionBundleVersionId()); + assertEquals("org.apache.nifi", dependency.getGroupId()); + assertEquals("nifi-example-service-api-nar", dependency.getArtifactId()); + assertEquals("2.0.0", dependency.getVersion()); + } + + @Test + public void testGetExtensionBundleVersionDependenciesWhenNoneExist() { + final List<ExtensionBundleVersionDependencyEntity> dependencies = metadataService.getDependenciesForBundleVersion("DOES-NOT-EXIST"); + assertNotNull(dependencies); + assertEquals(0, dependencies.size()); + } + + //----------------- Extensions --------------------------------- + + @Test + public void testCreateExtension() { + final ExtensionEntity extension = new ExtensionEntity(); + extension.setId("4"); + extension.setExtensionBundleVersionId("eb1-v1"); + extension.setType("com.example.FooBarProcessor"); + extension.setTypeDescription("This the FoorBarProcessor"); + extension.setCategory(ExtensionEntityCategory.PROCESSOR); + extension.setRestricted(false); + extension.setTags("tag1, tag2"); + + metadataService.createExtension(extension); + + final ExtensionEntity retrievedExtension = metadataService.getExtensionById(extension.getId()); + assertEquals(extension.getId(), retrievedExtension.getId()); + assertEquals(extension.getExtensionBundleVersionId(), retrievedExtension.getExtensionBundleVersionId()); + assertEquals(extension.getType(), retrievedExtension.getType()); + assertEquals(extension.getTypeDescription(), retrievedExtension.getTypeDescription()); + assertEquals(extension.getCategory(), retrievedExtension.getCategory()); + assertEquals(extension.isRestricted(), retrievedExtension.isRestricted()); + assertEquals(extension.getTags(), retrievedExtension.getTags()); + + final List<ExtensionEntity> tag1Extensions = metadataService.getExtensionsByTag("tag1"); + assertNotNull(tag1Extensions); + assertEquals(1, tag1Extensions.size()); + assertEquals(extension.getId(), tag1Extensions.get(0).getId()); + + final List<ExtensionEntity> tag2Extensions = metadataService.getExtensionsByTag("tag2"); + assertNotNull(tag2Extensions); + assertEquals(1, tag2Extensions.size()); + assertEquals(extension.getId(), tag2Extensions.get(0).getId()); + } + + @Test + public void testGetExtensionById() { + final ExtensionEntity extension = metadataService.getExtensionById("e1"); + assertNotNull(extension); + assertEquals("e1", extension.getId()); + assertEquals("org.apache.nifi.ExampleProcessor", extension.getType()); + } + + @Test + public void testGetExtensionByIdDoesNotExist() { + final ExtensionEntity extension = metadataService.getExtensionById("does-not-exist"); + assertNull(extension); + } + + @Test + public void testGetAllExtensions() { + final List<ExtensionEntity> extensions = metadataService.getAllExtensions(); + assertNotNull(extensions); + assertEquals(3, extensions.size()); + } + + @Test + public void testGetExtensionsByBundleVersionId() { + final List<ExtensionEntity> extensions = metadataService.getExtensionsByBundleVersionId("eb1-v1"); + assertNotNull(extensions); + assertEquals(2, extensions.size()); + } + + @Test + public void testGetExtensionsByBundleVersionIdDoesNotExist() { + final List<ExtensionEntity> extensions = metadataService.getExtensionsByBundleVersionId("does-not-exist"); + assertNotNull(extensions); + assertEquals(0, extensions.size()); + } + + @Test + public void testGetExtensionsByBundleCoordinate() { + final String bucketId = "3"; + final String groupId = "org.apache.nifi"; + final String artifactId = "nifi-example-processors-nar"; + final String version = "1.0.0"; + + final List<ExtensionEntity> extensions = metadataService.getExtensionsByBundleCoordinate(bucketId, groupId, artifactId, version); + assertNotNull(extensions); + assertEquals(2, extensions.size()); + } + + @Test + public void testGetExtensionsByBundleCoordinateDoesNotExist() { + final String bucketId = "3"; + final String groupId = "org.apache.nifi"; + final String artifactId = "does-not-exist"; + final String version = "1.0.0"; + + final List<ExtensionEntity> extensions = metadataService.getExtensionsByBundleCoordinate(bucketId, groupId, artifactId, version); + assertNotNull(extensions); + assertEquals(0, extensions.size()); + } + + @Test + public void testGetExtensionsByCategory() { + final List<ExtensionEntity> services = metadataService.getExtensionsByCategory(ExtensionEntityCategory.CONTROLLER_SERVICE); + assertNotNull(services); + assertEquals(1, services.size()); + + final List<ExtensionEntity> processors = metadataService.getExtensionsByCategory(ExtensionEntityCategory.PROCESSOR); + assertNotNull(processors); + assertEquals(2, processors.size()); + } + + @Test + public void testGetExtensionTags() { + final Set<String> tags = metadataService.getAllExtensionTags(); + assertNotNull(tags); + assertEquals(4, tags.size()); + } + + @Test + public void testDeleteExtension() { + final ExtensionEntity extension = metadataService.getExtensionById("e1"); + assertNotNull(extension); + + metadataService.deleteExtension(extension); + + final ExtensionEntity deletedExtension = metadataService.getExtensionById("e1"); + assertNull(deletedExtension); + } + } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/migration/TestLegacyDatabaseService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/migration/TestLegacyDatabaseService.java b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/migration/TestLegacyDatabaseService.java index df37e8e..116ba35 100644 --- a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/migration/TestLegacyDatabaseService.java +++ b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/migration/TestLegacyDatabaseService.java @@ -52,9 +52,11 @@ public class TestLegacyDatabaseService { jdbcTemplate = new JdbcTemplate(dataSource); - flyway = new Flyway(); - flyway.setDataSource(dataSource); - flyway.setLocations("db/original"); + flyway = Flyway.configure() + .dataSource(dataSource) + .locations("db/original") + .load(); + flyway.migrate(); bucketEntityV1 = new BucketEntityV1(); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/event/TestEventFactory.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/event/TestEventFactory.java b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/event/TestEventFactory.java index a9ad911..e5075c0 100644 --- a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/event/TestEventFactory.java +++ b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/event/TestEventFactory.java @@ -17,6 +17,10 @@ package org.apache.nifi.registry.event; import org.apache.nifi.registry.bucket.Bucket; +import org.apache.nifi.registry.extension.ExtensionBundle; +import org.apache.nifi.registry.extension.ExtensionBundleType; +import org.apache.nifi.registry.extension.ExtensionBundleVersion; +import org.apache.nifi.registry.extension.ExtensionBundleVersionMetadata; import org.apache.nifi.registry.flow.VersionedFlow; import org.apache.nifi.registry.flow.VersionedFlowSnapshot; import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata; @@ -36,6 +40,8 @@ public class TestEventFactory { private Bucket bucket; private VersionedFlow versionedFlow; private VersionedFlowSnapshot versionedFlowSnapshot; + private ExtensionBundle extensionBundle; + private ExtensionBundleVersion extensionBundleVersion; @Before public void setup() { @@ -60,6 +66,24 @@ public class TestEventFactory { versionedFlowSnapshot = new VersionedFlowSnapshot(); versionedFlowSnapshot.setSnapshotMetadata(metadata); versionedFlowSnapshot.setFlowContents(new VersionedProcessGroup()); + + extensionBundle = new ExtensionBundle(); + extensionBundle.setIdentifier(UUID.randomUUID().toString()); + extensionBundle.setBucketIdentifier(bucket.getIdentifier()); + extensionBundle.setBundleType(ExtensionBundleType.NIFI_NAR); + extensionBundle.setGroupId("org.apache.nifi"); + extensionBundle.setArtifactId("nifi-foo-nar"); + + final ExtensionBundleVersionMetadata bundleVersionMetadata = new ExtensionBundleVersionMetadata(); + bundleVersionMetadata.setId(UUID.randomUUID().toString()); + bundleVersionMetadata.setVersion("1.0.0"); + bundleVersionMetadata.setBucketId(bucket.getIdentifier()); + bundleVersionMetadata.setExtensionBundleId(extensionBundle.getIdentifier()); + + extensionBundleVersion = new ExtensionBundleVersion(); + extensionBundleVersion.setVersionMetadata(bundleVersionMetadata); + extensionBundleVersion.setExtensionBundle(extensionBundle); + extensionBundleVersion.setBucket(bucket); } @Test @@ -166,4 +190,57 @@ public class TestEventFactory { assertEquals("", event.getField(EventFieldName.COMMENT).getValue()); } + @Test + public void testExtensionBundleCreated() { + final Event event = EventFactory.extensionBundleCreated(extensionBundle); + event.validate(); + + assertEquals(EventType.CREATE_EXTENSION_BUNDLE, event.getEventType()); + assertEquals(3, event.getFields().size()); + + assertEquals(bucket.getIdentifier(), event.getField(EventFieldName.BUCKET_ID).getValue()); + assertEquals(extensionBundle.getIdentifier(), event.getField(EventFieldName.EXTENSION_BUNDLE_ID).getValue()); + assertEquals("unknown", event.getField(EventFieldName.USER).getValue()); + } + + @Test + public void testExtensionBundleDeleted() { + final Event event = EventFactory.extensionBundleDeleted(extensionBundle); + event.validate(); + + assertEquals(EventType.DELETE_EXTENSION_BUNDLE, event.getEventType()); + assertEquals(3, event.getFields().size()); + + assertEquals(bucket.getIdentifier(), event.getField(EventFieldName.BUCKET_ID).getValue()); + assertEquals(extensionBundle.getIdentifier(), event.getField(EventFieldName.EXTENSION_BUNDLE_ID).getValue()); + assertEquals("unknown", event.getField(EventFieldName.USER).getValue()); + } + + @Test + public void testExtensionBundleVersionCreated() { + final Event event = EventFactory.extensionBundleVersionCreated(extensionBundleVersion); + event.validate(); + + assertEquals(EventType.CREATE_EXTENSION_BUNDLE_VERSION, event.getEventType()); + assertEquals(4, event.getFields().size()); + + assertEquals(bucket.getIdentifier(), event.getField(EventFieldName.BUCKET_ID).getValue()); + assertEquals(extensionBundle.getIdentifier(), event.getField(EventFieldName.EXTENSION_BUNDLE_ID).getValue()); + assertEquals(extensionBundleVersion.getVersionMetadata().getVersion(), event.getField(EventFieldName.VERSION).getValue()); + assertEquals("unknown", event.getField(EventFieldName.USER).getValue()); + } + + @Test + public void testExtensionBundleVersionDeleted() { + final Event event = EventFactory.extensionBundleVersionDeleted(extensionBundleVersion); + event.validate(); + + assertEquals(EventType.DELETE_EXTENSION_BUNDLE_VERSION, event.getEventType()); + assertEquals(4, event.getFields().size()); + + assertEquals(bucket.getIdentifier(), event.getField(EventFieldName.BUCKET_ID).getValue()); + assertEquals(extensionBundle.getIdentifier(), event.getField(EventFieldName.EXTENSION_BUNDLE_ID).getValue()); + assertEquals(extensionBundleVersion.getVersionMetadata().getVersion(), event.getField(EventFieldName.VERSION).getValue()); + assertEquals("unknown", event.getField(EventFieldName.USER).getValue()); + } } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/MockExtensionBundlePersistenceProvider.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/MockExtensionBundlePersistenceProvider.java b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/MockExtensionBundlePersistenceProvider.java new file mode 100644 index 0000000..ba7f12f --- /dev/null +++ b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/MockExtensionBundlePersistenceProvider.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.nifi.registry.provider; + +import org.apache.nifi.registry.extension.ExtensionBundleContext; +import org.apache.nifi.registry.extension.ExtensionBundlePersistenceException; +import org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider; + +import java.io.InputStream; +import java.io.OutputStream; +import java.util.Map; + +public class MockExtensionBundlePersistenceProvider implements ExtensionBundlePersistenceProvider { + + private Map<String,String> properties; + + @Override + public void saveBundleVersion(ExtensionBundleContext context, InputStream contentStream) + throws ExtensionBundlePersistenceException { + + } + + @Override + public void getBundleVersion(ExtensionBundleContext context, OutputStream outputStream) throws ExtensionBundlePersistenceException { + + } + + @Override + public void deleteBundleVersion(ExtensionBundleContext context) throws ExtensionBundlePersistenceException { + + } + + @Override + public void deleteAllBundleVersions(String bucketId, String bucketName, String groupId, String artifactId) throws ExtensionBundlePersistenceException { + + } + + @Override + public void onConfigured(ProviderConfigurationContext configurationContext) + throws ProviderCreationException { + properties = configurationContext.getProperties(); + } + + public Map<String,String> getProperties() { + return properties; + } + +} http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java ---------------------------------------------------------------------- diff --git a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java index 30f66ef..2105cff 100644 --- a/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java +++ b/nifi-registry-core/nifi-registry-framework/src/test/java/org/apache/nifi/registry/provider/TestStandardProviderFactory.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.registry.provider; +import org.apache.nifi.registry.extension.ExtensionBundlePersistenceProvider; import org.apache.nifi.registry.extension.ExtensionManager; import org.apache.nifi.registry.flow.FlowPersistenceProvider; import org.apache.nifi.registry.properties.NiFiRegistryProperties; @@ -47,6 +48,14 @@ public class TestStandardProviderFactory { assertNotNull(mockFlowProvider.getProperties()); assertEquals("flow foo", mockFlowProvider.getProperties().get("Flow Property 1")); assertEquals("flow bar", mockFlowProvider.getProperties().get("Flow Property 2")); + + final ExtensionBundlePersistenceProvider bundlePersistenceProvider = providerFactory.getExtensionBundlePersistenceProvider(); + assertNotNull(bundlePersistenceProvider); + + final MockExtensionBundlePersistenceProvider mockBundlePersistenceProvider = (MockExtensionBundlePersistenceProvider) bundlePersistenceProvider; + assertNotNull(mockBundlePersistenceProvider.getProperties()); + assertEquals("extension foo", mockBundlePersistenceProvider.getProperties().get("Extension Property 1")); + assertEquals("extension bar", mockBundlePersistenceProvider.getProperties().get("Extension Property 2")); } @Test(expected = ProviderFactoryException.class)
