NIFI-4436: - Adding support to save a version of a flow based on a selected Process Group. - Adding support for revert changes back to the most recent version. - Adding support to disconnect from version control. - Moving the version control information out of the entity objects and into the dto's. - Fixing checkstyle issues. NIFI-4502: - Updating the UI to allow for the user to register registry clients. - Updating the version control menu item names.
Project: http://git-wip-us.apache.org/repos/asf/nifi/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi/commit/7a0a900a Tree: http://git-wip-us.apache.org/repos/asf/nifi/tree/7a0a900a Diff: http://git-wip-us.apache.org/repos/asf/nifi/diff/7a0a900a Branch: refs/heads/master Commit: 7a0a900a0ff8b9329296b9a19b9239b63fc2d76d Parents: 6a58d78 Author: Matt Gilman <[email protected]> Authored: Thu Oct 12 12:29:05 2017 -0400 Committer: Bryan Bende <[email protected]> Committed: Mon Jan 8 12:44:52 2018 -0500 ---------------------------------------------------------------------- .../org/apache/nifi/web/api/dto/BucketDTO.java | 69 +++ .../web/api/dto/ControllerConfigurationDTO.java | 1 + .../nifi/web/api/dto/FlowConfigurationDTO.java | 15 + .../apache/nifi/web/api/dto/RegistryDTO.java | 69 +++ .../nifi/web/api/dto/VersionedFlowDTO.java | 10 + .../web/api/dto/flow/FlowBreadcrumbDTO.java | 16 + .../nifi/web/api/entity/BucketEntity.java | 39 ++ .../nifi/web/api/entity/BucketsEntity.java | 41 ++ .../nifi/web/api/entity/RegistriesEntity.java | 41 ++ .../nifi/web/api/entity/RegistryEntity.java | 39 ++ .../entity/VersionControlInformationEntity.java | 6 +- .../org/apache/nifi/groups/ProcessGroup.java | 7 +- .../apache/nifi/registry/flow/FlowRegistry.java | 17 + .../nifi-framework/nifi-framework-core/pom.xml | 5 + .../nifi/groups/StandardProcessGroup.java | 58 ++- .../flow/FileBasedFlowRegistryClient.java | 49 +- .../service/mock/MockProcessGroup.java | 25 +- .../org/apache/nifi/web/NiFiServiceFacade.java | 75 ++- .../nifi/web/NiFiWebApiResourceConfig.java | 1 + .../nifi/web/StandardNiFiServiceFacade.java | 142 ++++-- .../apache/nifi/web/api/ControllerResource.java | 298 ++++++++++++ .../org/apache/nifi/web/api/FlowResource.java | 113 +++++ .../apache/nifi/web/api/VersionsResource.java | 156 +++--- .../api/concurrent/AsynchronousWebRequest.java | 6 +- .../org/apache/nifi/web/api/dto/DtoFactory.java | 74 +-- .../apache/nifi/web/api/dto/EntityFactory.java | 1 + .../apache/nifi/web/dao/ProcessGroupDAO.java | 18 +- .../web/dao/impl/StandardProcessGroupDAO.java | 20 +- .../ClusterReplicationComponentLifecycle.java | 37 +- .../nifi/web/util/LocalComponentLifecycle.java | 16 +- .../src/main/resources/nifi-web-api-context.xml | 3 + .../nifi-framework/nifi-web/nifi-web-ui/pom.xml | 1 + .../main/resources/filters/canvas.properties | 1 + .../src/main/webapp/WEB-INF/pages/canvas.jsp | 2 + .../WEB-INF/partials/canvas/canvas-header.jsp | 16 +- .../canvas/registry-configuration-dialog.jsp | 40 ++ .../canvas/save-flow-version-dialog.jsp | 54 +++ .../partials/canvas/settings-content.jsp | 3 + .../nifi-web-ui/src/main/webapp/css/dialog.css | 16 + .../nifi-web-ui/src/main/webapp/css/graph.css | 8 + .../src/main/webapp/css/navigation.css | 5 + .../controllers/nf-ng-breadcrumbs-controller.js | 15 + .../nf-ng-canvas-graph-controls-controller.js | 2 +- .../src/main/webapp/js/nf/canvas/nf-actions.js | 54 ++- .../webapp/js/nf/canvas/nf-canvas-bootstrap.js | 11 +- .../main/webapp/js/nf/canvas/nf-canvas-utils.js | 11 +- .../src/main/webapp/js/nf/canvas/nf-canvas.js | 18 + .../webapp/js/nf/canvas/nf-component-state.js | 2 +- .../webapp/js/nf/canvas/nf-component-version.js | 2 +- .../main/webapp/js/nf/canvas/nf-context-menu.js | 97 +++- .../main/webapp/js/nf/canvas/nf-flow-version.js | 476 +++++++++++++++++++ .../nf/canvas/nf-process-group-configuration.js | 2 +- .../webapp/js/nf/canvas/nf-process-group.js | 15 + .../src/main/webapp/js/nf/canvas/nf-settings.js | 392 ++++++++++++++- .../views/nf-ng-breadcrumbs-directive-view.html | 1 + 55 files changed, 2465 insertions(+), 246 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java new file mode 100644 index 0000000..3c004c7 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/BucketDTO.java @@ -0,0 +1,69 @@ +/* + * 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.web.api.dto; + +import io.swagger.annotations.ApiModelProperty; + +import javax.xml.bind.annotation.XmlType; + +/** + * Details about a bucket in a registry. + */ +@XmlType(name = "bucket") +public class BucketDTO { + + private String id; + private String name; + private String description; + private Long created; + + @ApiModelProperty("The bucket identifier") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @ApiModelProperty("The bucket name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @ApiModelProperty("The bucket description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @ApiModelProperty("The created timestamp of this bucket") + public Long getCreated() { + return created; + } + + public void setCreated(Long created) { + this.created = created; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java index 61b037f..597d700 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerConfigurationDTO.java @@ -28,6 +28,7 @@ public class ControllerConfigurationDTO { private Integer maxTimerDrivenThreadCount; private Integer maxEventDrivenThreadCount; + private String registryUrl; /** * @return maximum number of timer driven threads this NiFi has available http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java index 657d760..03e1a7d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java @@ -32,6 +32,7 @@ public class FlowConfigurationDTO { private Boolean supportsManagedAuthorizer; private Boolean supportsConfigurableAuthorizer; private Boolean supportsConfigurableUsersAndGroups; + private Boolean supportsFlowVersioning; private Long autoRefreshIntervalSeconds; private Date currentTime; @@ -127,4 +128,18 @@ public class FlowConfigurationDTO { public void setTimeOffset(Integer timeOffset) { this.timeOffset = timeOffset; } + + /** + * @return whether this NiFi is configured for support flow versioning + */ + @ApiModelProperty( + value = "Whether this NiFi supports flow versioning." + ) + public Boolean getSupportsFlowVersioning() { + return supportsFlowVersioning; + } + + public void setSupportsFlowVersioning(Boolean supportsFlowVersioning) { + this.supportsFlowVersioning = supportsFlowVersioning; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java new file mode 100644 index 0000000..f630430 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/RegistryDTO.java @@ -0,0 +1,69 @@ +/* + * 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.web.api.dto; + +import io.swagger.annotations.ApiModelProperty; + +import javax.xml.bind.annotation.XmlType; + +/** + * Details about a configured registry. + */ +@XmlType(name = "registry") +public class RegistryDTO { + + private String id; + private String name; + private String description; + private String uri; + + @ApiModelProperty("The registry identifier") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @ApiModelProperty("The registry name") + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @ApiModelProperty("The registry description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @ApiModelProperty("The registry URI") + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java index 27a83e6..1e1f5f5 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/VersionedFlowDTO.java @@ -28,6 +28,7 @@ public class VersionedFlowDTO { private String flowId; private String flowName; private String description; + private String comments; @ApiModelProperty("The ID of the registry that the flow is tracked to") public String getRegistryId() { @@ -73,4 +74,13 @@ public class VersionedFlowDTO { public void setDescription(String description) { this.description = description; } + + @ApiModelProperty("Comments for the changeset") + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java index 170a30f..60af3fa 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/flow/FlowBreadcrumbDTO.java @@ -17,6 +17,7 @@ package org.apache.nifi.web.api.dto.flow; import io.swagger.annotations.ApiModelProperty; +import org.apache.nifi.web.api.dto.VersionControlInformationDTO; import javax.xml.bind.annotation.XmlType; @@ -28,6 +29,7 @@ public class FlowBreadcrumbDTO { private String id; private String name; + private VersionControlInformationDTO versionControlInformation; /** * The id for this group. @@ -60,4 +62,18 @@ public class FlowBreadcrumbDTO { public void setName(final String name) { this.name = name; } + + /** + * @return the process group version control information or null if not version controlled + */ + @ApiModelProperty( + value = "The process group version control information or null if not version controlled." + ) + public VersionControlInformationDTO getVersionControlInformation() { + return versionControlInformation; + } + + public void setVersionControlInformation(VersionControlInformationDTO versionControlInformation) { + this.versionControlInformation = versionControlInformation; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketEntity.java new file mode 100644 index 0000000..3d99308 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketEntity.java @@ -0,0 +1,39 @@ +/* + * 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.web.api.entity; + +import org.apache.nifi.web.api.dto.BucketDTO; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a BucketDTO. + */ +@XmlRootElement(name = "bucketEntity") +public class BucketEntity extends Entity { + + private BucketDTO bucket; + + + public BucketDTO getBucket() { + return bucket; + } + + public void setBucket(BucketDTO bucket) { + this.bucket = bucket; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketsEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketsEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketsEntity.java new file mode 100644 index 0000000..830c1c2 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/BucketsEntity.java @@ -0,0 +1,41 @@ +/* + * 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.web.api.entity; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Set; + +/** + * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds a reference to a set of BucketEntity's. + */ +@XmlRootElement(name = "bucketsEntity") +public class BucketsEntity extends Entity { + + private Set<BucketEntity> buckets; + + /** + * @return collection of BucketEntity's that are being serialized + */ + public Set<BucketEntity> getBuckets() { + return buckets; + } + + public void setBuckets(Set<BucketEntity> buckets) { + this.buckets = buckets; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistriesEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistriesEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistriesEntity.java new file mode 100644 index 0000000..6705c7a --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistriesEntity.java @@ -0,0 +1,41 @@ +/* + * 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.web.api.entity; + +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Set; + +/** + * A serialized representation of this class can be placed in the entity body of a response to the API. This particular entity holds a reference to a set of RegistryEntity's. + */ +@XmlRootElement(name = "registriesEntity") +public class RegistriesEntity extends Entity { + + private Set<RegistryEntity> registries; + + /** + * @return collection of LabelEntity's that are being serialized + */ + public Set<RegistryEntity> getRegistries() { + return registries; + } + + public void setRegistries(Set<RegistryEntity> registries) { + this.registries = registries; + } + +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistryEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistryEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistryEntity.java new file mode 100644 index 0000000..5968579 --- /dev/null +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/RegistryEntity.java @@ -0,0 +1,39 @@ +/* + * 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.web.api.entity; + +import org.apache.nifi.web.api.dto.RegistryDTO; + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a RegistryDTO. + */ +@XmlRootElement(name = "registryEntity") +public class RegistryEntity extends ComponentEntity { + + private RegistryDTO component; + + + public RegistryDTO getComponent() { + return component; + } + + public void setComponent(RegistryDTO component) { + this.component = component; + } +} http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java index e8ec81f..749a118 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/entity/VersionControlInformationEntity.java @@ -25,16 +25,16 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "versionControlInformationEntity") public class VersionControlInformationEntity extends Entity { - private VersionControlInformationDTO versionControlDto; + private VersionControlInformationDTO versionControlInformation; private RevisionDTO processGroupRevision; @ApiModelProperty("The Version Control information") public VersionControlInformationDTO getVersionControlInformation() { - return versionControlDto; + return versionControlInformation; } public void setVersionControlInformation(VersionControlInformationDTO versionControlDto) { - this.versionControlDto = versionControlDto; + this.versionControlInformation = versionControlDto; } @ApiModelProperty("The Revision for the Process Group") http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java index 8934788..d335461 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/groups/ProcessGroup.java @@ -16,7 +16,6 @@ */ package org.apache.nifi.groups; -import java.io.IOException; import java.util.Collection; import java.util.List; import java.util.Map; @@ -42,7 +41,6 @@ import org.apache.nifi.flowfile.FlowFile; import org.apache.nifi.processor.Processor; import org.apache.nifi.registry.ComponentVariableRegistry; import org.apache.nifi.registry.flow.FlowRegistryClient; -import org.apache.nifi.registry.flow.UnknownResourceException; import org.apache.nifi.registry.flow.VersionControlInformation; import org.apache.nifi.registry.flow.VersionedFlowSnapshot; import org.apache.nifi.remote.RemoteGroupPort; @@ -941,6 +939,11 @@ public interface ProcessGroup extends ComponentAuthorizable, Positionable, Versi void setVersionControlInformation(VersionControlInformation versionControlInformation, Map<String, String> versionedComponentIds); /** + * Disconnects this Process Group from version control. If not currently under version control, this method does nothing. + */ + void disconnectVersionControl(); + + /** * Synchronizes the Process Group with the given Flow Registry, determining whether or not the local flow * is up to date with the newest version of the flow in the Registry and whether or not the local flow has been * modified since it was last synced with the Flow Registry. If this Process Group is not under Version Control, http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java index a5bb738..962a940 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core-api/src/main/java/org/apache/nifi/registry/flow/FlowRegistry.java @@ -17,7 +17,11 @@ package org.apache.nifi.registry.flow; +import org.apache.nifi.authorization.user.NiFiUser; +import org.apache.nifi.registry.bucket.Bucket; + import java.io.IOException; +import java.util.Set; public interface FlowRegistry { @@ -27,6 +31,19 @@ public interface FlowRegistry { String getURL(); /** + * @return the name of the Flow Registry + */ + String getName(); + + /** + * Gets the buckets for the specified user. + * + * @param user current user + * @return buckets for this user + */ + Set<Bucket> getBuckets(NiFiUser user) throws IOException; + + /** * Registers the given Versioned Flow with the Flow Registry * * @param flow the Versioned Flow to add to the registry http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml index 09d032e..6548004 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/pom.xml @@ -160,6 +160,11 @@ <groupId>org.apache.nifi.registry</groupId> <artifactId>nifi-registry-flow-diff</artifactId> </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <version>${jackson.version}</version> + </dependency> <dependency> <groupId>org.apache.curator</groupId> http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java index 282c50d..3b8117b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java @@ -16,30 +16,6 @@ */ package org.apache.nifi.groups; -import static java.util.Objects.requireNonNull; - -import java.io.IOException; -import java.net.URL; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.Function; -import java.util.stream.Collectors; - import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; @@ -133,6 +109,30 @@ import org.apache.nifi.web.api.dto.TemplateDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.IOException; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; +import java.util.stream.Collectors; + +import static java.util.Objects.requireNonNull; + public final class StandardProcessGroup implements ProcessGroup { private final String id; @@ -2835,6 +2835,16 @@ public final class StandardProcessGroup implements ProcessGroup { } } + public void disconnectVersionControl() { + writeLock.lock(); + try { + // TODO remove version component ids from each component (until another versioned PG is encountered) + this.versionControlInfo.set(null); + } finally { + writeLock.unlock(); + } + } + private void updateVersionedComponentIds(final ProcessGroup processGroup, final Map<String, String> versionedComponentIds) { if (versionedComponentIds == null || versionedComponentIds.isEmpty()) { return; http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java index 22ba50b..2cc39c6 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/registry/flow/FileBasedFlowRegistryClient.java @@ -17,6 +17,15 @@ package org.apache.nifi.registry.flow; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.nifi.authorization.user.NiFiUser; +import org.apache.nifi.registry.bucket.Bucket; + import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -35,13 +44,6 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.UUID; -import org.codehaus.jackson.JsonFactory; -import org.codehaus.jackson.JsonGenerator; -import org.codehaus.jackson.JsonParser; -import org.codehaus.jackson.map.DeserializationConfig; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.util.DefaultPrettyPrinter; - /** * A simple file-based implementation of a Flow Registry Client. Rather than interacting * with an actual Flow Registry, this implementation simply reads flows from disk and writes @@ -114,6 +116,35 @@ public class FileBasedFlowRegistryClient implements FlowRegistryClient, FlowRegi } @Override + public String getName() { + return "Local Registry"; + } + + @Override + public Set<Bucket> getBuckets(NiFiUser user) throws IOException { + final Set<Bucket> buckets = new HashSet<>(); + + final File[] bucketDirs = directory.listFiles(); + if (bucketDirs == null) { + throw new IOException("Could not get listing of directory " + directory); + } + + for (final File bucketDirectory : bucketDirs) { + final String bucketIdentifier = bucketDirectory.getName(); + final long creation = bucketDirectory.lastModified(); + + final Bucket bucket = new Bucket(); + bucket.setIdentifier(bucketIdentifier); + bucket.setName("Bucket '" + bucketIdentifier + "'"); + bucket.setCreatedTimestamp(creation); + + buckets.add(bucket); + } + + return buckets; + } + + @Override public synchronized VersionedFlow registerVersionedFlow(final VersionedFlow flow) throws IOException, UnknownResourceException { Objects.requireNonNull(flow); Objects.requireNonNull(flow.getBucketIdentifier()); @@ -303,9 +334,9 @@ public class FileBasedFlowRegistryClient implements FlowRegistryClient, FlowRegi final File contentsFile = new File(versionDir, "flow.xml"); final VersionedProcessGroup processGroup; - try (final JsonParser parser = jsonFactory.createJsonParser(contentsFile)) { + try (final JsonParser parser = jsonFactory.createParser(contentsFile)) { final ObjectMapper mapper = new ObjectMapper(); - mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); parser.setCodec(mapper); processGroup = parser.readValueAs(VersionedProcessGroup.class); http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java index 27e1678..18dc51b 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/test/java/org/apache/nifi/controller/service/mock/MockProcessGroup.java @@ -17,16 +17,6 @@ package org.apache.nifi.controller.service.mock; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.CompletableFuture; - import org.apache.nifi.authorization.Resource; import org.apache.nifi.authorization.resource.Authorizable; import org.apache.nifi.connectable.Connectable; @@ -52,6 +42,16 @@ import org.apache.nifi.registry.flow.VersionedFlowSnapshot; import org.apache.nifi.registry.variable.MutableVariableRegistry; import org.apache.nifi.remote.RemoteGroupPort; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.CompletableFuture; + public class MockProcessGroup implements ProcessGroup { private final Map<String, ControllerServiceNode> serviceMap = new HashMap<>(); private final Map<String, ProcessorNode> processorMap = new HashMap<>(); @@ -661,4 +661,9 @@ public class MockProcessGroup implements ProcessGroup { public void setVersionControlInformation(VersionControlInformation versionControlInformation, Map<String, String> versionedComponentIds) { this.versionControlInfo = versionControlInformation; } + + @Override + public void disconnectVersionControl() { + this.versionControlInfo = null; + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java index 84e582c..a68ad0c 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java @@ -16,14 +16,6 @@ */ package org.apache.nifi.web; -import java.io.IOException; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; - import org.apache.nifi.authorization.AuthorizeAccess; import org.apache.nifi.authorization.RequestAction; import org.apache.nifi.authorization.user.NiFiUser; @@ -31,7 +23,6 @@ import org.apache.nifi.controller.ScheduledState; import org.apache.nifi.controller.repository.claim.ContentDirection; import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.groups.ProcessGroup; -import org.apache.nifi.registry.flow.FlowRegistryClient; import org.apache.nifi.registry.flow.UnknownResourceException; import org.apache.nifi.registry.flow.VersionedFlow; import org.apache.nifi.registry.flow.VersionedFlowSnapshot; @@ -62,6 +53,7 @@ import org.apache.nifi.web.api.dto.PortDTO; import org.apache.nifi.web.api.dto.ProcessGroupDTO; import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; +import org.apache.nifi.web.api.dto.RegistryDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; import org.apache.nifi.web.api.dto.ReportingTaskDTO; @@ -104,6 +96,7 @@ import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ProcessorEntity; import org.apache.nifi.web.api.entity.ProcessorStatusEntity; +import org.apache.nifi.web.api.entity.RegistryEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; @@ -119,6 +112,14 @@ import org.apache.nifi.web.api.entity.VersionControlComponentMappingEntity; import org.apache.nifi.web.api.entity.VersionControlInformationEntity; import org.apache.nifi.web.api.entity.VersionedFlowEntity; +import java.io.IOException; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; + /** * Defines the NiFiServiceFacade interface. */ @@ -1320,6 +1321,14 @@ public interface NiFiServiceFacade { VersionControlInformationEntity setVersionControlInformation(Revision processGroupRevision, String processGroupId, VersionControlInformationDTO versionControlInfo, Map<String, String> versionedComponentMapping); + /** + * Disconnects the specified Process Group from version control. + * + * @param revision revision + * @param processGroupId group id + * @return version control information prior to disconnecting + */ + VersionControlInformationEntity deleteVersionControl(final Revision revision, final String processGroupId); /** * Retrieves the Versioned Flow Snapshot for the coordinates provided by the given Version Control Information DTO @@ -1381,8 +1390,6 @@ public interface NiFiServiceFacade { ProcessGroupEntity updateProcessGroup(NiFiUser user, Revision revision, String groupId, VersionControlInformationDTO versionControlInfo, VersionedFlowSnapshot snapshot, String componentIdSeed, boolean verifyNotModified); - void setFlowRegistryClient(FlowRegistryClient flowRegistryClient); - // ---------------------------------------- // Component state methods // ---------------------------------------- @@ -1829,6 +1836,52 @@ public interface NiFiServiceFacade { void verifyDeleteReportingTask(String reportingTaskId); // ---------------------------------------- + // Registry methods + // ---------------------------------------- + + /** + * Creates a registry. + * + * @param revision revision + * @param registryDTO The registry DTO + * @return The reporting task DTO + */ + RegistryEntity createRegistry(Revision revision, RegistryDTO registryDTO); + + /** + * Gets a registry with the specified id. + * + * @param registryId id + * @return entity + */ + RegistryEntity getRegistry(String registryId); + + /** + * Gets all registries. + * + * @return registries + */ + Set<RegistryEntity> getRegistries(); + + /** + * Updates the specified registry using the specified revision. + * + * @param revision revision + * @param registryDTO the registry dto + * @return the updated registry registry entity + */ + RegistryEntity updateRegistry(Revision revision, RegistryDTO registryDTO); + + /** + * Deletes the specified registry using the specified revision. + * + * @param revision revision + * @param registryId id + * @return the deleted registry entity + */ + RegistryEntity deleteRegistry(Revision revision, String registryId); + + // ---------------------------------------- // History methods // ---------------------------------------- /** http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java index 0881cdf..065db86 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiWebApiResourceConfig.java @@ -98,6 +98,7 @@ public class NiFiWebApiResourceConfig extends ResourceConfig { register(ctx.getBean("accessResource")); register(ctx.getBean("accessPolicyResource")); register(ctx.getBean("tenantsResource")); + register(ctx.getBean("versionsResource")); // exception mappers register(AccessDeniedExceptionMapper.class); http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java index d3a5fd0..0105bf1 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java @@ -16,32 +16,7 @@ */ package org.apache.nifi.web; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; - +import com.google.common.collect.Sets; import org.apache.nifi.action.Action; import org.apache.nifi.action.Component; import org.apache.nifi.action.FlowChangeAction; @@ -141,6 +116,7 @@ import org.apache.nifi.reporting.BulletinQuery; import org.apache.nifi.reporting.BulletinRepository; import org.apache.nifi.reporting.ComponentType; import org.apache.nifi.util.NiFiProperties; +import org.apache.nifi.util.Tuple; import org.apache.nifi.web.api.dto.AccessPolicyDTO; import org.apache.nifi.web.api.dto.AccessPolicySummaryDTO; import org.apache.nifi.web.api.dto.AffectedComponentDTO; @@ -179,6 +155,7 @@ import org.apache.nifi.web.api.dto.ProcessorConfigDTO; import org.apache.nifi.web.api.dto.ProcessorDTO; import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; import org.apache.nifi.web.api.dto.PropertyHistoryDTO; +import org.apache.nifi.web.api.dto.RegistryDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; import org.apache.nifi.web.api.dto.ReportingTaskDTO; @@ -236,6 +213,7 @@ import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity; import org.apache.nifi.web.api.entity.ProcessorEntity; import org.apache.nifi.web.api.entity.ProcessorStatusEntity; +import org.apache.nifi.web.api.entity.RegistryEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; @@ -279,7 +257,30 @@ import org.apache.nifi.web.util.SnippetUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.collect.Sets; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; /** * Implementation of NiFiServiceFacade that performs revision checking. @@ -330,6 +331,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { private AuthorizableLookup authorizableLookup; + private Map<String, Tuple<Revision, RegistryDTO>> registryCache = new HashMap<>(); + // ----------------------------------------- // Synchronization methods // ----------------------------------------- @@ -2257,6 +2260,45 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { return entityFactory.createControllerServiceEntity(snapshot, null, permissions, null); } + private RegistryEntity createRegistryEntity(final Revision updatedRevision, final RegistryDTO registryDTO) { + final RegistryEntity entity = new RegistryEntity(); + entity.setId(registryDTO.getId()); + entity.setPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController())); + entity.setRevision(dtoFactory.createRevisionDTO(updatedRevision)); + entity.setComponent(registryDTO); + return entity; + } + + @Override + public RegistryEntity createRegistry(Revision revision, RegistryDTO registryDTO) { + registryCache.put(registryDTO.getId(), new Tuple(revision, registryDTO)); + return createRegistryEntity(revision, registryDTO); + } + + @Override + public RegistryEntity getRegistry(String registryId) { + final Tuple<Revision, RegistryDTO> registry = registryCache.get(registryId); + return createRegistry(registry.getKey(), registry.getValue()); + } + + @Override + public Set<RegistryEntity> getRegistries() { + return registryCache.values().stream() + .map(registry -> createRegistry(registry.getKey(), registry.getValue())) + .collect(Collectors.toSet()); + } + + @Override + public RegistryEntity updateRegistry(Revision revision, RegistryDTO registryDTO) { + registryCache.put(registryDTO.getId(), new Tuple(revision, registryDTO)); + return createRegistryEntity(revision, registryDTO); + } + + @Override + public RegistryEntity deleteRegistry(Revision revision, String registryId) { + final Tuple<Revision, RegistryDTO> registry = registryCache.remove(registryId); + return createRegistryEntity(registry.getKey(), registry.getValue()); + } @Override public ReportingTaskEntity createReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) { @@ -3504,7 +3546,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { return null; } - final VersionControlInformationDTO versionControlDto = dtoFactory.createVersionControlInformationDto(versionControlInfo); + final VersionControlInformationDTO versionControlDto = dtoFactory.createVersionControlInformationDto(processGroup); final RevisionDTO groupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(groupId)); return entityFactory.createVersionControlInformationEntity(versionControlDto, groupRevision); } @@ -3555,7 +3597,19 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { final RevisionUpdate<VersionControlInformationDTO> snapshot = updateComponent(revision, group, () -> processGroupDAO.updateVersionControlInformation(versionControlInfo, versionedComponentMapping), - processGroup -> dtoFactory.createVersionControlInformationDto(processGroup.getVersionControlInformation())); + processGroup -> dtoFactory.createVersionControlInformationDto(processGroup)); + + return entityFactory.createVersionControlInformationEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification())); + } + + @Override + public VersionControlInformationEntity deleteVersionControl(final Revision revision, final String processGroupId) { + final ProcessGroup group = processGroupDAO.getProcessGroup(processGroupId); + + final RevisionUpdate<VersionControlInformationDTO> snapshot = updateComponent(revision, + group, + () -> processGroupDAO.disconnectVersionControl(processGroupId), + processGroup -> dtoFactory.createVersionControlInformationDto(group)); return entityFactory.createVersionControlInformationEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification())); } @@ -3835,12 +3889,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, permissions, status, bulletinEntities); } - - @Override - public void setFlowRegistryClient(final FlowRegistryClient client) { - this.flowRegistryClient = client; - } - private AuthorizationResult authorizeAction(final Action action) { final String sourceId = action.getSourceId(); final Component type = action.getSourceType(); @@ -4194,4 +4242,28 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade { public void setLeaderElectionManager(final LeaderElectionManager leaderElectionManager) { this.leaderElectionManager = leaderElectionManager; } + + public void setFlowRegistryClient(FlowRegistryClient flowRegistryClient) { + this.flowRegistryClient = flowRegistryClient; + + // temp code to load the registry client cache + final Set<String> registryIdentifiers = flowRegistryClient.getRegistryIdentifiers(); + if (registryIdentifiers != null) { + + for (final String registryIdentifier : registryIdentifiers) { + final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(registryIdentifier); + + final RegistryDTO registry = new RegistryDTO(); + registry.setId(registryIdentifier); + registry.setName(flowRegistry.getName()); + registry.setUri(flowRegistry.getURL()); + registry.setDescription("Default client for storing Flow Revisions to the local disk."); + + final RegistryEntity registryEntity = new RegistryEntity(); + registryEntity.setComponent(registry); + + registryCache.put(registryIdentifier, new Tuple(new Revision(0L, null, registryIdentifier), registry)); + } + } + } } http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java index b213755..959d06d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerResource.java @@ -37,6 +37,7 @@ import org.apache.nifi.web.api.dto.BulletinDTO; import org.apache.nifi.web.api.dto.ClusterDTO; import org.apache.nifi.web.api.dto.ControllerServiceDTO; import org.apache.nifi.web.api.dto.NodeDTO; +import org.apache.nifi.web.api.dto.RegistryDTO; import org.apache.nifi.web.api.dto.ReportingTaskDTO; import org.apache.nifi.web.api.entity.BulletinEntity; import org.apache.nifi.web.api.entity.ClusterEntity; @@ -45,12 +46,16 @@ import org.apache.nifi.web.api.entity.ControllerServiceEntity; import org.apache.nifi.web.api.entity.Entity; import org.apache.nifi.web.api.entity.HistoryEntity; import org.apache.nifi.web.api.entity.NodeEntity; +import org.apache.nifi.web.api.entity.RegistryEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; +import org.apache.nifi.web.api.request.ClientIdParameter; import org.apache.nifi.web.api.request.DateTimeParameter; +import org.apache.nifi.web.api.request.LongParameter; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.Consumes; import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; import javax.ws.rs.GET; import javax.ws.rs.HttpMethod; import javax.ws.rs.POST; @@ -82,6 +87,17 @@ public class ControllerResource extends ApplicationResource { private ControllerServiceResource controllerServiceResource; /** + * Populate the uri's for the specified registry. + * + * @param registryEntity registry + * @return dtos + */ + public RegistryEntity populateRemainingRegistryEntityContent(final RegistryEntity registryEntity) { + registryEntity.setUri(generateResourceUri("controller", "registries", registryEntity.getId())); + return registryEntity; + } + + /** * Authorizes access to the flow. */ private void authorizeController(final RequestAction action) { @@ -290,6 +306,288 @@ public class ControllerResource extends ApplicationResource { ); } + // ---------- + // registries + // ---------- + + /** + * Creates a new Registry. + * + * @param httpServletRequest request + * @param requestRegistryEntity A registryEntity. + * @return A registryEntity. + */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("registries") + @ApiOperation( + value = "Creates a new registry", + response = RegistryEntity.class, + authorizations = { + @Authorization(value = "Write - /controller") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) + + public Response createRegistry( + @Context final HttpServletRequest httpServletRequest, + @ApiParam( + value = "The registry configuration details.", + required = true + ) final RegistryEntity requestRegistryEntity) { + + if (requestRegistryEntity == null || requestRegistryEntity.getComponent() == null) { + throw new IllegalArgumentException("Registry details must be specified."); + } + + if (requestRegistryEntity.getRevision() == null || (requestRegistryEntity.getRevision().getVersion() == null || requestRegistryEntity.getRevision().getVersion() != 0)) { + throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Registry."); + } + + final RegistryDTO requestReportingTask = requestRegistryEntity.getComponent(); + if (requestReportingTask.getId() != null) { + throw new IllegalArgumentException("Registry ID cannot be specified."); + } + + if (isReplicateRequest()) { + return replicate(HttpMethod.POST, requestRegistryEntity); + } + + return withWriteLock( + serviceFacade, + requestRegistryEntity, + lookup -> { + authorizeController(RequestAction.WRITE); + }, + null, + (registryEntity) -> { + final RegistryDTO registry = registryEntity.getComponent(); + + // set the processor id as appropriate + registry.setId(generateUuid()); + + // create the reporting task and generate the json + final Revision revision = getRevision(registryEntity, registry.getId()); + final RegistryEntity entity = serviceFacade.createRegistry(revision, registry); + populateRemainingRegistryEntityContent(entity); + + // build the response + return generateCreatedResponse(URI.create(entity.getUri()), entity).build(); + } + ); + } + + /** + * Retrieves the specified registry. + * + * @param id The id of the registry to retrieve + * @return A registryEntity. + */ + @GET + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.APPLICATION_JSON) + @Path("/registries/{id}") + @ApiOperation( + value = "Gets a registry", + response = RegistryEntity.class, + authorizations = { + @Authorization(value = "Read - /controller") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 404, message = "The specified resource could not be found."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) + public Response getRegistry( + @ApiParam( + value = "The registry id.", + required = true + ) + @PathParam("id") final String id) { + + if (isReplicateRequest()) { + return replicate(HttpMethod.GET); + } + + // authorize access + authorizeController(RequestAction.READ); + + // get the registry + final RegistryEntity entity = serviceFacade.getRegistry(id); + populateRemainingRegistryEntityContent(entity); + + return generateOkResponse(entity).build(); + } + + /** + * Updates the specified registry. + * + * @param httpServletRequest request + * @param id The id of the controller service to update. + * @param requestRegsitryEntity A controllerServiceEntity. + * @return A controllerServiceEntity. + */ + @PUT + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Path("/registries/{id}") + @ApiOperation( + value = "Updates a registry", + response = RegistryEntity.class, + authorizations = { + @Authorization(value = "Write - /controller") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 404, message = "The specified resource could not be found."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) + public Response updateControllerService( + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The registry id.", + required = true + ) + @PathParam("id") final String id, + @ApiParam( + value = "The registry configuration details.", + required = true + ) final RegistryEntity requestRegsitryEntity) { + + if (requestRegsitryEntity == null || requestRegsitryEntity.getComponent() == null) { + throw new IllegalArgumentException("Registry details must be specified."); + } + + if (requestRegsitryEntity.getRevision() == null) { + throw new IllegalArgumentException("Revision must be specified."); + } + + // ensure the ids are the same + final RegistryDTO requestRegistryDTO = requestRegsitryEntity.getComponent(); + if (!id.equals(requestRegistryDTO.getId())) { + throw new IllegalArgumentException(String.format("The registry id (%s) in the request body does not equal the " + + "registry id of the requested resource (%s).", requestRegistryDTO.getId(), id)); + } + + if (isReplicateRequest()) { + return replicate(HttpMethod.PUT, requestRegsitryEntity); + } + + // handle expects request (usually from the cluster manager) + final Revision requestRevision = getRevision(requestRegsitryEntity, id); + return withWriteLock( + serviceFacade, + requestRegsitryEntity, + requestRevision, + lookup -> { + authorizeController(RequestAction.WRITE); + }, + null, + (revision, registryEntity) -> { + final RegistryDTO registry = registryEntity.getComponent(); + + // update the controller service + final RegistryEntity entity = serviceFacade.updateRegistry(revision, registry); + populateRemainingRegistryEntityContent(entity); + + return generateOkResponse(entity).build(); + } + ); + } + + /** + * Removes the specified registry. + * + * @param httpServletRequest request + * @param version The revision is used to verify the client is working with + * the latest version of the flow. + * @param clientId Optional client id. If the client id is not specified, a + * new one will be generated. This value (whether specified or generated) is + * included in the response. + * @param id The id of the registry to remove. + * @return A entity containing the client id and an updated revision. + */ + @DELETE + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.APPLICATION_JSON) + @Path("/registries/{id}") + @ApiOperation( + value = "Deletes a reistry", + response = RegistryEntity.class, + authorizations = { + @Authorization(value = "Write - /controller") + } + ) + @ApiResponses( + value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 404, message = "The specified resource could not be found."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + } + ) + public Response deleteRegistry( + @Context HttpServletRequest httpServletRequest, + @ApiParam( + value = "The revision is used to verify the client is working with the latest version of the flow.", + required = false + ) + @QueryParam(VERSION) final LongParameter version, + @ApiParam( + value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.", + required = false + ) + @QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) final ClientIdParameter clientId, + @ApiParam( + value = "The registry id.", + required = true + ) + @PathParam("id") final String id) { + + if (isReplicateRequest()) { + return replicate(HttpMethod.DELETE); + } + + final RegistryEntity requestRegistryEntity = new RegistryEntity(); + requestRegistryEntity.setId(id); + + // handle expects request (usually from the cluster manager) + final Revision requestRevision = new Revision(version == null ? null : version.getLong(), clientId.getClientId(), id); + return withWriteLock( + serviceFacade, + requestRegistryEntity, + requestRevision, + lookup -> { + authorizeController(RequestAction.WRITE); + }, + null, + (revision, registryEntity) -> { + // delete the specified registry + final RegistryEntity entity = serviceFacade.deleteRegistry(revision, registryEntity.getId()); + return generateOkResponse(entity).build(); + } + ); + } + /** * Creates a Bulletin. * http://git-wip-us.apache.org/repos/asf/nifi/blob/7a0a900a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java ---------------------------------------------------------------------- diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java index 38e8891..3e9be6d 100644 --- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java +++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/FlowResource.java @@ -39,13 +39,18 @@ import org.apache.nifi.controller.service.ControllerServiceNode; import org.apache.nifi.controller.service.ControllerServiceState; import org.apache.nifi.groups.ProcessGroup; import org.apache.nifi.nar.NarClassLoaders; +import org.apache.nifi.registry.bucket.Bucket; +import org.apache.nifi.registry.flow.FlowRegistry; +import org.apache.nifi.registry.flow.FlowRegistryClient; import org.apache.nifi.util.NiFiProperties; import org.apache.nifi.web.IllegalClusterResourceRequestException; +import org.apache.nifi.web.NiFiCoreException; import org.apache.nifi.web.NiFiServiceFacade; import org.apache.nifi.web.ResourceNotFoundException; import org.apache.nifi.web.Revision; import org.apache.nifi.web.api.dto.AboutDTO; import org.apache.nifi.web.api.dto.BannerDTO; +import org.apache.nifi.web.api.dto.BucketDTO; import org.apache.nifi.web.api.dto.BulletinBoardDTO; import org.apache.nifi.web.api.dto.BulletinQueryDTO; import org.apache.nifi.web.api.dto.ClusterDTO; @@ -64,6 +69,8 @@ import org.apache.nifi.web.api.entity.AboutEntity; import org.apache.nifi.web.api.entity.ActionEntity; import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity; import org.apache.nifi.web.api.entity.BannerEntity; +import org.apache.nifi.web.api.entity.BucketEntity; +import org.apache.nifi.web.api.entity.BucketsEntity; import org.apache.nifi.web.api.entity.BulletinBoardEntity; import org.apache.nifi.web.api.entity.ClusteSummaryEntity; import org.apache.nifi.web.api.entity.ClusterSearchResultsEntity; @@ -84,6 +91,8 @@ import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ProcessorStatusEntity; import org.apache.nifi.web.api.entity.ProcessorTypesEntity; +import org.apache.nifi.web.api.entity.RegistriesEntity; +import org.apache.nifi.web.api.entity.RegistryEntity; import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; import org.apache.nifi.web.api.entity.ReportingTaskEntity; import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity; @@ -112,6 +121,7 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import java.io.IOException; import java.util.ArrayList; import java.util.Date; import java.util.EnumSet; @@ -148,8 +158,11 @@ public class FlowResource extends ApplicationResource { private TemplateResource templateResource; private ProcessGroupResource processGroupResource; private ControllerServiceResource controllerServiceResource; + private ControllerResource controllerResource; private ReportingTaskResource reportingTaskResource; + private FlowRegistryClient flowRegistryClient; + public FlowResource() { super(); } @@ -1317,6 +1330,98 @@ public class FlowResource extends ApplicationResource { return generateOkResponse(entity).build(); } + // ---------- + // registries + // ---------- + + @GET + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.APPLICATION_JSON) + @Path("registries") + @ApiOperation(value = "Gets the listing of available registries", response = RegistriesEntity.class, authorizations = { + @Authorization(value = "Read - /flow") + }) + @ApiResponses(value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 404, message = "The specified resource could not be found."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + }) + public Response getRegistries() { + authorizeFlow(); + + if (isReplicateRequest()) { + return replicate(HttpMethod.GET); + } + + final Set<RegistryEntity> registries = serviceFacade.getRegistries(); + registries.forEach(registry -> controllerResource.populateRemainingRegistryEntityContent(registry)); + + final RegistriesEntity registryEntities = new RegistriesEntity(); + registryEntities.setRegistries(registries); + + return generateOkResponse(registryEntities).build(); + } + + @GET + @Consumes(MediaType.WILDCARD) + @Produces(MediaType.APPLICATION_JSON) + @Path("registries/{id}/buckets") + @ApiOperation(value = "Gets the buckets from the specified registry for the current user", response = BucketsEntity.class, authorizations = { + @Authorization(value = "Read - /flow") + }) + @ApiResponses(value = { + @ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."), + @ApiResponse(code = 401, message = "Client could not be authenticated."), + @ApiResponse(code = 403, message = "Client is not authorized to make this request."), + @ApiResponse(code = 404, message = "The specified resource could not be found."), + @ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.") + }) + public Response getBuckets( + @ApiParam( + value = "The registry id.", + required = true + ) + @PathParam("id") String id) { + + authorizeFlow(); + + try { + final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(id); + if (flowRegistry == null) { + throw new IllegalArgumentException("The specified registry id is unknown to this NiFi."); + } + + final Set<Bucket> userBuckets = flowRegistry.getBuckets(NiFiUserUtils.getNiFiUser()); + + final BucketsEntity bucketsEntity = new BucketsEntity(); + + if (userBuckets != null) { + + final Set<BucketEntity> bucketSet = new HashSet<>(); + for (final Bucket userBucket : userBuckets) { + final BucketDTO bucket = new BucketDTO(); + bucket.setId(userBucket.getIdentifier()); + bucket.setName(userBucket.getName()); + bucket.setDescription(userBucket.getDescription()); + bucket.setCreated(userBucket.getCreatedTimestamp()); + + final BucketEntity bucketEntity = new BucketEntity(); + bucketEntity.setBucket(bucket); + + bucketSet.add(bucketEntity); + } + + bucketsEntity.setBuckets(bucketSet); + } + + return generateOkResponse(bucketsEntity).build(); + } catch (final IOException ioe) { + throw new NiFiCoreException("Unable to obtain bucket listing: " + ioe.getMessage(), ioe); + } + } + // -------------- // bulletin board // -------------- @@ -2524,6 +2629,10 @@ public class FlowResource extends ApplicationResource { this.processGroupResource = processGroupResource; } + public void setControllerResource(ControllerResource controllerResource) { + this.controllerResource = controllerResource; + } + public void setControllerServiceResource(ControllerServiceResource controllerServiceResource) { this.controllerServiceResource = controllerServiceResource; } @@ -2535,4 +2644,8 @@ public class FlowResource extends ApplicationResource { public void setAuthorizer(Authorizer authorizer) { this.authorizer = authorizer; } + + public void setFlowRegistryClient(FlowRegistryClient flowRegistryClient) { + this.flowRegistryClient = flowRegistryClient; + } }
