[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r632768175 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +294,42 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Import flow version", +notes = "Import the next version of a flow. The version number of the object being created will be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@ApiParam("file") final VersionedFlowSnapshot versionedFlowSnapshot, +@HeaderParam("Comments") final String comments) { + +final VersionedFlowSnapshot createdSnapshot = serviceFacade.importVersionedFlowSnapshot(versionedFlowSnapshot, bucketId, flowId, comments); +publish(EventFactory.flowVersionCreated(createdSnapshot)); +return Response.status(Response.Status.CREATED).entity(createdSnapshot).build(); Review comment: @exceptionfactory I've added the header. Thanks! -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r631410991 ## File path: nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/dialogs/download-versioned-flow/nf-registry-download-versioned-flow.js ## @@ -0,0 +1,96 @@ +/* + * 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. + */ + +import { Component } from '@angular/core'; +import NfRegistryApi from 'services/nf-registry.api'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { FdsSnackBarService } from '@nifi-fds/core'; + +/** + * NfRegistryDownloadVersionedFlow constructor. + * + * @param nfRegistryApi The api service. + * @param fdsSnackBarServiceThe FDS snack bar service module. + * @param matDialogRef The angular material dialog ref. + * @param data The data passed into this component. + * @constructor + */ +function NfRegistryDownloadVersionedFlow(nfRegistryApi, fdsSnackBarService, matDialogRef, data) { +// Services +this.snackBarService = fdsSnackBarService; +this.nfRegistryApi = nfRegistryApi; +this.dialogRef = matDialogRef; +// local state +this.keepDialogOpen = false; +this.protocol = location.protocol; +this.droplet = data.droplet; +this.selectedVersion = this.droplet.snapshotMetadata[0].version; +} + +NfRegistryDownloadVersionedFlow.prototype = { +constructor: NfRegistryDownloadVersionedFlow, + +/** + * Download specified versioned flow snapshot. + */ +downloadVersion: function () { +var self = this; +var version = this.selectedVersion; + + this.nfRegistryApi.exportDropletVersionedSnapshot(this.droplet.link.href, version).subscribe(function (response) { +if (!response.status || response.status === 200) { Review comment: @exceptionfactory A successful response has typically been just the response body returned. So, when the body is returned (a success) there will not be a status property. I can see how this could be confusing at first glance and without much context. This if-statement is used throughout the codebase, so I decided to follow the conventions. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r631404406 ## File path: nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js ## @@ -75,6 +75,137 @@ NfRegistryApi.prototype = { ); }, +/** + * Retrieves the specified versioned flow snapshot for an existing droplet the registry has stored. + * + * @param {string} dropletUri The uri of the droplet to request. + * @param {number} versionNumber The version of the flow to request. + * @returns {*} + */ +exportDropletVersionedSnapshot: function (dropletUri, versionNumber) { +var self = this; +var url = '../nifi-registry-api/' + dropletUri + '/versions/' + versionNumber + '/export'; +var options = { +headers: headers, +observe: 'response' +}; + +return this.http.get(url, options).pipe( +map(function (response) { +// export the VersionedFlowSnapshot by creating a hidden anchor element +var stringSnapshot = encodeURIComponent(JSON.stringify(response.body, null, 2)); Review comment: @exceptionfactory Good catch! I can return a `responseType: 'text'` and omit calling `JSON.stringify()`. The file content will not be in pretty print format but that seems ok to me. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r622688442 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { + versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); + versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +// if there are new comments, then set it +// otherwise, keep the original comments +if (!StringUtils.isBlank(comments)) { + versionedFlowSnapshot.getSnapshotMetadata().setComments(comments); +} +} + +return createFlowVersion(bucketId, flowId, versionedFlowSnapshot); +} + +@POST +@Path("import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Create flow", +notes = "Creates a flow in the given bucket. The flow id is created by the server and populated in the returned entity.", +response = VersionedFlow.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response importFlow( Review comment: @bbende I went ahead and removed the `importFlow` method. Now when importing a new flow, a call will first be made to `createFlow`, then another to `importVersionedFlow`. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617195342 ## File path: nifi-registry-core/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/dialogs/import-new-flow/nf-registry-import-new-flow.js ## @@ -0,0 +1,182 @@ +/* + * 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. + */ + +import { Component } from '@angular/core'; + +import NfRegistryApi from 'services/nf-registry.api'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { FdsSnackBarService } from '@nifi-fds/core'; + +/** + * NfRegistryImportNewFlow constructor. + * + * @param nfRegistryApi The api service. + * @param fdsSnackBarServiceThe FDS snack bar service module. + * @param matDialogRef The angular material dialog ref. + * @param data The data passed into this component. + * @constructor + */ +function NfRegistryImportNewFlow(nfRegistryApi, fdsSnackBarService, matDialogRef, data) { +// Services +this.snackBarService = fdsSnackBarService; +this.nfRegistryApi = nfRegistryApi; +this.dialogRef = matDialogRef; +// local state +this.keepDialogOpen = false; +this.protocol = location.protocol; +this.buckets = data.buckets; +this.writableBuckets = []; +this.fileToUpload = null; +this.fileName = null; +this.name = ''; +this.description = ''; +this.selectedBucket = ''; +this.hoverValidity = ''; +this.extensions = 'application/json'; +this.multiple = false; +} + +NfRegistryImportNewFlow.prototype = { +constructor: NfRegistryImportNewFlow, + +ngOnInit: function () { +// only show buckets the user can write +var self = this; +self.writableBuckets = self.filterWritableBuckets(self.buckets); +}, + +//TODO: get from the service instead Review comment: My goal is to have this be like a utility method in Angular service (`nf-registry.service.js`). It would only show the buckets the user is authorized to write. I've been having issues injecting it into this import-new-flow component, so I'm in the middle of troubleshooting that. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617193232 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { + versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); + versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +// if there are new comments, then set it +// otherwise, keep the original comments +if (!StringUtils.isBlank(comments)) { + versionedFlowSnapshot.getSnapshotMetadata().setComments(comments); +} +} + +return createFlowVersion(bucketId, flowId, versionedFlowSnapshot); +} + +@POST +@Path("import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Create flow", +notes = "Creates a flow in the given bucket. The flow id is created by the server and populated in the returned entity.", +response = VersionedFlow.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response importFlow( Review comment: My thought for creating this endpoint was to mainly handle the uploaded file and clear the snapshot metadata. It also made it a bit easier for the frontend to only make one request to the server. I have refactored some logic here to minimize duplicating code. It now returns `createFlowVersion` endpoint. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and us
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617189610 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { + versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); + versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +// if there are new comments, then set it +// otherwise, keep the original comments +if (!StringUtils.isBlank(comments)) { + versionedFlowSnapshot.getSnapshotMetadata().setComments(comments); +} +} + +return createFlowVersion(bucketId, flowId, versionedFlowSnapshot); +} + +@POST +@Path("import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Create flow", +notes = "Creates a flow in the given bucket. The flow id is created by the server and populated in the returned entity.", +response = VersionedFlow.class, Review comment: Changed to VersionedFlowSnapshot. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617189439 ## File path: nifi-registry-core/nifi-registry-web-ui/src/main/webapp/services/nf-registry.api.js ## @@ -75,6 +75,113 @@ NfRegistryApi.prototype = { ); }, +/** + * Retrieves the specified versioned flow snapshot for an existing droplet the registry has stored. + * + * @param {string} dropletUri The uri of the droplet to request. + * @param {number} versionNumber The version of the flow to request. + * @returns {*} + */ +exportDropletVersionedSnapshot: function (dropletUri, versionNumber) { +var self = this; +var url = '../nifi-registry-api/' + dropletUri; +url += '/versions/' + versionNumber + '/export'; Review comment: I don't think it's necessary to split up. I have changed to one line. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617188914 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -385,6 +520,64 @@ public Response getLatestFlowVersionMetadata( return Response.status(Response.Status.OK).entity(latest).build(); } +@GET +@Path("{flowId}/versions/{versionNumber: \\d+}/export") +@Consumes(MediaType.WILDCARD) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Exports specified bucket flow version content", +notes = "Exports the specified version of a flow, including the metadata and content of the flow.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "read"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response exportVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") final String bucketId, +@PathParam("flowId") +@ApiParam("The flow identifier") final String flowId, +@PathParam("versionNumber") +@ApiParam("The version number") final Integer versionNumber) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +if (versionNumber == null) { +throw new IllegalArgumentException("The version number is required."); +} + +final VersionedFlowSnapshot versionedFlowSnapshot = serviceFacade.getFlowSnapshot(bucketId, flowId, versionNumber); + +versionedFlowSnapshot.setFlow(null); +versionedFlowSnapshot.setBucket(null); +versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); + +String attachmentName = "flow-version-" + versionNumber; + +UriUtils.encodePath(attachmentName, StandardCharsets.UTF_8); Review comment: I've removed the encoding. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617188670 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { + versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); + versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +// if there are new comments, then set it +// otherwise, keep the original comments +if (!StringUtils.isBlank(comments)) { + versionedFlowSnapshot.getSnapshotMetadata().setComments(comments); +} +} + +return createFlowVersion(bucketId, flowId, versionedFlowSnapshot); +} + +@POST +@Path("import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Create flow", +notes = "Creates a flow in the given bucket. The flow id is created by the server and populated in the returned entity.", +response = VersionedFlow.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response importFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") final String bucketId, +@FormDataParam("file") final InputStream in, +@FormDataParam("name") final String name, +@FormDataParam("description") final String description) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (Str
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617188536 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { + versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); + versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); Review comment: Good idea - I've changed to use a static variable and removed the duplicate line of code. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617188294 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { + versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); + versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +versionedFlowSnapshot.getSnapshotMetadata().setVersion(-1); +// if there are new comments, then set it +// otherwise, keep the original comments +if (!StringUtils.isBlank(comments)) { + versionedFlowSnapshot.getSnapshotMetadata().setComments(comments); +} +} + +return createFlowVersion(bucketId, flowId, versionedFlowSnapshot); +} + +@POST +@Path("import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Create flow", +notes = "Creates a flow in the given bucket. The flow id is created by the server and populated in the returned entity.", +response = VersionedFlow.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response importFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") final String bucketId, +@FormDataParam("file") final InputStream in, +@FormDataParam("name") final String name, +@FormDataParam("description") final String description) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (Str
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617188040 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -385,6 +520,64 @@ public Response getLatestFlowVersionMetadata( return Response.status(Response.Status.OK).entity(latest).build(); } +@GET +@Path("{flowId}/versions/{versionNumber: \\d+}/export") +@Consumes(MediaType.WILDCARD) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Exports specified bucket flow version content", +notes = "Exports the specified version of a flow, including the metadata and content of the flow.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "read"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response exportVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") final String bucketId, +@PathParam("flowId") +@ApiParam("The flow identifier") final String flowId, +@PathParam("versionNumber") +@ApiParam("The version number") final Integer versionNumber) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +if (versionNumber == null) { +throw new IllegalArgumentException("The version number is required."); +} + +final VersionedFlowSnapshot versionedFlowSnapshot = serviceFacade.getFlowSnapshot(bucketId, flowId, versionNumber); + +versionedFlowSnapshot.setFlow(null); +versionedFlowSnapshot.setBucket(null); +versionedFlowSnapshot.getSnapshotMetadata().setBucketIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setFlowIdentifier(null); +versionedFlowSnapshot.getSnapshotMetadata().setLink(null); + +String attachmentName = "flow-version-" + versionNumber; + +UriUtils.encodePath(attachmentName, StandardCharsets.UTF_8); + +String filename = attachmentName + ".json"; + +final String versionedFlowSnapshotJsonString = serializeToJson(versionedFlowSnapshot); + +return generateOkResponse(versionedFlowSnapshotJsonString).header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=\"%s\"", filename)).build(); Review comment: Agreed that's easier to read. I've made the suggested changes. Thanks! -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617187780 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -385,6 +520,64 @@ public Response getLatestFlowVersionMetadata( return Response.status(Response.Status.OK).entity(latest).build(); } +@GET +@Path("{flowId}/versions/{versionNumber: \\d+}/export") Review comment: I don't think the space is necessary, but decided to follow the format of the other endpoints. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617187478 ## File path: nifi-registry-core/nifi-registry-web-api/pom.xml ## @@ -423,6 +423,16 @@ jjwt 0.7.0 + +com.fasterxml.jackson.core +jackson-databind + + +com.google.protobuf +protobuf-java +3.11.4 +compile + Review comment: Removed - see above comment. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617187404 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -385,6 +520,64 @@ public Response getLatestFlowVersionMetadata( return Response.status(Response.Status.OK).entity(latest).build(); } +@GET +@Path("{flowId}/versions/{versionNumber: \\d+}/export") +@Consumes(MediaType.WILDCARD) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Exports specified bucket flow version content", +notes = "Exports the specified version of a flow, including the metadata and content of the flow.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "read"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}")}) +} +) +@ApiResponses({ +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409)}) +public Response exportVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") final String bucketId, +@PathParam("flowId") +@ApiParam("The flow identifier") final String flowId, +@PathParam("versionNumber") +@ApiParam("The version number") final Integer versionNumber) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +if (versionNumber == null) { +throw new IllegalArgumentException("The version number is required."); +} + +final VersionedFlowSnapshot versionedFlowSnapshot = serviceFacade.getFlowSnapshot(bucketId, flowId, versionNumber); Review comment: I refactored the some of this logic into the service facade. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617187216 ## File path: nifi-registry-core/nifi-registry-web-api/src/main/java/org/apache/nifi/registry/web/api/BucketFlowResource.java ## @@ -291,6 +303,129 @@ public Response createFlowVersion( return Response.status(Response.Status.OK).entity(createdSnapshot).build(); } +@POST +@Path("{flowId}/versions/import") +@Consumes(MediaType.MULTIPART_FORM_DATA) +@Produces(MediaType.APPLICATION_JSON) +@ApiOperation( +value = "Upload flow version", +notes = "Uploads the next version of a flow. The version number of the object being created must be the " + +"next available version integer. Flow versions are immutable after they are created.", +response = VersionedFlowSnapshot.class, +extensions = { +@Extension(name = "access-policy", properties = { +@ExtensionProperty(name = "action", value = "write"), +@ExtensionProperty(name = "resource", value = "/buckets/{bucketId}") }) +} +) +@ApiResponses({ +@ApiResponse(code = 400, message = HttpStatusMessages.MESSAGE_400), +@ApiResponse(code = 401, message = HttpStatusMessages.MESSAGE_401), +@ApiResponse(code = 403, message = HttpStatusMessages.MESSAGE_403), +@ApiResponse(code = 404, message = HttpStatusMessages.MESSAGE_404), +@ApiResponse(code = 409, message = HttpStatusMessages.MESSAGE_409) }) +public Response importVersionedFlow( +@PathParam("bucketId") +@ApiParam("The bucket identifier") +final String bucketId, +@PathParam("flowId") +@ApiParam(value = "The flow identifier") +final String flowId, +@FormDataParam("file") final InputStream in, +@FormDataParam("comments") final String comments) { + +if (StringUtils.isBlank(bucketId)) { +throw new IllegalArgumentException("The bucket identifier is required."); +} + +if (StringUtils.isBlank(flowId)) { +throw new IllegalArgumentException("The flow identifier is required."); +} + +// deserialize InputStream to a VersionedFlowSnapshot +VersionedFlowSnapshot versionedFlowSnapshot; + +versionedFlowSnapshot = deserializeVersionedFlowSnapshot(in); + +// clear or set the necessary snapShotMetadata +if (versionedFlowSnapshot.getSnapshotMetadata() != null) { Review comment: Good idea to set new metadata first - I revised this to create a new snapshotMetadata then set any necessary properties from there. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org
[GitHub] [nifi-registry] mtien-apache commented on a change in pull request #319: NIFIREG-395 - Implemented the ability to import and export versioned flows through the UI
mtien-apache commented on a change in pull request #319: URL: https://github.com/apache/nifi-registry/pull/319#discussion_r617186563 ## File path: nifi-registry-core/nifi-registry-web-api/pom.xml ## @@ -423,6 +423,16 @@ jjwt 0.7.0 + +com.fasterxml.jackson.core +jackson-databind + + +com.google.protobuf +protobuf-java Review comment: Removed - this was accidentally leftover from some previous work. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org