Repository: nifi-registry Updated Branches: refs/heads/master f2d712f32 -> 2e35235d5
NIFIREG-73 Making flow/item name be unique per bucket instead of globally. This closes #59 Project: http://git-wip-us.apache.org/repos/asf/nifi-registry/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi-registry/commit/2e35235d Tree: http://git-wip-us.apache.org/repos/asf/nifi-registry/tree/2e35235d Diff: http://git-wip-us.apache.org/repos/asf/nifi-registry/diff/2e35235d Branch: refs/heads/master Commit: 2e35235d5cfc094f0120b6a77db4c1d1c3f15721 Parents: f2d712f Author: Bryan Bende <[email protected]> Authored: Fri Dec 15 13:25:24 2017 -0500 Committer: Matt Gilman <[email protected]> Committed: Mon Dec 18 10:28:44 2017 -0500 ---------------------------------------------------------------------- .../nifi/registry/client/ItemsClient.java | 22 --------- .../registry/client/impl/JerseyItemsClient.java | 31 ++---------- .../registry/db/DatabaseMetadataService.java | 42 +++++++++++++++- .../registry/db/entity/BucketItemEntity.java | 10 ++++ .../db/mapper/BucketItemEntityRowMapper.java | 1 + .../nifi/registry/service/DataModelMapper.java | 2 + .../nifi/registry/service/MetadataService.java | 9 ++++ .../nifi/registry/service/RegistryService.java | 8 +-- .../V1.3__DropBucketItemNameUniqueness.sql | 27 +++++++++++ .../db/TestDatabaseMetadataService.java | 18 +++++++ .../registry/service/TestRegistryService.java | 4 +- .../db/migration/V999999.1__test-setup.sql | 6 +-- .../apache/nifi/registry/web/api/FlowsIT.java | 51 ++++++++++++++++++++ .../web/api/UnsecuredNiFiRegistryClientIT.java | 16 ++---- .../registry/nf-registry-grid-list-viewer.html | 2 +- 15 files changed, 174 insertions(+), 75 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/ItemsClient.java ---------------------------------------------------------------------- diff --git a/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/ItemsClient.java b/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/ItemsClient.java index f862f03..96fa801 100644 --- a/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/ItemsClient.java +++ b/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/ItemsClient.java @@ -18,7 +18,6 @@ package org.apache.nifi.registry.client; import org.apache.nifi.registry.bucket.BucketItem; import org.apache.nifi.registry.field.Fields; -import org.apache.nifi.registry.params.SortParameter; import java.io.IOException; import java.util.List; @@ -44,16 +43,6 @@ public interface ItemsClient { List<BucketItem> getAll() throws NiFiRegistryException, IOException; /** - * Gets all bucket items in the registry in sorted order. - * - * @param sortParameters the sort parameters - * @return the sorted list of items - * @throws NiFiRegistryException if an error is encountered other than IOException - * @throws IOException if an I/O error is encountered - */ - List<BucketItem> getAll(List<SortParameter> sortParameters) throws NiFiRegistryException, IOException; - - /** * Gets all bucket items for the given bucket. * * @param bucketId the bucket id @@ -64,17 +53,6 @@ public interface ItemsClient { List<BucketItem> getByBucket(String bucketId) throws NiFiRegistryException, IOException; /** - * Gets all bucket items in the given bucket in sorted order. - * - * @param bucketId the bucket id - * @param sortParameters the sort parameters - * @return the list of items - * @throws NiFiRegistryException if an error is encountered other than IOException - * @throws IOException if an I/O error is encountered - */ - List<BucketItem> getByBucket(String bucketId, List<SortParameter> sortParameters) throws NiFiRegistryException, IOException; - - /** * Gets the field info for bucket items. * * @return the list of field info http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyItemsClient.java ---------------------------------------------------------------------- diff --git a/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyItemsClient.java b/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyItemsClient.java index 05fb613..6b01fc4 100644 --- a/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyItemsClient.java +++ b/nifi-registry-client/src/main/java/org/apache/nifi/registry/client/impl/JerseyItemsClient.java @@ -21,7 +21,6 @@ import org.apache.nifi.registry.bucket.BucketItem; import org.apache.nifi.registry.client.ItemsClient; import org.apache.nifi.registry.client.NiFiRegistryException; import org.apache.nifi.registry.field.Fields; -import org.apache.nifi.registry.params.SortParameter; import javax.ws.rs.client.WebTarget; import java.io.IOException; @@ -46,53 +45,29 @@ public class JerseyItemsClient extends AbstractJerseyClient implements ItemsClie this.itemsTarget = baseTarget.path("/items"); } - @Override - public List<BucketItem> getAll() throws NiFiRegistryException, IOException { - return getAll(Collections.emptyList()); - } - @Override - public List<BucketItem> getAll(final List<SortParameter> sorts) throws NiFiRegistryException, IOException { - if (sorts == null) { - throw new IllegalArgumentException("Sort Parameters cannot be null"); - } + @Override + public List<BucketItem> getAll() throws NiFiRegistryException, IOException { return executeAction("", () -> { WebTarget target = itemsTarget; - for (final SortParameter sortParam : sorts) { - target = target.queryParam("sort", sortParam.toString()); - } - final BucketItem[] bucketItems = getRequestBuilder(target).get(BucketItem[].class); return bucketItems == null ? Collections.emptyList() : Arrays.asList(bucketItems); }); } @Override - public List<BucketItem> getByBucket(final String bucketId) throws NiFiRegistryException, IOException { - return getByBucket(bucketId, Collections.emptyList()); - } - - @Override - public List<BucketItem> getByBucket(final String bucketId, final List<SortParameter> sorts) + public List<BucketItem> getByBucket(final String bucketId) throws NiFiRegistryException, IOException { if (StringUtils.isBlank(bucketId)) { throw new IllegalArgumentException("Bucket Identifier cannot be blank"); } - if (sorts == null) { - throw new IllegalArgumentException("Sort Parameters cannot be null"); - } - return executeAction("", () -> { WebTarget target = itemsTarget .path("/{bucketId}") .resolveTemplate("bucketId", bucketId); - for (final SortParameter sortParam : sorts) { - target = target.queryParam("sort", sortParam.toString()); - } - final BucketItem[] bucketItems = getRequestBuilder(target).get(BucketItem[].class); return bucketItems == null ? Collections.emptyList() : Arrays.asList(bucketItems); }); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java index 1481ccd..a3fe74f 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/DatabaseMetadataService.java @@ -129,7 +129,23 @@ public class DatabaseMetadataService implements MetadataService { @Override public List<BucketItemEntity> getBucketItems(final String bucketIdentifier) { - final String sql = "SELECT * FROM bucket_item WHERE bucket_id = ?"; + final String sql = + "SELECT " + + "item.id as ID, " + + "item.name as NAME, " + + "item.description as DESCRIPTION, " + + "item.created as CREATED, " + + "item.modified as MODIFIED, " + + "item.item_type as ITEM_TYPE, " + + "b.id as BUCKET_ID, " + + "b.name as BUCKET_NAME " + + "FROM " + + "bucket_item item, bucket b " + + "WHERE " + + "item.bucket_id = b.id " + + "AND " + + "item.bucket_id = ?"; + final List<BucketItemEntity> items = jdbcTemplate.query(sql, new Object[] { bucketIdentifier }, new BucketItemEntityRowMapper()); return getItemsWithCounts(items); } @@ -140,7 +156,23 @@ public class DatabaseMetadataService implements MetadataService { return Collections.emptyList(); } - final StringBuilder sqlBuilder = new StringBuilder("SELECT * FROM bucket_item WHERE bucket_id IN ("); + final StringBuilder sqlBuilder = new StringBuilder( + "SELECT " + + "item.id as ID, " + + "item.name as NAME, " + + "item.description as DESCRIPTION, " + + "item.created as CREATED, " + + "item.modified as MODIFIED, " + + "item.item_type as ITEM_TYPE, " + + "b.id as BUCKET_ID, " + + "b.name as BUCKET_NAME " + + "FROM " + + "bucket_item item, bucket b " + + "WHERE " + + "item.bucket_id = b.id " + + "AND " + + "item.bucket_id IN ("); + for (int i=0; i < bucketIds.size(); i++) { if (i > 0) { sqlBuilder.append(", "); @@ -244,6 +276,12 @@ public class DatabaseMetadataService implements MetadataService { } @Override + public List<FlowEntity> getFlowsByName(final String bucketIdentifier, final String name) { + final String sql = "SELECT * FROM flow f, bucket_item item WHERE item.name = ? AND item.id = f.id AND item.bucket_id = ?"; + return jdbcTemplate.query(sql, new Object[] {name, bucketIdentifier}, new FlowEntityRowMapper()); + } + + @Override public List<FlowEntity> getFlowsByBucket(final String bucketIdentifier) { final String sql = "SELECT * FROM flow f, bucket_item item WHERE item.bucket_id = ? AND item.id = f.id"; final List<FlowEntity> flows = jdbcTemplate.query(sql, new Object[] {bucketIdentifier}, new FlowEntityRowMapper()); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntity.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntity.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntity.java index 0c61a26..cdfa963 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntity.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/entity/BucketItemEntity.java @@ -36,6 +36,8 @@ public class BucketItemEntity { private String bucketId; + private String bucketName; + public String getId() { return id; @@ -93,6 +95,14 @@ public class BucketItemEntity { this.bucketId = bucketId; } + public String getBucketName() { + return bucketName; + } + + public void setBucketName(String bucketName) { + this.bucketName = bucketName; + } + @Override public int hashCode() { return Objects.hashCode(this.id); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/mapper/BucketItemEntityRowMapper.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/mapper/BucketItemEntityRowMapper.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/mapper/BucketItemEntityRowMapper.java index 2ebe094..7b3df05 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/mapper/BucketItemEntityRowMapper.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/mapper/BucketItemEntityRowMapper.java @@ -51,6 +51,7 @@ public class BucketItemEntityRowMapper implements RowMapper<BucketItemEntity> { item.setCreated(rs.getTimestamp("CREATED")); item.setModified(rs.getTimestamp("MODIFIED")); item.setBucketId(rs.getString("BUCKET_ID")); + item.setBucketName(rs.getString("BUCKET_NAME")); item.setType(type); return item; } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/DataModelMapper.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/DataModelMapper.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/DataModelMapper.java index 80c8582..1dbf49a 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/DataModelMapper.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/DataModelMapper.java @@ -78,6 +78,8 @@ public class DataModelMapper { if (bucketEntity != null) { versionedFlow.setBucketName(bucketEntity.getName()); + } else { + versionedFlow.setBucketName(flowEntity.getBucketName()); } return versionedFlow; http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java index 453271a..ea0b214 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/MetadataService.java @@ -138,6 +138,15 @@ public interface MetadataService { List<FlowEntity> getFlowsByName(String name); /** + * Retrieves the versioned flows with the given name in the given bucket. The name comparison must be case-insensitive. + * + * @param bucketIdentifier the identifier of the bucket + * @param name the name of the flow to retrieve + * @return the versioned flows with the given name in the given bucket, or empty list if no flows with the given name exists + */ + List<FlowEntity> getFlowsByName(String bucketIdentifier, String name); + + /** * Retrieves the versioned flows for the given bucket. * * @param bucketIdentifier the bucket id to retrieve flows for http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java index 1717776..8a96d20 100644 --- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java +++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/RegistryService.java @@ -323,9 +323,9 @@ public class RegistryService { } // ensure another flow with the same name doesn't exist - final List<FlowEntity> flowsWithSameName = metadataService.getFlowsByName(versionedFlow.getName()); + final List<FlowEntity> flowsWithSameName = metadataService.getFlowsByName(existingBucket.getId(), versionedFlow.getName()); if (flowsWithSameName != null && flowsWithSameName.size() > 0) { - throw new IllegalStateException("A versioned flow with the same name already exists"); + throw new IllegalStateException("A versioned flow with the same name already exists in the selected bucket"); } // convert from dto to entity and set the bucket relationship @@ -425,11 +425,11 @@ public class RegistryService { // ensure a different flow with the same name does not exist // since we're allowing partial updates here, only check this if a non-null name is provided if (StringUtils.isNotBlank(versionedFlow.getName())) { - final List<FlowEntity> flowsWithSameName = metadataService.getFlowsByName(versionedFlow.getName()); + final List<FlowEntity> flowsWithSameName = metadataService.getFlowsByName(existingBucket.getId(), versionedFlow.getName()); if (flowsWithSameName != null) { for (final FlowEntity flowWithSameName : flowsWithSameName) { if(!flowWithSameName.getId().equals(existingFlow.getId())) { - throw new IllegalStateException("A versioned flow with the same name already exists - " + versionedFlow.getName()); + throw new IllegalStateException("A versioned flow with the same name already exists in the selected bucket"); } } } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/main/resources/db/migration/V1.3__DropBucketItemNameUniqueness.sql ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/main/resources/db/migration/V1.3__DropBucketItemNameUniqueness.sql b/nifi-registry-framework/src/main/resources/db/migration/V1.3__DropBucketItemNameUniqueness.sql new file mode 100644 index 0000000..f29b4d0 --- /dev/null +++ b/nifi-registry-framework/src/main/resources/db/migration/V1.3__DropBucketItemNameUniqueness.sql @@ -0,0 +1,27 @@ +-- Licensed to the Apache Software Foundation (ASF) under one or more +-- contributor license agreements. See the NOTICE file distributed with +-- this work for additional information regarding copyright ownership. +-- The ASF licenses this file to You under the Apache License, Version 2.0 +-- (the "License"); you may not use this file except in compliance with +-- the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, software +-- distributed under the License is distributed on an "AS IS" BASIS, +-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +-- See the License for the specific language governing permissions and +-- limitations under the License. + +CREATE ALIAS IF NOT EXISTS EXECUTE AS $$ void executeSql(Connection conn, String sql) +throws SQLException { conn.createStatement().executeUpdate(sql); } $$; + +call execute('ALTER TABLE BUCKET_ITEM DROP CONSTRAINT ' || + ( + SELECT DISTINCT CONSTRAINT_NAME + FROM INFORMATION_SCHEMA.CONSTRAINTS + WHERE TABLE_NAME = 'BUCKET_ITEM' + AND COLUMN_LIST = 'NAME' + AND CONSTRAINT_TYPE = 'UNIQUE' + ) +); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java b/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java index dfdeef4..35ba757 100644 --- a/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java +++ b/nifi-registry-framework/src/test/java/org/apache/nifi/registry/db/TestDatabaseMetadataService.java @@ -150,6 +150,8 @@ public class TestDatabaseMetadataService extends DatabaseBaseTest { final List<BucketItemEntity> items = metadataService.getBucketItems(bucket.getId()); assertNotNull(items); assertEquals(2, items.size()); + + items.stream().forEach(i -> assertNotNull(i.getBucketName())); } @Test @@ -157,6 +159,8 @@ public class TestDatabaseMetadataService extends DatabaseBaseTest { final List<BucketItemEntity> items = metadataService.getBucketItems(new HashSet<>(Arrays.asList("1", "2"))); assertNotNull(items); assertEquals(3, items.size()); + + items.stream().forEach(i -> assertNotNull(i.getBucketName())); } @Test @@ -173,6 +177,8 @@ public class TestDatabaseMetadataService extends DatabaseBaseTest { final FlowEntity flowEntity = (FlowEntity) item1; assertEquals(3, flowEntity.getSnapshotCount()); + + items.stream().forEach(i -> assertNotNull(i.getBucketName())); } @Test @@ -189,6 +195,8 @@ public class TestDatabaseMetadataService extends DatabaseBaseTest { final FlowEntity flowEntity = (FlowEntity) item1; assertEquals(3, flowEntity.getSnapshotCount()); + + items.stream().forEach(i -> assertNotNull(i.getBucketName())); } //----------------- Flows --------------------------------- @@ -255,8 +263,18 @@ public class TestDatabaseMetadataService extends DatabaseBaseTest { public void testGetFlowsByName() { final List<FlowEntity> flows = metadataService.getFlowsByName("Flow 1"); assertNotNull(flows); + assertEquals(2, flows.size()); + assertEquals("Flow 1", flows.get(0).getName()); + assertEquals("Flow 1", flows.get(1).getName()); + } + + @Test + public void testGetFlowsByNameByBucket() { + final List<FlowEntity> flows = metadataService.getFlowsByName("2","Flow 1"); + assertNotNull(flows); assertEquals(1, flows.size()); assertEquals("Flow 1", flows.get(0).getName()); + assertEquals("2", flows.get(0).getBucketId()); } @Test http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java b/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java index 3d25dae..26467ca 100644 --- a/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java +++ b/nifi-registry-framework/src/test/java/org/apache/nifi/registry/service/TestRegistryService.java @@ -318,7 +318,7 @@ public class TestRegistryService { flowWithSameName.setCreated(new Date()); flowWithSameName.setModified(new Date()); - when(metadataService.getFlowsByName(flowWithSameName.getName())).thenReturn(Collections.singletonList(flowWithSameName)); + when(metadataService.getFlowsByName(existingBucket.getId(), flowWithSameName.getName())).thenReturn(Collections.singletonList(flowWithSameName)); final VersionedFlow versionedFlow = new VersionedFlow(); versionedFlow.setName(flowWithSameName.getName()); @@ -478,7 +478,7 @@ public class TestRegistryService { otherFlow.setModified(new Date()); otherFlow.setBucketId(existingBucket.getId()); - when(metadataService.getFlowsByName(otherFlow.getName())).thenReturn(Collections.singletonList(otherFlow)); + when(metadataService.getFlowsByName(existingBucket.getId(), otherFlow.getName())).thenReturn(Collections.singletonList(otherFlow)); final VersionedFlow versionedFlow = new VersionedFlow(); versionedFlow.setIdentifier(flowToUpdate.getId()); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-framework/src/test/resources/db/migration/V999999.1__test-setup.sql ---------------------------------------------------------------------- diff --git a/nifi-registry-framework/src/test/resources/db/migration/V999999.1__test-setup.sql b/nifi-registry-framework/src/test/resources/db/migration/V999999.1__test-setup.sql index 6a10a87..8f3cfa8 100644 --- a/nifi-registry-framework/src/test/resources/db/migration/V999999.1__test-setup.sql +++ b/nifi-registry-framework/src/test/resources/db/migration/V999999.1__test-setup.sql @@ -37,17 +37,17 @@ insert into bucket (id, name, description, created) -- test data for flows insert into bucket_item (id, name, description, created, modified, item_type, bucket_id) - values ('1', 'Flow 1', 'This is flow 1', parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), 'FLOW', '1'); + values ('1', 'Flow 1', 'This is flow 1 bucket 1', parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), 'FLOW', '1'); insert into flow (id) values ('1'); insert into bucket_item (id, name, description, created, modified, item_type, bucket_id) - values ('2', 'Flow 2', 'This is flow 2', parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), 'FLOW', '1'); + values ('2', 'Flow 2', 'This is flow 2 bucket 1', parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), 'FLOW', '1'); insert into flow (id) values ('2'); insert into bucket_item (id, name, description, created, modified, item_type, bucket_id) - values ('3', 'Flow 3', 'This is flow 3', parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), 'FLOW', '2'); + values ('3', 'Flow 1', 'This is flow 1 bucket 2', parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), parsedatetime('2017-09-11 12:56:00.000 UTC', 'yyyy-MM-dd hh:mm:ss.SSS z'), 'FLOW', '2'); insert into flow (id) values ('3'); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/FlowsIT.java ---------------------------------------------------------------------- diff --git a/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/FlowsIT.java b/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/FlowsIT.java index 854c9c1..d0d02ce 100644 --- a/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/FlowsIT.java +++ b/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/FlowsIT.java @@ -21,10 +21,12 @@ import org.apache.nifi.registry.flow.VersionedFlow; import org.apache.nifi.registry.flow.VersionedFlowSnapshot; import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata; import org.apache.nifi.registry.flow.VersionedProcessGroup; +import org.junit.Assert; import org.junit.Test; import org.skyscreamer.jsonassert.JSONAssert; import org.springframework.test.context.jdbc.Sql; +import javax.ws.rs.WebApplicationException; import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; @@ -390,4 +392,53 @@ public class FlowsIT extends UnsecuredITBase { } + @Test + public void testFlowNameUniquePerBucket() throws Exception { + + final String flowName = "Flow 1"; + + // verify we have an existing flow with the name "Flow 1" in bucket 1 + final VersionedFlow existingFlow = client + .target(createURL("buckets/1/flows/1")) + .request() + .get(VersionedFlow.class); + + assertNotNull(existingFlow); + assertEquals(flowName, existingFlow.getName()); + + // create a new flow with the same name + + final String bucketId = "3"; + + final VersionedFlow flow = new VersionedFlow(); + flow.setBucketIdentifier(bucketId); + flow.setName(flowName); + flow.setDescription("This is a flow created by an integration test."); + + // saving this flow to bucket 3 should work because bucket 3 is empty + + final VersionedFlow createdFlow = client + .target(createURL("buckets/3/flows")) + .resolveTemplate("bucketId", bucketId) + .request() + .post(Entity.entity(flow, MediaType.APPLICATION_JSON), VersionedFlow.class); + + assertNotNull(createdFlow); + + // saving the flow to bucket 1 should not work because there is a flow with the same name + flow.setBucketIdentifier("1"); + try { + client.target(createURL("buckets/1/flows")) + .resolveTemplate("bucketId", bucketId) + .request() + .post(Entity.entity(flow, MediaType.APPLICATION_JSON), VersionedFlow.class); + + Assert.fail("Should have thrown exception"); + } catch (WebApplicationException e) { + final String errorMessage = e.getResponse().readEntity(String.class); + Assert.assertEquals("A versioned flow with the same name already exists in the selected bucket", errorMessage); + } + + } + } http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/UnsecuredNiFiRegistryClientIT.java ---------------------------------------------------------------------- diff --git a/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/UnsecuredNiFiRegistryClientIT.java b/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/UnsecuredNiFiRegistryClientIT.java index 184a54d..a12056b 100644 --- a/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/UnsecuredNiFiRegistryClientIT.java +++ b/nifi-registry-web-api/src/test/java/org/apache/nifi/registry/web/api/UnsecuredNiFiRegistryClientIT.java @@ -16,6 +16,7 @@ */ package org.apache.nifi.registry.web.api; +import org.apache.nifi.registry.authorization.CurrentUser; import org.apache.nifi.registry.authorization.Permissions; import org.apache.nifi.registry.bucket.Bucket; import org.apache.nifi.registry.bucket.BucketItem; @@ -34,9 +35,6 @@ import org.apache.nifi.registry.flow.VersionedFlowSnapshot; import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata; import org.apache.nifi.registry.flow.VersionedProcessGroup; import org.apache.nifi.registry.flow.VersionedProcessor; -import org.apache.nifi.registry.authorization.CurrentUser; -import org.apache.nifi.registry.params.SortOrder; -import org.apache.nifi.registry.params.SortParameter; import org.junit.After; import org.junit.Assert; import org.junit.Before; @@ -46,7 +44,6 @@ import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -259,22 +256,15 @@ public class UnsecuredNiFiRegistryClientIT extends UnsecuredITBase { // get all items final List<BucketItem> allItems = itemsClient.getAll(); Assert.assertEquals(2, allItems.size()); + allItems.stream().forEach(i -> Assert.assertNotNull(i.getBucketName())); allItems.stream().forEach(i -> LOGGER.info("All items, item " + i.getIdentifier())); - // get all items with sorting - final SortParameter itemsSortParam = new SortParameter("created", SortOrder.ASC); - final List<BucketItem> allItemsSorted = itemsClient.getAll(Arrays.asList(itemsSortParam)); - Assert.assertEquals(2, allItemsSorted.size()); - // get items for bucket final List<BucketItem> bucketItems = itemsClient.getByBucket(flowsBucket.getIdentifier()); Assert.assertEquals(2, bucketItems.size()); + allItems.stream().forEach(i -> Assert.assertNotNull(i.getBucketName())); bucketItems.stream().forEach(i -> LOGGER.info("Items in bucket, item " + i.getIdentifier())); - // get items for bucket with sorting - final List<BucketItem> bucketItemsSorted = itemsClient.getByBucket(flowsBucket.getIdentifier(), Arrays.asList(itemsSortParam)); - Assert.assertEquals(2, bucketItemsSorted.size()); - // ---------------------- DELETE DATA --------------------------// final VersionedFlow deletedFlow1 = flowClient.delete(flowsBucket.getIdentifier(), flow1.getIdentifier()); http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/2e35235d/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html ---------------------------------------------------------------------- diff --git a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html index 8e336ab..f1d58f3 100644 --- a/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html +++ b/nifi-registry-web-ui/src/main/webapp/components/explorer/grid-list/registry/nf-registry-grid-list-viewer.html @@ -44,7 +44,7 @@ limitations under the License. [disabled]="disabled" (expanded)="nfRegistryService.getDropletSnapshotMetadata(droplet)"> <ng-template td-expansion-panel-label> <div fxLayout="column" fxLayoutAlign="space-between start"> - <span class="md-title capitalize">{{droplet.name}}</span> + <span class="md-title capitalize">{{droplet.name}} - {{droplet.bucketName}}</span> <span class="md-subhead">{{droplet.type}}</span> </div> </ng-template>
