You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by kd...@apache.org on 2018/11/30 18:56:33 UTC
[6/7] nifi-registry git commit: NIFIREG-211 Initial work for adding
extenion bundles to NiFi Registry
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyNiFiRegistryClient.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyNiFiRegistryClient.java b/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyNiFiRegistryClient.java
index 329a47a..972211b 100644
--- a/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyNiFiRegistryClient.java
+++ b/nifi-registry-core/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyNiFiRegistryClient.java
@@ -24,6 +24,9 @@ import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.registry.bucket.BucketItem;
import org.apache.nifi.registry.client.BucketClient;
+import org.apache.nifi.registry.client.ExtensionBundleClient;
+import org.apache.nifi.registry.client.ExtensionBundleVersionClient;
+import org.apache.nifi.registry.client.ExtensionRepoClient;
import org.apache.nifi.registry.client.FlowClient;
import org.apache.nifi.registry.client.FlowSnapshotClient;
import org.apache.nifi.registry.client.ItemsClient;
@@ -33,7 +36,9 @@ import org.apache.nifi.registry.client.UserClient;
import org.apache.nifi.registry.security.util.ProxiedEntitiesUtils;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.RequestEntityProcessing;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
+import org.glassfish.jersey.media.multipart.MultiPartFeature;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
@@ -107,9 +112,13 @@ public class JerseyNiFiRegistryClient implements NiFiRegistryClient {
final ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout);
clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout);
+ clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED);
clientConfig.register(jacksonJaxbJsonProvider());
clientBuilder.withConfig(clientConfig);
- this.client = clientBuilder.build();
+
+ this.client = clientBuilder
+ .register(MultiPartFeature.class)
+ .build();
this.baseTarget = client.target(baseUrl);
this.bucketClient = new JerseyBucketClient(baseTarget);
@@ -173,6 +182,39 @@ public class JerseyNiFiRegistryClient implements NiFiRegistryClient {
return new JerseyUserClient(baseTarget, headers);
}
+ @Override
+ public ExtensionBundleClient getExtensionBundleClient() {
+ return new JerseyExtensionBundleClient(baseTarget);
+ }
+
+ @Override
+ public ExtensionBundleClient getExtensionBundleClient(String... proxiedEntity) {
+ final Map<String,String> headers = getHeaders(proxiedEntity);
+ return new JerseyExtensionBundleClient(baseTarget, headers);
+ }
+
+ @Override
+ public ExtensionBundleVersionClient getExtensionBundleVersionClient() {
+ return new JerseyExtensionBundleVersionClient(baseTarget);
+ }
+
+ @Override
+ public ExtensionBundleVersionClient getExtensionBundleVersionClient(String... proxiedEntity) {
+ final Map<String,String> headers = getHeaders(proxiedEntity);
+ return new JerseyExtensionBundleVersionClient(baseTarget, headers);
+ }
+
+ @Override
+ public ExtensionRepoClient getExtensionRepoClient() {
+ return new JerseyExtensionRepoClient(baseTarget);
+ }
+
+ @Override
+ public ExtensionRepoClient getExtensionRepoClient(String... proxiedEntity) {
+ final Map<String,String> headers = getHeaders(proxiedEntity);
+ return new JerseyExtensionRepoClient(baseTarget, headers);
+ }
+
private Map<String,String> getHeaders(String[] proxiedEntities) {
final String proxiedEntitiesValue = getProxiedEntitesValue(proxiedEntities);
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketItemType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketItemType.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketItemType.java
index e119c02..b746491 100644
--- a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketItemType.java
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/bucket/BucketItemType.java
@@ -23,5 +23,8 @@ public enum BucketItemType {
// The case of these enum names matches what we want to return in
// the BucketItem.type field when serialized in an API response.
- Flow;
+
+ Flow,
+
+ Extension_Bundle;
}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundle.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundle.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundle.java
new file mode 100644
index 0000000..c9f0e7f
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundle.java
@@ -0,0 +1,92 @@
+/*
+ * 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.extension;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.bucket.BucketItem;
+import org.apache.nifi.registry.bucket.BucketItemType;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * Represents an extension bundle identified by a group and artifact id with in a bucket.
+ *
+ * Each bundle may then have one or more versions associated with it by creating an {@link ExtensionBundleVersion}.
+ *
+ * The {@link ExtensionBundleVersion} represents the actually binary bundle which may contain one or more extensions.
+ */
+@ApiModel
+@XmlRootElement
+public class ExtensionBundle extends BucketItem {
+
+ @NotNull
+ private ExtensionBundleType bundleType;
+
+ @NotBlank
+ private String groupId;
+
+ @NotBlank
+ private String artifactId;
+
+ @Min(0)
+ private long versionCount;
+
+ public ExtensionBundle() {
+ super(BucketItemType.Extension_Bundle);
+ }
+
+ @ApiModelProperty(value = "The type of the extension bundle")
+ public ExtensionBundleType getBundleType() {
+ return bundleType;
+ }
+
+ public void setBundleType(ExtensionBundleType bundleType) {
+ this.bundleType = bundleType;
+ }
+
+ @ApiModelProperty(value = "The group id of the extension bundle")
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ @ApiModelProperty(value = "The artifact id of the extension bundle")
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ @ApiModelProperty(value = "The number of versions of this extension bundle.", readOnly = true)
+ public long getVersionCount() {
+ return versionCount;
+ }
+
+ public void setVersionCount(long versionCount) {
+ this.versionCount = versionCount;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleType.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleType.java
new file mode 100644
index 0000000..0eb0447
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleType.java
@@ -0,0 +1,58 @@
+/*
+ * 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.extension;
+
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+/**
+ * The possible types of extension bundles.
+ */
+@XmlJavaTypeAdapter(ExtensionBundleTypeAdapter.class)
+public enum ExtensionBundleType {
+
+ NIFI_NAR("nifi-nar"),
+
+ MINIFI_CPP("minifi-cpp");
+
+ private final String displayName;
+
+ ExtensionBundleType(String displayName) {
+ this.displayName = displayName;
+ }
+
+ // Note: This method must be name fromString for JAX-RS/Jersey to use it on query and path params
+ public static ExtensionBundleType fromString(String value) {
+ if (value == null) {
+ throw new IllegalArgumentException("Value cannot be null");
+ }
+
+ for (final ExtensionBundleType type : values()) {
+ if (type.toString().equals(value)) {
+ return type;
+ }
+ }
+
+ throw new IllegalArgumentException("Unknown ExtensionBundleType: " + value);
+ }
+
+
+ @Override
+ public String toString() {
+ return displayName;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleTypeAdapter.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleTypeAdapter.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleTypeAdapter.java
new file mode 100644
index 0000000..1a993cf
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleTypeAdapter.java
@@ -0,0 +1,40 @@
+/*
+ * 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.extension;
+
+import javax.xml.bind.annotation.adapters.XmlAdapter;
+
+public class ExtensionBundleTypeAdapter extends XmlAdapter<String,ExtensionBundleType> {
+
+ @Override
+ public ExtensionBundleType unmarshal(String v) throws Exception {
+ if (v == null) {
+ return null;
+ }
+
+ return ExtensionBundleType.fromString(v);
+ }
+
+ @Override
+ public String marshal(final ExtensionBundleType v) throws Exception {
+ if (v == null) {
+ return null;
+ }
+
+ return v.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersion.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersion.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersion.java
new file mode 100644
index 0000000..a8ef0c3
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersion.java
@@ -0,0 +1,98 @@
+/*
+ * 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.extension;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.bucket.Bucket;
+import org.apache.nifi.registry.link.LinkableEntity;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+import java.util.Set;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionBundleVersion extends LinkableEntity {
+
+ @Valid
+ @NotNull
+ private ExtensionBundleVersionMetadata versionMetadata;
+
+ // read-only, only populated from retrieval of an individual bundle version
+ private Set<ExtensionBundleVersionDependency> dependencies;
+
+ // read-only, only populated from retrieval of an individual bundle version
+ private ExtensionBundle extensionBundle;
+
+ // read-only, only populated from retrieval of an individual bundle version
+ private Bucket bucket;
+
+ @ApiModelProperty(value = "The metadata about this version of the extension bundle")
+ public ExtensionBundleVersionMetadata getVersionMetadata() {
+ return versionMetadata;
+ }
+
+ public void setVersionMetadata(ExtensionBundleVersionMetadata versionMetadata) {
+ this.versionMetadata = versionMetadata;
+ }
+
+ @ApiModelProperty(value = "The set of other bundle versions that this version is dependent on", readOnly = true)
+ public Set<ExtensionBundleVersionDependency> getDependencies() {
+ return dependencies;
+ }
+
+ public void setDependencies(Set<ExtensionBundleVersionDependency> dependencies) {
+ this.dependencies = dependencies;
+ }
+
+ @ApiModelProperty(value = "The bundle this version is for", readOnly = true)
+ public ExtensionBundle getExtensionBundle() {
+ return extensionBundle;
+ }
+
+ public void setExtensionBundle(ExtensionBundle extensionBundle) {
+ this.extensionBundle = extensionBundle;
+ }
+
+ @ApiModelProperty(value = "The bucket that the extension bundle belongs to")
+ public Bucket getBucket() {
+ return bucket;
+ }
+
+ public void setBucket(Bucket bucket) {
+ this.bucket = bucket;
+ }
+
+ @XmlTransient
+ public String getFilename() {
+ final String filename = extensionBundle.getArtifactId() + "-" + versionMetadata.getVersion();
+
+ switch (extensionBundle.getBundleType()) {
+ case NIFI_NAR:
+ return filename + ".nar";
+ case MINIFI_CPP:
+ // TODO should CPP get a special extension
+ return filename;
+ default:
+ throw new IllegalStateException("Unknown bundle type: " + extensionBundle.getBundleType());
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionDependency.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionDependency.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionDependency.java
new file mode 100644
index 0000000..f84649b
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionDependency.java
@@ -0,0 +1,84 @@
+/*
+ * 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.extension;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Objects;
+
+@ApiModel
+public class ExtensionBundleVersionDependency {
+
+ @NotBlank
+ private String groupId;
+
+ @NotBlank
+ private String artifactId;
+
+ @NotBlank
+ private String version;
+
+ @ApiModelProperty(value = "The group id of the bundle dependency")
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ @ApiModelProperty(value = "The artifact id of the bundle dependency")
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ @ApiModelProperty(value = "The version of the bundle dependency")
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(groupId, artifactId, version);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ExtensionBundleVersionDependency other = (ExtensionBundleVersionDependency) obj;
+
+ return Objects.equals(groupId, other.groupId)
+ && Objects.equals(artifactId, other.artifactId)
+ && Objects.equals(version, other.version);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionMetadata.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionMetadata.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionMetadata.java
new file mode 100644
index 0000000..35756f9
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/ExtensionBundleVersionMetadata.java
@@ -0,0 +1,163 @@
+/*
+ * 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.extension;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.link.LinkableEntity;
+
+import javax.validation.constraints.Min;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Objects;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionBundleVersionMetadata extends LinkableEntity implements Comparable<ExtensionBundleVersionMetadata> {
+
+ @NotBlank
+ private String id;
+
+ @NotBlank
+ private String extensionBundleId;
+
+ @NotBlank
+ private String bucketId;
+
+ @NotBlank
+ private String version;
+
+ @Min(1)
+ private long timestamp;
+
+ @NotBlank
+ private String author;
+
+ private String description;
+
+ @NotBlank
+ private String sha256;
+
+ @NotNull
+ private Boolean sha256Supplied;
+
+
+ @ApiModelProperty(value = "The id of this version of the extension bundle")
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ @ApiModelProperty(value = "The id of the extension bundle this version is for")
+ public String getExtensionBundleId() {
+ return extensionBundleId;
+ }
+
+ public void setExtensionBundleId(String extensionBundleId) {
+ this.extensionBundleId = extensionBundleId;
+ }
+
+ @ApiModelProperty(value = "The id of the bucket the extension bundle belongs to", required = true)
+ public String getBucketId() {
+ return bucketId;
+ }
+
+ public void setBucketId(String bucketId) {
+ this.bucketId = bucketId;
+ }
+
+ @ApiModelProperty(value = "The version of the extension bundle")
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ @ApiModelProperty(value = "The timestamp of the create date of this version")
+ public long getTimestamp() {
+ return timestamp;
+ }
+
+ public void setTimestamp(long timestamp) {
+ this.timestamp = timestamp;
+ }
+
+ @ApiModelProperty(value = "The identity that created this version")
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+
+ @ApiModelProperty(value = "The description for this version")
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ @ApiModelProperty(value = "The hex representation of the SHA-256 digest of the binary content for this version")
+ public String getSha256() {
+ return sha256;
+ }
+
+ public void setSha256(String sha256) {
+ this.sha256 = sha256;
+ }
+
+ @ApiModelProperty(value = "Whether or not the client supplied a SHA-256 when uploading the bundle")
+ public Boolean getSha256Supplied() {
+ return sha256Supplied;
+ }
+
+ public void setSha256Supplied(Boolean sha256Supplied) {
+ this.sha256Supplied = sha256Supplied;
+ }
+
+ @Override
+ public int compareTo(final ExtensionBundleVersionMetadata o) {
+ return o == null ? -1 : version.compareTo(o.version);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.id);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ExtensionBundleVersionMetadata other = (ExtensionBundleVersionMetadata) obj;
+ return Objects.equals(this.id, other.id);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoArtifact.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoArtifact.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoArtifact.java
new file mode 100644
index 0000000..6b42678
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoArtifact.java
@@ -0,0 +1,93 @@
+/*
+ * 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.extension.repo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.link.LinkableEntity;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Comparator;
+import java.util.Objects;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionRepoArtifact extends LinkableEntity implements Comparable<ExtensionRepoArtifact> {
+
+ private String bucketName;
+
+ private String groupId;
+
+ private String artifactId;
+
+ @ApiModelProperty(value = "The bucket name")
+ public String getBucketName() {
+ return bucketName;
+ }
+
+ public void setBucketName(String bucketName) {
+ this.bucketName = bucketName;
+ }
+
+ @ApiModelProperty("The group id")
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ @ApiModelProperty("The artifact id")
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ @Override
+ public int compareTo(final ExtensionRepoArtifact o) {
+ return Comparator.comparing(ExtensionRepoArtifact::getArtifactId)
+ .thenComparing(ExtensionRepoArtifact::getGroupId)
+ .thenComparing(ExtensionRepoArtifact::getBucketName)
+ .compare(this, o);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.bucketName, this.groupId, this.artifactId) ;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ExtensionRepoArtifact other = (ExtensionRepoArtifact) obj;
+
+ return Objects.equals(this.getBucketName(), other.getBucketName())
+ && Objects.equals(this.getGroupId(), other.getGroupId())
+ && Objects.equals(this.getArtifactId(), other.getArtifactId());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoBucket.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoBucket.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoBucket.java
new file mode 100644
index 0000000..1798df7
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoBucket.java
@@ -0,0 +1,64 @@
+/*
+ * 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.extension.repo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.link.LinkableEntity;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Comparator;
+import java.util.Objects;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionRepoBucket extends LinkableEntity implements Comparable<ExtensionRepoBucket> {
+
+ private String bucketName;
+
+ @ApiModelProperty(value = "The name of the bucket")
+ public String getBucketName() {
+ return bucketName;
+ }
+
+ public void setBucketName(String bucketName) {
+ this.bucketName = bucketName;
+ }
+
+ @Override
+ public int compareTo(final ExtensionRepoBucket o) {
+ return Comparator.comparing(ExtensionRepoBucket::getBucketName).compare(this, o);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(this.bucketName);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ExtensionRepoBucket other = (ExtensionRepoBucket) obj;
+ return Objects.equals(this.getBucketName(), other.getBucketName());
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoGroup.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoGroup.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoGroup.java
new file mode 100644
index 0000000..86e25f2
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoGroup.java
@@ -0,0 +1,80 @@
+/*
+ * 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.extension.repo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.link.LinkableEntity;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Comparator;
+import java.util.Objects;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionRepoGroup extends LinkableEntity implements Comparable<ExtensionRepoGroup> {
+
+ private String bucketName;
+
+ private String groupId;
+
+ @ApiModelProperty(value = "The bucket name")
+ public String getBucketName() {
+ return bucketName;
+ }
+
+ public void setBucketName(String bucketName) {
+ this.bucketName = bucketName;
+ }
+
+ @ApiModelProperty(value = "The group id")
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ @Override
+ public int compareTo(final ExtensionRepoGroup o) {
+ return Comparator.comparing(ExtensionRepoGroup::getGroupId)
+ .thenComparing(ExtensionRepoGroup::getBucketName)
+ .compare(this, o);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.bucketName, this.groupId) ;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ExtensionRepoGroup other = (ExtensionRepoGroup) obj;
+
+ return Objects.equals(this.getBucketName(), other.getBucketName())
+ && Objects.equals(this.getGroupId(), other.getGroupId());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersion.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersion.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersion.java
new file mode 100644
index 0000000..4dff6e6
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersion.java
@@ -0,0 +1,68 @@
+/*
+ * 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.extension.repo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.link.LinkAdapter;
+
+import javax.ws.rs.core.Link;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionRepoVersion {
+
+ private Link downloadLink;
+
+ private Link sha256Link;
+
+ private Boolean sha256Supplied;
+
+ @XmlElement
+ @XmlJavaTypeAdapter(LinkAdapter.class)
+ @ApiModelProperty(value = "The WebLink to download this version of the extension bundle.", readOnly = true)
+ public Link getDownloadLink() {
+ return downloadLink;
+ }
+
+ public void setDownloadLink(Link downloadLink) {
+ this.downloadLink = downloadLink;
+ }
+
+ @XmlElement
+ @XmlJavaTypeAdapter(LinkAdapter.class)
+ @ApiModelProperty(value = "The WebLink to retrieve the SHA-256 digest for this version of the extension bundle.", readOnly = true)
+ public Link getSha256Link() {
+ return sha256Link;
+ }
+
+ public void setSha256Link(Link sha256Link) {
+ this.sha256Link = sha256Link;
+ }
+
+ @ApiModelProperty(value = "Indicates if the client supplied a SHA-256 when uploading this version of the extension bundle.", readOnly = true)
+ public Boolean getSha256Supplied() {
+ return sha256Supplied;
+ }
+
+ public void setSha256Supplied(Boolean sha256Supplied) {
+ this.sha256Supplied = sha256Supplied;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersionSummary.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersionSummary.java b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersionSummary.java
new file mode 100644
index 0000000..f73d32e
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-data-model/src/main/java/org/apache/nifi/registry/extension/repo/ExtensionRepoVersionSummary.java
@@ -0,0 +1,106 @@
+/*
+ * 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.extension.repo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.apache.nifi.registry.link.LinkableEntity;
+
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Comparator;
+import java.util.Objects;
+
+@ApiModel
+@XmlRootElement
+public class ExtensionRepoVersionSummary extends LinkableEntity implements Comparable<ExtensionRepoVersionSummary> {
+
+ private String bucketName;
+
+ private String groupId;
+
+ private String artifactId;
+
+ private String version;
+
+ @ApiModelProperty(value = "The bucket name")
+ public String getBucketName() {
+ return bucketName;
+ }
+
+ public void setBucketName(String bucketName) {
+ this.bucketName = bucketName;
+ }
+
+ @ApiModelProperty("The group id")
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ @ApiModelProperty("The artifact id")
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ @ApiModelProperty("The version")
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ @Override
+ public int compareTo(ExtensionRepoVersionSummary o) {
+ return Comparator.comparing(ExtensionRepoVersionSummary::getVersion)
+ .thenComparing(ExtensionRepoVersionSummary::getArtifactId)
+ .thenComparing(ExtensionRepoVersionSummary::getGroupId)
+ .thenComparing(ExtensionRepoVersionSummary::getBucketName)
+ .compare(this, o);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(this.bucketName, this.groupId, this.artifactId, this.version);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+
+ final ExtensionRepoVersionSummary other = (ExtensionRepoVersionSummary) obj;
+
+ return Objects.equals(this.getBucketName(), other.getBucketName())
+ && Objects.equals(this.getGroupId(), other.getGroupId())
+ && Objects.equals(this.getArtifactId(), other.getArtifactId())
+ && Objects.equals(this.getVersion(), other.getVersion());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/f1e5aef7/nifi-registry-core/nifi-registry-framework/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/pom.xml b/nifi-registry-core/nifi-registry-framework/pom.xml
index 8ce4a13..c226e42 100644
--- a/nifi-registry-core/nifi-registry-framework/pom.xml
+++ b/nifi-registry-core/nifi-registry-framework/pom.xml
@@ -182,6 +182,11 @@
<version>0.4.0-SNAPSHOT</version>
</dependency>
<dependency>
+ <groupId>org.apache.nifi.registry</groupId>
+ <artifactId>nifi-registry-bundle-utils</artifactId>
+ <version>0.4.0-SNAPSHOT</version>
+ </dependency>
+ <dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
@@ -233,10 +238,6 @@
<artifactId>commons-io</artifactId>
</dependency>
<dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-validator</artifactId>
- </dependency>
- <dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
</dependency>
@@ -266,6 +267,11 @@
</exclusions>
</dependency>
<dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-validation</artifactId>
+ <version>${spring.boot.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>${flyway.version}</version>
@@ -315,7 +321,7 @@
<dependency>
<groupId>org.flywaydb.flyway-test-extensions</groupId>
<artifactId>flyway-spring-test</artifactId>
- <version>${flyway.version}</version>
+ <version>${flyway.tests.version}</version>
<scope>test</scope>
<exclusions>
<exclusion>
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/db/CustomFlywayMigrationStrategy.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/CustomFlywayMigrationStrategy.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/CustomFlywayMigrationStrategy.java
index 7748acf..13954c6 100644
--- a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/CustomFlywayMigrationStrategy.java
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/CustomFlywayMigrationStrategy.java
@@ -61,7 +61,7 @@ public class CustomFlywayMigrationStrategy implements FlywayMigrationStrategy {
@Override
public void migrate(Flyway flyway) {
- final boolean newDatabase = isNewDatabase(flyway.getDataSource());
+ final boolean newDatabase = isNewDatabase(flyway.getConfiguration().getDataSource());
if (newDatabase) {
LOGGER.info("First time initializing database...");
} else {
@@ -90,7 +90,7 @@ public class CustomFlywayMigrationStrategy implements FlywayMigrationStrategy {
if (newDatabase && existingLegacyDatabase) {
final LegacyDataSourceFactory legacyDataSourceFactory = new LegacyDataSourceFactory(properties);
final DataSource legacyDataSource = legacyDataSourceFactory.getDataSource();
- final DataSource primaryDataSource = flyway.getDataSource();
+ final DataSource primaryDataSource = flyway.getConfiguration().getDataSource();
migrateData(legacyDataSource, primaryDataSource);
}
}
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/db/DatabaseMetadataService.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java
index 4d32790..de9cf69 100644
--- a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java
@@ -19,16 +19,27 @@ 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.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.db.mapper.BucketEntityRowMapper;
import org.apache.nifi.registry.db.mapper.BucketItemEntityRowMapper;
+import org.apache.nifi.registry.db.mapper.ExtensionBundleEntityRowMapper;
+import org.apache.nifi.registry.db.mapper.ExtensionBundleEntityWithBucketNameRowMapper;
+import org.apache.nifi.registry.db.mapper.ExtensionBundleVersionDependencyEntityRowMapper;
+import org.apache.nifi.registry.db.mapper.ExtensionBundleVersionEntityRowMapper;
+import org.apache.nifi.registry.db.mapper.ExtensionEntityRowMapper;
import org.apache.nifi.registry.db.mapper.FlowEntityRowMapper;
import org.apache.nifi.registry.db.mapper.FlowSnapshotEntityRowMapper;
import org.apache.nifi.registry.service.MetadataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
import java.util.ArrayList;
@@ -84,19 +95,7 @@ public class DatabaseMetadataService implements MetadataService {
@Override
public void deleteBucket(final BucketEntity bucket) {
- final String snapshotDeleteSql = "DELETE FROM flow_snapshot WHERE flow_id IN ( " +
- "SELECT f.id FROM flow f, bucket_item item WHERE f.id = item.id AND item.bucket_id = ?" +
- ")";
- jdbcTemplate.update(snapshotDeleteSql, bucket.getId());
-
- final String flowDeleteSql = "DELETE FROM flow WHERE id IN ( " +
- "SELECT f.id FROM flow f, bucket_item item WHERE f.id = item.id AND item.bucket_id = ?" +
- ")";
- jdbcTemplate.update(flowDeleteSql, bucket.getId());
-
- final String itemDeleteSql = "DELETE FROM bucket_item WHERE bucket_id = ?";
- jdbcTemplate.update(itemDeleteSql, bucket.getId());
-
+ // NOTE: Cascading deletes will delete from all child tables
final String sql = "DELETE FROM bucket WHERE id = ?";
jdbcTemplate.update(sql, bucket.getId());
}
@@ -128,25 +127,26 @@ public class DatabaseMetadataService implements MetadataService {
//----------------- BucketItems ---------------------------------
+ private static final String BASE_BUCKET_ITEMS_SQL =
+ "SELECT " +
+ "item.id as ID, " +
+ "item.name as NAME, " +
+ "item.description as DESCRIPTION, " +
+ "item.created as CREATED, " +
+ "item.modified as MODIFIED, " +
+ "item.item_type as ITEM_TYPE, " +
+ "b.id as BUCKET_ID, " +
+ "b.name as BUCKET_NAME ," +
+ "eb.bundle_type as BUNDLE_TYPE, " +
+ "eb.group_id as BUNDLE_GROUP_ID, " +
+ "eb.artifact_id as BUNDLE_ARTIFACT_ID " +
+ "FROM bucket_item item " +
+ "INNER JOIN bucket b ON item.bucket_id = b.id " +
+ "LEFT JOIN extension_bundle eb ON item.id = eb.id ";
+
@Override
public List<BucketItemEntity> getBucketItems(final String bucketIdentifier) {
- final String sql =
- "SELECT " +
- "item.id as ID, " +
- "item.name as NAME, " +
- "item.description as DESCRIPTION, " +
- "item.created as CREATED, " +
- "item.modified as MODIFIED, " +
- "item.item_type as ITEM_TYPE, " +
- "b.id as BUCKET_ID, " +
- "b.name as BUCKET_NAME " +
- "FROM " +
- "bucket_item item, bucket b " +
- "WHERE " +
- "item.bucket_id = b.id " +
- "AND " +
- "item.bucket_id = ?";
-
+ final String sql = BASE_BUCKET_ITEMS_SQL + " WHERE item.bucket_id = ?";
final List<BucketItemEntity> items = jdbcTemplate.query(sql, new Object[] { bucketIdentifier }, new BucketItemEntityRowMapper());
return getItemsWithCounts(items);
}
@@ -157,23 +157,7 @@ public class DatabaseMetadataService implements MetadataService {
return Collections.emptyList();
}
- final StringBuilder sqlBuilder = new StringBuilder(
- "SELECT " +
- "item.id as ID, " +
- "item.name as NAME, " +
- "item.description as DESCRIPTION, " +
- "item.created as CREATED, " +
- "item.modified as MODIFIED, " +
- "item.item_type as ITEM_TYPE, " +
- "b.id as BUCKET_ID, " +
- "b.name as BUCKET_NAME " +
- "FROM " +
- "bucket_item item, bucket b " +
- "WHERE " +
- "item.bucket_id = b.id " +
- "AND " +
- "item.bucket_id IN (");
-
+ final StringBuilder sqlBuilder = new StringBuilder(BASE_BUCKET_ITEMS_SQL + " WHERE item.bucket_id IN (");
for (int i=0; i < bucketIds.size(); i++) {
if (i > 0) {
sqlBuilder.append(", ");
@@ -188,6 +172,7 @@ public class DatabaseMetadataService implements MetadataService {
private List<BucketItemEntity> getItemsWithCounts(final Iterable<BucketItemEntity> items) {
final Map<String,Long> snapshotCounts = getFlowSnapshotCounts();
+ final Map<String,Long> extensionBundleVersionCounts = getExtensionBundleVersionCounts();
final List<BucketItemEntity> itemWithCounts = new ArrayList<>();
for (final BucketItemEntity item : items) {
@@ -197,6 +182,12 @@ public class DatabaseMetadataService implements MetadataService {
final FlowEntity flowEntity = (FlowEntity) item;
flowEntity.setSnapshotCount(snapshotCount);
}
+ } else if (item.getType() == BucketItemEntityType.EXTENSION_BUNDLE) {
+ final Long versionCount = extensionBundleVersionCounts.get(item.getId());
+ if (versionCount != null) {
+ final ExtensionBundleEntity extensionBundleEntity = (ExtensionBundleEntity) item;
+ extensionBundleEntity.setVersionCount(versionCount);
+ }
}
itemWithCounts.add(item);
@@ -223,6 +214,24 @@ public class DatabaseMetadataService implements MetadataService {
});
}
+ private Map<String,Long> getExtensionBundleVersionCounts() {
+ final String sql = "SELECT extension_bundle_id, count(*) FROM extension_bundle_version GROUP BY extension_bundle_id";
+
+ final Map<String,Long> results = new HashMap<>();
+ jdbcTemplate.query(sql, (rs) -> {
+ results.put(rs.getString(1), rs.getLong(2));
+ });
+ return results;
+ }
+
+ private Long getExtensionBundleVersionCount(final String extensionBundleIdentifier) {
+ final String sql = "SELECT count(*) FROM extension_bundle_version WHERE extension_bundle_id = ?";
+
+ return jdbcTemplate.queryForObject(sql, new Object[] {extensionBundleIdentifier}, (rs, num) -> {
+ return rs.getLong(1);
+ });
+ }
+
//----------------- Flows ---------------------------------
@Override
@@ -309,12 +318,7 @@ public class DatabaseMetadataService implements MetadataService {
@Override
public void deleteFlow(final FlowEntity flow) {
- final String snapshotDeleteSql = "DELETE FROM flow_snapshot WHERE flow_id = ?";
- jdbcTemplate.update(snapshotDeleteSql, flow.getId());
-
- final String flowDeleteSql = "DELETE FROM flow WHERE id = ?";
- jdbcTemplate.update(flowDeleteSql, flow.getId());
-
+ // NOTE: Cascading deletes will delete from child tables
final String itemDeleteSql = "DELETE FROM bucket_item WHERE id = ?";
jdbcTemplate.update(itemDeleteSql, flow.getId());
}
@@ -401,7 +405,456 @@ public class DatabaseMetadataService implements MetadataService {
jdbcTemplate.update(sql, flowSnapshot.getFlowId(), flowSnapshot.getVersion());
}
- //----------------- BucketItems ---------------------------------
+ //----------------- Extension Bundles ---------------------------------
+
+ @Override
+ public ExtensionBundleEntity createExtensionBundle(final ExtensionBundleEntity extensionBundle) {
+ final String itemSql =
+ "INSERT INTO bucket_item (" +
+ "ID, " +
+ "NAME, " +
+ "DESCRIPTION, " +
+ "CREATED, " +
+ "MODIFIED, " +
+ "ITEM_TYPE, " +
+ "BUCKET_ID) " +
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
+
+ jdbcTemplate.update(itemSql,
+ extensionBundle.getId(),
+ extensionBundle.getName(),
+ extensionBundle.getDescription(),
+ extensionBundle.getCreated(),
+ extensionBundle.getModified(),
+ extensionBundle.getType().toString(),
+ extensionBundle.getBucketId());
+
+ final String bundleSql =
+ "INSERT INTO extension_bundle (" +
+ "ID, " +
+ "BUCKET_ID, " +
+ "BUNDLE_TYPE, " +
+ "GROUP_ID, " +
+ "ARTIFACT_ID) " +
+ "VALUES (?, ?, ?, ?, ?)";
+
+ jdbcTemplate.update(bundleSql,
+ extensionBundle.getId(),
+ extensionBundle.getBucketId(),
+ extensionBundle.getBundleType().toString(),
+ extensionBundle.getGroupId(),
+ extensionBundle.getArtifactId());
+
+ return extensionBundle;
+ }
+
+ @Override
+ public ExtensionBundleEntity getExtensionBundle(final String extensionBundleId) {
+ final String sql =
+ "SELECT * " +
+ "FROM extension_bundle eb, bucket_item item " +
+ "WHERE eb.id = ? AND item.id = eb.id";
+ try {
+ final ExtensionBundleEntity entity = jdbcTemplate.queryForObject(sql, new ExtensionBundleEntityRowMapper(), extensionBundleId);
+
+ final Long versionCount = getExtensionBundleVersionCount(extensionBundleId);
+ if (versionCount != null) {
+ entity.setVersionCount(versionCount);
+ }
+
+ return entity;
+ } catch (EmptyResultDataAccessException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public ExtensionBundleEntity getExtensionBundle(final String bucketId, final String groupId, final String artifactId) {
+ final String sql =
+ "SELECT * " +
+ "FROM " +
+ "extension_bundle eb, " +
+ "bucket_item item " +
+ "WHERE " +
+ "item.id = eb.id AND " +
+ "eb.bucket_id = ? AND " +
+ "eb.group_id = ? AND " +
+ "eb.artifact_id = ?";
+ try {
+ final ExtensionBundleEntity entity = jdbcTemplate.queryForObject(sql, new ExtensionBundleEntityRowMapper(), bucketId, groupId, artifactId);
+
+ final Long versionCount = getExtensionBundleVersionCount(entity.getId());
+ if (versionCount != null) {
+ entity.setVersionCount(versionCount);
+ }
+
+ return entity;
+ } catch (EmptyResultDataAccessException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public List<ExtensionBundleEntity> getExtensionBundles(final Set<String> bucketIds) {
+ if (bucketIds == null || bucketIds.isEmpty()) {
+ return Collections.emptyList();
+ }
+
+ final String selectSql =
+ "SELECT " +
+ "item.id as ID, " +
+ "item.name as NAME, " +
+ "item.description as DESCRIPTION, " +
+ "item.created as CREATED, " +
+ "item.modified as MODIFIED, " +
+ "item.item_type as ITEM_TYPE, " +
+ "b.id as BUCKET_ID, " +
+ "b.name as BUCKET_NAME ," +
+ "eb.bundle_type as BUNDLE_TYPE, " +
+ "eb.group_id as BUNDLE_GROUP_ID, " +
+ "eb.artifact_id as BUNDLE_ARTIFACT_ID " +
+ "FROM " +
+ "extension_bundle eb, " +
+ "bucket_item item, " +
+ "bucket b " +
+ "WHERE " +
+ "item.id = eb.id AND " +
+ "b.id = item.bucket_id";
+
+ final StringBuilder sqlBuilder = new StringBuilder(selectSql).append(" AND item.bucket_id IN (");
+ for (int i=0; i < bucketIds.size(); i++) {
+ if (i > 0) {
+ sqlBuilder.append(", ");
+ }
+ sqlBuilder.append("?");
+ }
+ sqlBuilder.append(") ");
+ sqlBuilder.append("ORDER BY eb.group_id ASC, eb.artifact_id ASC");
+
+ final List<ExtensionBundleEntity> bundleEntities = jdbcTemplate.query(sqlBuilder.toString(), bucketIds.toArray(), new ExtensionBundleEntityWithBucketNameRowMapper());
+ return populateVersionCounts(bundleEntities);
+ }
+
+ @Override
+ public List<ExtensionBundleEntity> getExtensionBundlesByBucket(final String bucketId) {
+ final String sql =
+ "SELECT * " +
+ "FROM " +
+ "extension_bundle eb, " +
+ "bucket_item item " +
+ "WHERE " +
+ "item.id = eb.id AND " +
+ "item.bucket_id = ? " +
+ "ORDER BY eb.group_id ASC, eb.artifact_id ASC";
+
+ final List<ExtensionBundleEntity> bundles = jdbcTemplate.query(sql, new Object[]{bucketId}, new ExtensionBundleEntityRowMapper());
+ return populateVersionCounts(bundles);
+ }
+
+ @Override
+ public List<ExtensionBundleEntity> getExtensionBundlesByBucketAndGroup(String bucketId, String groupId) {
+ final String sql =
+ "SELECT * " +
+ "FROM " +
+ "extension_bundle eb, " +
+ "bucket_item item " +
+ "WHERE " +
+ "item.id = eb.id AND " +
+ "item.bucket_id = ? AND " +
+ "eb.group_id = ?" +
+ "ORDER BY eb.group_id ASC, eb.artifact_id ASC";
+
+ final List<ExtensionBundleEntity> bundles = jdbcTemplate.query(sql, new Object[]{bucketId, groupId}, new ExtensionBundleEntityRowMapper());
+ return populateVersionCounts(bundles);
+ }
+
+ private List<ExtensionBundleEntity> populateVersionCounts(final List<ExtensionBundleEntity> bundles) {
+ if (!bundles.isEmpty()) {
+ final Map<String, Long> versionCounts = getExtensionBundleVersionCounts();
+ for (final ExtensionBundleEntity entity : bundles) {
+ final Long versionCount = versionCounts.get(entity.getId());
+ if (versionCount != null) {
+ entity.setVersionCount(versionCount);
+ }
+ }
+ }
+
+ return bundles;
+ }
+
+ @Override
+ public void deleteExtensionBundle(final ExtensionBundleEntity extensionBundle) {
+ deleteExtensionBundle(extensionBundle.getId());
+ }
+
+ @Override
+ public void deleteExtensionBundle(final String extensionBundleId) {
+ // NOTE: All of the foreign key constraints for extension related tables are set to cascade on delete
+ final String itemDeleteSql = "DELETE FROM bucket_item WHERE id = ?";
+ jdbcTemplate.update(itemDeleteSql, extensionBundleId);
+ }
+
+ //----------------- Extension Bundle Versions ---------------------------------
+
+ @Override
+ public ExtensionBundleVersionEntity createExtensionBundleVersion(final ExtensionBundleVersionEntity extensionBundleVersion) {
+ final String sql =
+ "INSERT INTO extension_bundle_version (" +
+ "ID, " +
+ "EXTENSION_BUNDLE_ID, " +
+ "VERSION, " +
+ "CREATED, " +
+ "CREATED_BY, " +
+ "DESCRIPTION, " +
+ "SHA_256_HEX, " +
+ "SHA_256_SUPPLIED " +
+ ") VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
+
+ jdbcTemplate.update(sql,
+ extensionBundleVersion.getId(),
+ extensionBundleVersion.getExtensionBundleId(),
+ extensionBundleVersion.getVersion(),
+ extensionBundleVersion.getCreated(),
+ extensionBundleVersion.getCreatedBy(),
+ extensionBundleVersion.getDescription(),
+ extensionBundleVersion.getSha256Hex(),
+ extensionBundleVersion.getSha256Supplied() ? 1 : 0);
+
+ return extensionBundleVersion;
+ }
+
+ @Override
+ public ExtensionBundleVersionEntity getExtensionBundleVersion(final String extensionBundleId, final String version) {
+ final String sql =
+ "SELECT * " +
+ "FROM extension_bundle_version " +
+ "WHERE extension_bundle_id = ? AND version = ?";
+
+ try {
+ return jdbcTemplate.queryForObject(sql, new ExtensionBundleVersionEntityRowMapper(), extensionBundleId, version);
+ } catch (EmptyResultDataAccessException e) {
+ return null;
+ }
+ }
+
+ private static final String BASE_EXTENSION_BUNDLE_SQL =
+ "SELECT " +
+ "ebv.id AS ID," +
+ "ebv.extension_bundle_id AS EXTENSION_BUNDLE_ID, " +
+ "ebv.version AS VERSION, " +
+ "ebv.created AS CREATED, " +
+ "ebv.created_by AS CREATED_BY, " +
+ "ebv.description AS DESCRIPTION, " +
+ "ebv.sha_256_hex AS SHA_256_HEX, " +
+ "ebv.sha_256_supplied AS SHA_256_SUPPLIED " +
+ "FROM extension_bundle eb, extension_bundle_version ebv " +
+ "WHERE eb.id = ebv.extension_bundle_id ";
+
+ @Override
+ public ExtensionBundleVersionEntity getExtensionBundleVersion(final String bucketId, final String groupId, final String artifactId, final String version) {
+ final String sql = BASE_EXTENSION_BUNDLE_SQL +
+ "AND eb.bucket_id = ? " +
+ "AND eb.group_id = ? " +
+ "AND eb.artifact_id = ? " +
+ "AND ebv.version = ?";
+
+ try {
+ return jdbcTemplate.queryForObject(sql, new ExtensionBundleVersionEntityRowMapper(), bucketId, groupId, artifactId, version);
+ } catch (EmptyResultDataAccessException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public List<ExtensionBundleVersionEntity> getExtensionBundleVersions(final String extensionBundleId) {
+ final String sql = "SELECT * FROM extension_bundle_version WHERE extension_bundle_id = ?";
+ return jdbcTemplate.query(sql, new Object[]{extensionBundleId}, new ExtensionBundleVersionEntityRowMapper());
+ }
+
+ @Override
+ public List<ExtensionBundleVersionEntity> getExtensionBundleVersions(final String bucketId, final String groupId, final String artifactId) {
+ final String sql = BASE_EXTENSION_BUNDLE_SQL +
+ "AND eb.bucket_id = ? " +
+ "AND eb.group_id = ? " +
+ "AND eb.artifact_id = ? ";
+
+ final Object[] args = {bucketId, groupId, artifactId};
+ return jdbcTemplate.query(sql, args, new ExtensionBundleVersionEntityRowMapper());
+ }
+
+ @Override
+ public List<ExtensionBundleVersionEntity> getExtensionBundleVersionsGlobal(final String groupId, final String artifactId, final String version) {
+ final String sql = BASE_EXTENSION_BUNDLE_SQL +
+ "AND eb.group_id = ? " +
+ "AND eb.artifact_id = ? " +
+ "AND ebv.version = ?";
+
+ final Object[] args = {groupId, artifactId, version};
+ return jdbcTemplate.query(sql, args, new ExtensionBundleVersionEntityRowMapper());
+ }
+
+ @Override
+ public void deleteExtensionBundleVersion(final ExtensionBundleVersionEntity extensionBundleVersion) {
+ deleteExtensionBundleVersion(extensionBundleVersion.getId());
+ }
+
+ @Override
+ public void deleteExtensionBundleVersion(final String extensionBundleVersionId) {
+ // NOTE: All of the foreign key constraints for extension related tables are set to cascade on delete
+ final String sql = "DELETE FROM extension_bundle_version WHERE id = ?";
+ jdbcTemplate.update(sql, extensionBundleVersionId);
+ }
+
+ //------------ Extension Bundle Version Dependencies ------------
+
+ @Override
+ public ExtensionBundleVersionDependencyEntity createDependency(final ExtensionBundleVersionDependencyEntity dependencyEntity) {
+ final String dependencySql =
+ "INSERT INTO extension_bundle_version_dependency (" +
+ "ID, " +
+ "EXTENSION_BUNDLE_VERSION_ID, " +
+ "GROUP_ID, " +
+ "ARTIFACT_ID, " +
+ "VERSION " +
+ ") VALUES (?, ?, ?, ?, ?)";
+
+ jdbcTemplate.update(dependencySql,
+ dependencyEntity.getId(),
+ dependencyEntity.getExtensionBundleVersionId(),
+ dependencyEntity.getGroupId(),
+ dependencyEntity.getArtifactId(),
+ dependencyEntity.getVersion());
+
+ return dependencyEntity;
+ }
+
+ @Override
+ public List<ExtensionBundleVersionDependencyEntity> getDependenciesForBundleVersion(final String extensionBundleVersionId) {
+ final String sql = "SELECT * FROM extension_bundle_version_dependency WHERE extension_bundle_version_id = ?";
+ final Object[] args = {extensionBundleVersionId};
+ return jdbcTemplate.query(sql, args, new ExtensionBundleVersionDependencyEntityRowMapper());
+ }
+
+
+ //----------------- Extensions ---------------------------------
+
+ @Override
+ public ExtensionEntity createExtension(final ExtensionEntity extension) {
+ final String insertExtensionSql =
+ "INSERT INTO extension (" +
+ "ID, " +
+ "EXTENSION_BUNDLE_VERSION_ID, " +
+ "TYPE, " +
+ "TYPE_DESCRIPTION, " +
+ "IS_RESTRICTED, " +
+ "CATEGORY, " +
+ "TAGS " +
+ ") VALUES (?, ?, ?, ?, ?, ?, ?)";
+
+ jdbcTemplate.update(insertExtensionSql,
+ extension.getId(),
+ extension.getExtensionBundleVersionId(),
+ extension.getType(),
+ extension.getTypeDescription(),
+ extension.isRestricted() ? 1 : 0,
+ extension.getCategory().toString(),
+ extension.getTags()
+ );
+
+ final String insertTagSql = "INSERT INTO extension_tag (EXTENSION_ID, TAG) VALUES (?, ?);";
+
+ if (extension.getTags() != null) {
+ final String tags[] = extension.getTags().split("[,]");
+ for (final String tag : tags) {
+ if (tag != null) {
+ jdbcTemplate.update(insertTagSql, extension.getId(), tag.trim().toLowerCase());
+ }
+ }
+ }
+
+ return extension;
+ }
+
+ @Override
+ public ExtensionEntity getExtensionById(final String id) {
+ final String selectSql = "SELECT * FROM extension WHERE id = ?";
+ try {
+ return jdbcTemplate.queryForObject(selectSql, new ExtensionEntityRowMapper(), id);
+ } catch (EmptyResultDataAccessException e) {
+ return null;
+ }
+ }
+
+ @Override
+ public List<ExtensionEntity> getAllExtensions() {
+ final String selectSql = "SELECT * FROM extension ORDER BY type ASC";
+ return jdbcTemplate.query(selectSql, new ExtensionEntityRowMapper());
+ }
+
+ @Override
+ public List<ExtensionEntity> getExtensionsByBundleVersionId(final String extensionBundleVersionId) {
+ final String selectSql =
+ "SELECT * " +
+ "FROM extension " +
+ "WHERE extension_bundle_version_id = ?";
+
+ final Object[] args = { extensionBundleVersionId };
+ return jdbcTemplate.query(selectSql, args, new ExtensionEntityRowMapper());
+ }
+
+ @Override
+ public List<ExtensionEntity> getExtensionsByBundleCoordinate(final String bucketId, final String groupId, final String artifactId, final String version) {
+ final String sql =
+ "SELECT * " +
+ "FROM extension_bundle eb, extension_bundle_version ebv, extension e " +
+ "WHERE eb.id = ebv.extension_bundle_id " +
+ "AND ebv.id = e.extension_bundle_version_id " +
+ "AND eb.bucket_id = ? " +
+ "AND eb.group_id = ? " +
+ "AND eb.artifact_id = ? " +
+ "AND ebv.version = ?";
+
+ final Object[] args = { bucketId, groupId, artifactId, version };
+ return jdbcTemplate.query(sql, args, new ExtensionEntityRowMapper());
+ }
+
+ @Override
+ public List<ExtensionEntity> getExtensionsByCategory(final ExtensionEntityCategory category) {
+ final String selectSql = "SELECT * FROM extension WHERE category = ?";
+ final Object[] args = { category.toString() };
+ return jdbcTemplate.query(selectSql, args, new ExtensionEntityRowMapper());
+ }
+
+ @Override
+ public List<ExtensionEntity> getExtensionsByTag(final String tag) {
+ final String selectSql =
+ "SELECT * " +
+ "FROM extension e, extension_tag et " +
+ "WHERE e.id = et.extension_id AND et.tag = ?";
+
+ final Object[] args = { tag };
+ return jdbcTemplate.query(selectSql, args, new ExtensionEntityRowMapper());
+ }
+
+ @Override
+ public Set<String> getAllExtensionTags() {
+ final String selectSql = "SELECT DISTINCT tag FROM extension_tag ORDER BY tag ASC";
+
+ final Set<String> tags = new LinkedHashSet<>();
+ final RowCallbackHandler handler = (rs) -> tags.add(rs.getString(1));
+ jdbcTemplate.query(selectSql, handler);
+ return tags;
+ }
+
+ @Override
+ public void deleteExtension(final ExtensionEntity extension) {
+ // NOTE: All of the foreign key constraints for extension related tables are set to cascade on delete
+ final String deleteSql = "DELETE FROM extension WHERE id = ?";
+ jdbcTemplate.update(deleteSql, extension.getId());
+ }
+
+
+ //----------------- Fields ---------------------------------
@Override
public Set<String> getBucketFields() {
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/db/entity/BucketItemEntityType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntityType.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntityType.java
index e78b2b1..2bbdd7c 100644
--- a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntityType.java
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntityType.java
@@ -21,7 +21,10 @@ package org.apache.nifi.registry.db.entity;
*/
public enum BucketItemEntityType {
- FLOW(Values.FLOW);
+ FLOW(Values.FLOW),
+
+ EXTENSION_BUNDLE(Values.EXTENSION_BUNDLE);
+
private final String value;
@@ -37,6 +40,7 @@ public enum BucketItemEntityType {
// need these constants to reference from @DiscriminatorValue
public static class Values {
public static final String FLOW = "FLOW";
+ public static final String EXTENSION_BUNDLE = "EXTENSION_BUNDLE";
}
}
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/db/entity/ExtensionBundleEntity.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleEntity.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleEntity.java
new file mode 100644
index 0000000..f79d385
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleEntity.java
@@ -0,0 +1,73 @@
+/*
+ * 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.db.entity;
+
+public class ExtensionBundleEntity extends BucketItemEntity {
+
+ private String groupId;
+
+ private String artifactId;
+
+ private ExtensionBundleEntityType bundleType;
+
+ private long versionCount;
+
+ public ExtensionBundleEntity() {
+ setType(BucketItemEntityType.EXTENSION_BUNDLE);
+ }
+
+ public ExtensionBundleEntityType getBundleType() {
+ return bundleType;
+ }
+
+ public void setBundleType(ExtensionBundleEntityType bundleType) {
+ this.bundleType = bundleType;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public long getVersionCount() {
+ return versionCount;
+ }
+
+ public void setVersionCount(long versionCount) {
+ this.versionCount = versionCount;
+ }
+
+ @Override
+ public void setType(BucketItemEntityType type) {
+ if (BucketItemEntityType.EXTENSION_BUNDLE != type) {
+ throw new IllegalStateException("Must set type to " + BucketItemEntityType.Values.EXTENSION_BUNDLE);
+ }
+ super.setType(type);
+ }
+
+}
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/db/entity/ExtensionBundleEntityType.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleEntityType.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleEntityType.java
new file mode 100644
index 0000000..0f4950c
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleEntityType.java
@@ -0,0 +1,28 @@
+/*
+ * 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.db.entity;
+
+/**
+ * The possible types of extension bundles.
+ */
+public enum ExtensionBundleEntityType {
+
+ NIFI_NAR,
+
+ MINIFI_CPP;
+
+}
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/db/entity/ExtensionBundleVersionDependencyEntity.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleVersionDependencyEntity.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleVersionDependencyEntity.java
new file mode 100644
index 0000000..e6e2010
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleVersionDependencyEntity.java
@@ -0,0 +1,73 @@
+/*
+ * 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.db.entity;
+
+public class ExtensionBundleVersionDependencyEntity {
+
+ // Database id for this specific dependency
+ private String id;
+
+ // Foreign key to the extension bundle version this dependency goes with
+ private String extensionBundleVersionId;
+
+ // The bundle coordinates for this dependency
+ private String groupId;
+ private String artifactId;
+ private String version;
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getExtensionBundleVersionId() {
+ return extensionBundleVersionId;
+ }
+
+ public void setExtensionBundleVersionId(String extensionBundleVersionId) {
+ this.extensionBundleVersionId = extensionBundleVersionId;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public void setGroupId(String groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public void setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+}
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/db/entity/ExtensionBundleVersionEntity.java
----------------------------------------------------------------------
diff --git a/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleVersionEntity.java b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleVersionEntity.java
new file mode 100644
index 0000000..08fc2c2
--- /dev/null
+++ b/nifi-registry-core/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/ExtensionBundleVersionEntity.java
@@ -0,0 +1,107 @@
+/*
+ * 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.db.entity;
+
+import java.util.Date;
+
+public class ExtensionBundleVersionEntity {
+
+ // Database id for this specific version of an extension bundle
+ private String id;
+
+ // Foreign key to the extension bundle this version goes with
+ private String extensionBundleId;
+
+ // The version of this bundle
+ private String version;
+
+ // General info about this version of the bundle
+ private Date created;
+ private String createdBy;
+ private String description;
+
+ // The hex representation of the SHA-256 digest for the binary content of this version
+ private String sha256Hex;
+
+ // Indicates whether the SHA-256 was supplied by the client, which means it matched the server's calculation, or was not supplied by the client
+ private boolean sha256Supplied;
+
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getExtensionBundleId() {
+ return extensionBundleId;
+ }
+
+ public void setExtensionBundleId(String extensionBundleId) {
+ this.extensionBundleId = extensionBundleId;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public Date getCreated() {
+ return created;
+ }
+
+ public void setCreated(Date created) {
+ this.created = created;
+ }
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getSha256Hex() {
+ return sha256Hex;
+ }
+
+ public void setSha256Hex(String sha256Hex) {
+ this.sha256Hex = sha256Hex;
+ }
+
+ public boolean getSha256Supplied() {
+ return sha256Supplied;
+ }
+
+ public void setSha256Supplied(boolean sha256Supplied) {
+ this.sha256Supplied = sha256Supplied;
+ }
+}