You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by bb...@apache.org on 2017/10/05 18:11:33 UTC
[08/10] nifi-registry git commit: NIFIREG-9: Initial Auth
Implementation
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java
new file mode 100644
index 0000000..3a8a8bc
--- /dev/null
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/authorization/user/StandardNiFiUser.java
@@ -0,0 +1,189 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.registry.authorization.user;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.Collections;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * An implementation of NiFiUser.
+ */
+public class StandardNiFiUser implements NiFiUser {
+
+ public static final String ANONYMOUS_IDENTITY = "anonymous";
+ public static final StandardNiFiUser ANONYMOUS = new Builder().identity(ANONYMOUS_IDENTITY).anonymous(true).build();
+
+ private final String identity;
+ private final Set<String> groups;
+ private final NiFiUser chain;
+ private final String clientAddress;
+ private final boolean isAnonymous;
+
+ private StandardNiFiUser(final Builder builder) {
+ this.identity = builder.identity;
+ this.groups = builder.groups == null ? null : Collections.unmodifiableSet(builder.groups);
+ this.chain = builder.chain;
+ this.clientAddress = builder.clientAddress;
+ this.isAnonymous = builder.isAnonymous;
+ }
+
+ /**
+ * This static builder allows the chain and clientAddress to be populated without allowing calling code to provide a non-anonymous identity of the anonymous user.
+ *
+ * @param chain the proxied entities in {@see NiFiUser} form
+ * @param clientAddress the address the request originated from
+ * @return an anonymous user instance with the identity "anonymous"
+ */
+ public static StandardNiFiUser populateAnonymousUser(NiFiUser chain, String clientAddress) {
+ return new Builder().identity(ANONYMOUS_IDENTITY).chain(chain).clientAddress(clientAddress).anonymous(true).build();
+ }
+
+ @Override
+ public String getIdentity() {
+ return identity;
+ }
+
+ @Override
+ public Set<String> getGroups() {
+ return groups;
+ }
+
+ @Override
+ public NiFiUser getChain() {
+ return chain;
+ }
+
+ @Override
+ public boolean isAnonymous() {
+ return isAnonymous;
+ }
+
+ @Override
+ public String getClientAddress() {
+ return clientAddress;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+
+ if (!(obj instanceof NiFiUser)) {
+ return false;
+ }
+
+ final NiFiUser other = (NiFiUser) obj;
+ return Objects.equals(this.identity, other.getIdentity());
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 53 * hash + Objects.hashCode(this.identity);
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ final String formattedGroups;
+ if (groups == null) {
+ formattedGroups = "none";
+ } else {
+ formattedGroups = StringUtils.join(groups, ", ");
+ }
+
+ return String.format("identity[%s], groups[%s]", getIdentity(), formattedGroups);
+ }
+
+ /**
+ * Builder for a StandardNiFiUser
+ */
+ public static class Builder {
+
+ private String identity;
+ private Set<String> groups;
+ private NiFiUser chain;
+ private String clientAddress;
+ private boolean isAnonymous = false;
+
+ /**
+ * Sets the identity.
+ *
+ * @param identity the identity string for the user (i.e. "Andy" or "CN=alopresto, OU=Apache NiFi")
+ * @return the builder
+ */
+ public Builder identity(final String identity) {
+ this.identity = identity;
+ return this;
+ }
+
+ /**
+ * Sets the groups.
+ *
+ * @param groups the user groups
+ * @return the builder
+ */
+ public Builder groups(final Set<String> groups) {
+ this.groups = groups;
+ return this;
+ }
+
+ /**
+ * Sets the chain.
+ *
+ * @param chain the proxy chain that leads to this users
+ * @return the builder
+ */
+ public Builder chain(final NiFiUser chain) {
+ this.chain = chain;
+ return this;
+ }
+
+ /**
+ * Sets the client address.
+ *
+ * @param clientAddress the source address of the request
+ * @return the builder
+ */
+ public Builder clientAddress(final String clientAddress) {
+ this.clientAddress = clientAddress;
+ return this;
+ }
+
+ /**
+ * Sets whether this user is the canonical "anonymous" user
+ *
+ * @param isAnonymous true to represent the canonical "anonymous" user
+ * @return the builder
+ */
+ private Builder anonymous(final boolean isAnonymous) {
+ this.isAnonymous = isAnonymous;
+ return this;
+ }
+
+ /**
+ * @return builds a StandardNiFiUser from the current state of the builder
+ */
+ public StandardNiFiUser build() {
+ return new StandardNiFiUser(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/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 35c6b55..0fc10a4 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
@@ -42,6 +42,7 @@ import javax.persistence.metamodel.Metamodel;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -166,6 +167,10 @@ public class DatabaseMetadataService implements MetadataService {
return buckets;
}
+ private Set<BucketEntity> getBuckets(Set<String> bucketIds) {
+ return new HashSet<>(bucketRepository.findByIdIn(bucketIds));
+ }
+
// ------------------------------------------------------------------------------------
@Override
@@ -218,6 +223,18 @@ public class DatabaseMetadataService implements MetadataService {
}
}
+ @Override
+ public List<BucketItemEntity> getBucketItems(final QueryParameters params, final Set<String> bucketIds) {
+ Set<BucketEntity> filterBuckets = getBuckets(bucketIds);
+ if (params.getNumRows() != null && params.getPageNum() != null) {
+ return getPagedBucketItems(params, filterBuckets);
+ } else if (params.getSortParameters() != null && params.getSortParameters().size() > 0) {
+ return getSortedBucketItems(params, filterBuckets);
+ } else {
+ return getBucketItems(filterBuckets);
+ }
+ }
+
private List<BucketItemEntity> getBucketItems(final BucketEntity bucket) {
final List<BucketItemEntity> bucketItems = new ArrayList<>();
for (BucketItemEntity item : itemRepository.findByBucket(bucket)) {
@@ -244,6 +261,32 @@ public class DatabaseMetadataService implements MetadataService {
return items;
}
+ private List<BucketItemEntity> getBucketItems(final Set<BucketEntity> buckets) {
+ final List<BucketItemEntity> bucketItems = new ArrayList<>();
+ for (BucketItemEntity item : itemRepository.findByBucketIn(buckets)) {
+ bucketItems.add(item);
+ }
+ return bucketItems;
+ }
+
+ private List<BucketItemEntity> getPagedBucketItems(final QueryParameters params, final Set<BucketEntity> buckets) {
+ final Pageable pageable = getPageRequest(params);
+ final List<BucketItemEntity> items = new ArrayList<>();
+ for (BucketItemEntity item : itemRepository.findByBucketIn(buckets, pageable)) {
+ items.add(item);
+ }
+ return items;
+ }
+
+ private List<BucketItemEntity> getSortedBucketItems(final QueryParameters params, final Set<BucketEntity> buckets) {
+ final Sort sort = getSort(params);
+ final List<BucketItemEntity> items = new ArrayList<>();
+ for (BucketItemEntity item : itemRepository.findByBucketIn(buckets, sort)) {
+ items.add(item);
+ }
+ return items;
+ }
+
// ------------------------------------------------------------------------------------
@Override
@@ -254,8 +297,14 @@ public class DatabaseMetadataService implements MetadataService {
}
@Override
- public FlowEntity getFlowById(final String flowIdentifier) {
- return flowRepository.findOne(flowIdentifier);
+ public FlowEntity getFlowById(final String bucketIdentifier, final String flowIdentifier) {
+ FlowEntity flow = flowRepository.findOne(flowIdentifier);
+
+ if (flow.getBucket() == null || !bucketIdentifier.equals(flow.getBucket().getId())) {
+ return null;
+ }
+
+ return flow;
}
@Override
@@ -285,12 +334,18 @@ public class DatabaseMetadataService implements MetadataService {
@Override
public List<FlowEntity> getFlows(final QueryParameters params) {
+ return getFlows(params, null);
+ }
+
+ @Override
+ public List<FlowEntity> getFlows(final QueryParameters params, Set<String> bucketIds) {
+ Set<BucketEntity> filterBuckets = getBuckets(bucketIds);
if (params.getNumRows() != null && params.getPageNum() != null) {
- return getPagedFlows(params);
+ return getPagedFlows(params, filterBuckets);
} else if (params.getSortParameters() != null && params.getSortParameters().size() > 0) {
- return getSortedFlows(params);
+ return getSortedFlows(params, filterBuckets);
} else {
- return getAllFlows();
+ return getAllFlows(filterBuckets);
}
}
@@ -320,6 +375,20 @@ public class DatabaseMetadataService implements MetadataService {
return flows;
}
+ private List<FlowEntity> getAllFlows(Set<BucketEntity> buckets) {
+ return flowRepository.findByBucketIn(buckets);
+ }
+
+ private List<FlowEntity> getPagedFlows(final QueryParameters params, Set<BucketEntity> buckets) {
+ final Pageable pageable = getPageRequest(params);
+ return flowRepository.findByBucketIn(buckets, pageable);
+ }
+
+ private List<FlowEntity> getSortedFlows(final QueryParameters params, Set<BucketEntity> buckets) {
+ final Sort sort = getSort(params);
+ return flowRepository.findByBucketIn(buckets, sort);
+ }
+
// ------------------------------------------------------------------------------------
@Override
@@ -329,9 +398,18 @@ public class DatabaseMetadataService implements MetadataService {
}
@Override
- public FlowSnapshotEntity getFlowSnapshot(final String flowIdentifier, final Integer version) {
+ public FlowSnapshotEntity getFlowSnapshot(final String bucketIdentifier, final String flowIdentifier, final Integer version) {
final FlowSnapshotEntityKey key = new FlowSnapshotEntityKey(flowIdentifier, version);
- return flowSnapshotRepository.findOne(key);
+ FlowSnapshotEntity flowSnapshot = flowSnapshotRepository.findOne(key);
+
+ if (flowSnapshot == null
+ || flowSnapshot.getFlow() == null
+ || flowSnapshot.getFlow().getBucket() == null
+ || !bucketIdentifier.equals(flowSnapshot.getFlow().getBucket().getId())) {
+ return null;
+ }
+
+ return flowSnapshot;
}
@Override
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java
index 85d98ad..2f188e1 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketItemRepository.java
@@ -24,6 +24,7 @@ import org.springframework.data.domain.Sort;
import org.springframework.data.repository.Repository;
import java.util.List;
+import java.util.Set;
/**
* Repository for BucketItems that exposes only the methods from PagingAndSortingRepository.
@@ -81,4 +82,30 @@ public interface BucketItemRepository extends Repository<BucketItemEntity,String
*/
List<BucketItemEntity> findByBucket(BucketEntity bucket, Pageable pageable);
+ /**
+ * Find all items by buckets.
+ *
+ * @param buckets the buckets to find items for
+ * @return the list of items for the buckets
+ */
+ List<BucketItemEntity> findByBucketIn(Set<BucketEntity> buckets);
+
+ /**
+ * Find all items by buckets with sorting.
+ *
+ * @param buckets the buckets to find items for
+ * @param sort the sort params
+ * @return the list of items for the buckets
+ */
+ List<BucketItemEntity> findByBucketIn(Set<BucketEntity> buckets, Sort sort);
+
+ /**
+ * Find all items by buckets with paging/sorting.
+ *
+ * @param buckets the buckets to find items for
+ * @param pageable the pageable params
+ * @return the list of items for the buckets based on the pageable params
+ */
+ List<BucketItemEntity> findByBucketIn(Set<BucketEntity> buckets, Pageable pageable);
+
}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java
index e917c2d..f7fb7fb 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/BucketRepository.java
@@ -20,6 +20,7 @@ import org.apache.nifi.registry.db.entity.BucketEntity;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
+import java.util.Set;
/**
* Spring Data Repository for BucketEntity.
@@ -28,4 +29,6 @@ public interface BucketRepository extends PagingAndSortingRepository<BucketEntit
List<BucketEntity> findByNameIgnoreCase(String name);
+ List<BucketEntity> findByIdIn(Set<String> id);
+
}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java
index ac20f81..bfda5d0 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/db/repository/FlowRepository.java
@@ -16,10 +16,14 @@
*/
package org.apache.nifi.registry.db.repository;
+import org.apache.nifi.registry.db.entity.BucketEntity;
import org.apache.nifi.registry.db.entity.FlowEntity;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.Sort;
import org.springframework.data.repository.PagingAndSortingRepository;
import java.util.List;
+import java.util.Set;
/**
* Spring Data Repository for FlowEntity.
@@ -28,4 +32,30 @@ public interface FlowRepository extends PagingAndSortingRepository<FlowEntity,St
List<FlowEntity> findByNameIgnoreCase(String name);
+ /**
+ * Find all flows by buckets.
+ *
+ * @param buckets the buckets to find items for
+ * @return the list of items for the buckets
+ */
+ List<FlowEntity> findByBucketIn(Set<BucketEntity> buckets);
+
+ /**
+ * Find all flows by buckets with sorting.
+ *
+ * @param buckets the buckets to find flows for
+ * @param sort the sort params
+ * @return the list of flows for the buckets
+ */
+ List<FlowEntity> findByBucketIn(Set<BucketEntity> buckets, Sort sort);
+
+ /**
+ * Find all flows by buckets with paging/sorting.
+ *
+ * @param buckets the buckets to find flows for
+ * @param pageable the pageable params
+ * @return the list of flows for the buckets based on the pageable params
+ */
+ List<FlowEntity> findByBucketIn(Set<BucketEntity> buckets, Pageable pageable);
+
}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.java
new file mode 100644
index 0000000..8f9180c
--- /dev/null
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/exception/AdministrationException.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.registry.exception;
+
+/**
+ *
+ */
+public class AdministrationException extends RuntimeException {
+
+ public AdministrationException(Throwable cause) {
+ super(cause);
+ }
+
+ public AdministrationException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AdministrationException(String message) {
+ super(message);
+ }
+
+ public AdministrationException() {
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
new file mode 100644
index 0000000..c62d170
--- /dev/null
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/AuthorizationService.java
@@ -0,0 +1,695 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.registry.service;
+
+import org.apache.nifi.registry.authorization.AccessPolicyProvider;
+import org.apache.nifi.registry.authorization.AccessPolicyProviderInitializationContext;
+import org.apache.nifi.registry.authorization.AuthorizableLookup;
+import org.apache.nifi.registry.authorization.exception.AccessDeniedException;
+import org.apache.nifi.registry.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.registry.authorization.AuthorizeAccess;
+import org.apache.nifi.registry.authorization.Authorizer;
+import org.apache.nifi.registry.authorization.AuthorizerCapabilityDetection;
+import org.apache.nifi.registry.authorization.AuthorizerConfigurationContext;
+import org.apache.nifi.registry.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.registry.authorization.exception.AuthorizerDestructionException;
+import org.apache.nifi.registry.authorization.ConfigurableAccessPolicyProvider;
+import org.apache.nifi.registry.authorization.ConfigurableUserGroupProvider;
+import org.apache.nifi.registry.authorization.Group;
+import org.apache.nifi.registry.authorization.ManagedAuthorizer;
+import org.apache.nifi.registry.authorization.RequestAction;
+import org.apache.nifi.registry.authorization.UserAndGroups;
+import org.apache.nifi.registry.authorization.UserGroupProvider;
+import org.apache.nifi.registry.authorization.UserGroupProviderInitializationContext;
+import org.apache.nifi.registry.authorization.resource.ResourceFactory;
+import org.apache.nifi.registry.authorization.resource.ResourceType;
+import org.apache.nifi.registry.authorization.user.NiFiUserUtils;
+import org.apache.nifi.registry.bucket.Bucket;
+import org.apache.nifi.registry.model.authorization.AccessPolicy;
+import org.apache.nifi.registry.model.authorization.AccessPolicySummary;
+import org.apache.nifi.registry.model.authorization.Resource;
+import org.apache.nifi.registry.model.authorization.Tenant;
+import org.apache.nifi.registry.model.authorization.User;
+import org.apache.nifi.registry.model.authorization.UserGroup;
+import org.apache.nifi.registry.service.params.QueryParameters;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Collectors;
+
+@Service
+public class AuthorizationService {
+
+ public static final String MSG_NON_MANAGED_AUTHORIZER = "This NiFi Registry is not configured to internally manage users, groups, or policies. Please contact your system administrator.";
+ public static final String MSG_NON_CONFIGURABLE_POLICIES = "This NiFi Registry is not configured to allow configurable policies. Please contact your system administrator.";
+ public static final String MSG_NON_CONFIGURABLE_USERS = "This NiFi Registry is not configured to allow configurable users and groups. Please contact your system administrator.";
+
+ private AuthorizableLookup authorizableLookup;
+ private Authorizer authorizer;
+ private RegistryService registryService;
+ private UserGroupProvider userGroupProvider;
+ private AccessPolicyProvider accessPolicyProvider;
+
+ private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
+ private final Lock readLock = lock.readLock();
+ private final Lock writeLock = lock.writeLock();
+
+ @Autowired
+ public AuthorizationService(
+ final AuthorizableLookup authorizableLookup,
+ final Authorizer authorizer,
+ final RegistryService registryService) {
+ this.authorizableLookup = authorizableLookup;
+ this.authorizer = authorizer;
+ this.registryService = registryService;
+
+ if (AuthorizerCapabilityDetection.isManagedAuthorizer(this.authorizer)) {
+ this.accessPolicyProvider = ((ManagedAuthorizer) authorizer).getAccessPolicyProvider();
+ } else {
+ this.accessPolicyProvider = createExceptionThrowingAccessPolicyProvider();
+ }
+ this.userGroupProvider = accessPolicyProvider.getUserGroupProvider();
+ }
+
+
+ // ---------------------- Authorization methods -------------------------------------
+
+ public void authorizeAccess(final AuthorizeAccess authorizeAccess) {
+ authorizeAccess.authorize(authorizableLookup);
+ }
+
+
+ // ---------------------- Tenant methods --------------------------------------------
+
+ public Tenant getTenant(String identifier) {
+ this.readLock.lock();
+ try {
+ org.apache.nifi.registry.authorization.User user = userGroupProvider.getUser(identifier);
+ if (user != null) {
+ return tenantToDTO(user);
+ } else {
+ org.apache.nifi.registry.authorization.Group group = userGroupProvider.getGroup(identifier);
+ return tenantToDTO(group);
+ }
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+
+ // ---------------------- User methods ----------------------------------------------
+
+ public User createUser(User user) {
+ verifyUserGroupProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ final org.apache.nifi.registry.authorization.User createdUser =
+ ((ConfigurableUserGroupProvider) userGroupProvider).addUser(userFromDTO(user));
+ return userToDTO(createdUser);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public List<User> getUsers() {
+ this.readLock.lock();
+ try {
+ return userGroupProvider.getUsers().stream().map(this::userToDTO).collect(Collectors.toList());
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ public User getUser(String identifier) {
+ this.readLock.lock();
+ try {
+ return userToDTO(userGroupProvider.getUser(identifier));
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ public User updateUser(User user) {
+ verifyUserGroupProviderIsConfigurable();
+ this.writeLock.lock();
+ try {
+ final org.apache.nifi.registry.authorization.User updatedUser =
+ ((ConfigurableUserGroupProvider) userGroupProvider).updateUser(userFromDTO(user));
+ return userToDTO(updatedUser);
+ } finally {
+ this.writeLock.unlock();
+ }
+ }
+
+ public User deleteUser(String identifier) {
+ verifyUserGroupProviderIsConfigurable();
+ this.writeLock.lock();
+ try {
+ User deletedUserDTO = getUser(identifier);
+ ((ConfigurableUserGroupProvider) userGroupProvider).deleteUser(identifier);
+ return deletedUserDTO;
+ } finally {
+ this.writeLock.unlock();
+ }
+ }
+
+
+ // ---------------------- User Group methods --------------------------------------
+
+ public UserGroup createUserGroup(UserGroup userGroup) {
+ verifyUserGroupProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ final org.apache.nifi.registry.authorization.Group createdGroup =
+ ((ConfigurableUserGroupProvider) userGroupProvider).addGroup(userGroupFromDTO(userGroup));
+ return userGroupToDTO(createdGroup);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public List<UserGroup> getUserGroups() {
+ this.readLock.lock();
+ try {
+ return userGroupProvider.getGroups().stream().map(this::userGroupToDTO).collect(Collectors.toList());
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ public List<UserGroup> getUserGroupsForUser(String userIdentifier) {
+ this.readLock.lock();
+ try {
+ return userGroupProvider.getGroups()
+ .stream()
+ .filter(group -> group.getUsers().contains(userIdentifier))
+ .map(this::userGroupToDTO)
+ .collect(Collectors.toList());
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ public UserGroup getUserGroup(String identifier) {
+ this.readLock.lock();
+ try {
+ return userGroupToDTO(userGroupProvider.getGroup(identifier));
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ public UserGroup updateUserGroup(UserGroup userGroup) {
+ verifyUserGroupProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ final org.apache.nifi.registry.authorization.Group updatedGroup =
+ ((ConfigurableUserGroupProvider) userGroupProvider).updateGroup(userGroupFromDTO(userGroup));
+ return userGroupToDTO(updatedGroup);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public UserGroup deleteUserGroup(String identifier) {
+ verifyUserGroupProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ final UserGroup userGroupDTO = getUserGroup(identifier);
+ ((ConfigurableUserGroupProvider) userGroupProvider).deleteGroup(identifier);
+ return userGroupDTO;
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+
+ // ---------------------- Access Policy methods ----------------------------------------
+
+ public AccessPolicy createAccessPolicy(AccessPolicy accessPolicy) {
+ verifyAccessPolicyProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ org.apache.nifi.registry.authorization.AccessPolicy createdAccessPolicy =
+ ((ConfigurableAccessPolicyProvider) accessPolicyProvider).addAccessPolicy(accessPolicyFromDTO(accessPolicy));
+ return accessPolicyToDTO(createdAccessPolicy);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public AccessPolicy getAccessPolicy(String identifier) {
+ readLock.lock();
+ try {
+ return accessPolicyToDTO(accessPolicyProvider.getAccessPolicy(identifier));
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public AccessPolicy getAccessPolicy(String resource, RequestAction action) {
+ readLock.lock();
+ try {
+ return accessPolicyToDTO(accessPolicyProvider.getAccessPolicy(resource, action));
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public List<AccessPolicy> getAccessPolicies() {
+ readLock.lock();
+ try {
+ return accessPolicyProvider.getAccessPolicies().stream().map(this::accessPolicyToDTO).collect(Collectors.toList());
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public List<AccessPolicySummary> getAccessPolicySummaries() {
+ readLock.lock();
+ try {
+ return accessPolicyProvider.getAccessPolicies().stream().map(this::accessPolicyToSummaryDTO).collect(Collectors.toList());
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public List<AccessPolicy> getAccessPoliciesForUser(String userIdentifier) {
+ readLock.lock();
+ try {
+ return accessPolicyProvider.getAccessPolicies().stream()
+ .filter(accessPolicy -> accessPolicy.getUsers().contains(userIdentifier))
+ .map(this::accessPolicyToDTO)
+ .collect(Collectors.toList());
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public List<AccessPolicySummary> getAccessPolicySummariesForUser(String userIdentifier) {
+ readLock.lock();
+ try {
+ return accessPolicyProvider.getAccessPolicies().stream()
+ .filter(accessPolicy -> accessPolicy.getUsers().contains(userIdentifier))
+ .map(this::accessPolicyToSummaryDTO)
+ .collect(Collectors.toList());
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public List<AccessPolicySummary> getAccessPolicySummariesForUserGroup(String userGroupIdentifier) {
+ readLock.lock();
+ try {
+ return accessPolicyProvider.getAccessPolicies().stream()
+ .filter(accessPolicy -> accessPolicy.getGroups().contains(userGroupIdentifier))
+ .map(this::accessPolicyToSummaryDTO)
+ .collect(Collectors.toList());
+ } finally {
+ readLock.unlock();
+ }
+ }
+
+ public AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) {
+ verifyAccessPolicyProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ // Don't allow changing action or resource of existing policy (should only be adding/removing users/groups)
+ org.apache.nifi.registry.authorization.AccessPolicy currentAccessPolicy =
+ accessPolicyProvider.getAccessPolicy(accessPolicy.getIdentifier());
+ accessPolicy.setResource(currentAccessPolicy.getResource());
+ accessPolicy.setAction(currentAccessPolicy.getAction().toString());
+
+ org.apache.nifi.registry.authorization.AccessPolicy updateAccessPolicy =
+ ((ConfigurableAccessPolicyProvider) accessPolicyProvider).updateAccessPolicy(accessPolicyFromDTO(accessPolicy));
+ return accessPolicyToDTO(updateAccessPolicy);
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+ public AccessPolicy deleteAccessPolicy(String identifier) {
+ verifyAccessPolicyProviderIsConfigurable();
+ writeLock.lock();
+ try {
+ AccessPolicy deletedAccessPolicyDTO = getAccessPolicy(identifier);
+ ((ConfigurableAccessPolicyProvider) accessPolicyProvider).deleteAccessPolicy(identifier);
+ return deletedAccessPolicyDTO;
+ } finally {
+ writeLock.unlock();
+ }
+ }
+
+
+ // ---------------------- Resource Lookup methods --------------------------------------
+
+ public List<Resource> getAuthorizedResources(RequestAction actionType, ResourceType resourceType) {
+ final List<Resource> authorizedResources =
+ getAllAuthorizableResources()
+ .stream()
+ .filter(resource -> {
+ String resourceId = resource.getIdentifier();
+ if (resourceType != null) {
+ if (!resourceId.startsWith(resourceType.getValue())) {
+ return false;
+ }
+ }
+ try {
+ authorizableLookup
+ .getAuthorizableByResource(resource.getIdentifier())
+ .authorize(authorizer, actionType, NiFiUserUtils.getNiFiUser());
+ } catch (AccessDeniedException e) {
+ return false;
+ }
+ return true;
+
+ })
+ .map(AuthorizationService::resourceToDTO)
+ .collect(Collectors.toList());
+
+ return authorizedResources;
+ }
+
+ public List<Resource> getAuthorizedResources(RequestAction actionType) {
+ return getAuthorizedResources(actionType, null);
+ }
+
+ public List<Resource> getResources() {
+ final List<Resource> dtoResources =
+ getAllAuthorizableResources()
+ .stream()
+ .map(AuthorizationService::resourceToDTO)
+ .collect(Collectors.toList());
+ return dtoResources;
+ }
+
+
+ // ---------------------- Private Helper methods --------------------------------------
+
+ private void verifyUserGroupProviderIsConfigurable() {
+ if (!(userGroupProvider instanceof ConfigurableUserGroupProvider)) {
+ throw new IllegalStateException(MSG_NON_CONFIGURABLE_USERS);
+ }
+ }
+
+ private void verifyAccessPolicyProviderIsConfigurable() {
+ if (!(accessPolicyProvider instanceof ConfigurableAccessPolicyProvider)) {
+ throw new IllegalStateException(MSG_NON_CONFIGURABLE_POLICIES);
+ }
+ }
+
+ private List<org.apache.nifi.registry.authorization.Resource> getAllAuthorizableResources() {
+ final List<org.apache.nifi.registry.authorization.Resource> resources = new ArrayList<>();
+ resources.add(ResourceFactory.getPoliciesResource());
+ resources.add(ResourceFactory.getTenantResource());
+ resources.add(ResourceFactory.getProxyResource());
+ resources.add(ResourceFactory.getResourceResource());
+
+ // add all buckets
+ resources.add(ResourceFactory.getBucketsResource());
+ for (final Bucket bucket : registryService.getBuckets(QueryParameters.EMPTY_PARAMETERS)) {
+ resources.add(ResourceFactory.getChildResource(ResourceType.Bucket, bucket.getIdentifier(), bucket.getName()));
+ }
+
+ return resources;
+ }
+
+ private org.apache.nifi.registry.model.authorization.User userToDTO(
+ final org.apache.nifi.registry.authorization.User user) {
+ if (user == null) {
+ return null;
+ }
+ String userIdentifier = user.getIdentifier();
+ Collection<UserGroup> userGroups = getUserGroupsForUser(userIdentifier);
+ Collection<AccessPolicySummary> accessPolicySummaries = getAccessPolicySummariesForUser(userIdentifier);
+
+ return userToDTO(user, userGroups, accessPolicySummaries);
+ }
+
+ private org.apache.nifi.registry.model.authorization.UserGroup userGroupToDTO(
+ final org.apache.nifi.registry.authorization.Group userGroup) {
+ if (userGroup == null) {
+ return null;
+ }
+ Collection<Tenant> userTenants = userGroup.getUsers() != null
+ ? userGroup.getUsers().stream().map(this::getTenant).collect(Collectors.toSet()) : null;
+ Collection<AccessPolicySummary> accessPolicySummaries = getAccessPolicySummariesForUserGroup(userGroup.getIdentifier());
+
+ return userGroupToDTO(userGroup, userTenants, accessPolicySummaries);
+ }
+
+ private org.apache.nifi.registry.model.authorization.AccessPolicy accessPolicyToDTO(
+ final org.apache.nifi.registry.authorization.AccessPolicy accessPolicy) {
+ if (accessPolicy == null) {
+ return null;
+ }
+
+ Collection<Tenant> users = accessPolicy.getUsers() != null
+ ? accessPolicy.getUsers().stream().map(this::getTenant).collect(Collectors.toList()) : null;
+ Collection<Tenant> userGroups = accessPolicy.getGroups() != null
+ ? accessPolicy.getGroups().stream().map(this::getTenant).collect(Collectors.toList()) : null;
+
+ Boolean isConfigurable = AuthorizerCapabilityDetection.isAccessPolicyConfigurable(authorizer, accessPolicy);
+
+ return accessPolicyToDTO(accessPolicy, userGroups, users, isConfigurable);
+ }
+
+ private org.apache.nifi.registry.model.authorization.AccessPolicySummary accessPolicyToSummaryDTO(
+ final org.apache.nifi.registry.authorization.AccessPolicy accessPolicy) {
+ if (accessPolicy == null) {
+ return null;
+ }
+
+ Boolean isConfigurable = AuthorizerCapabilityDetection.isAccessPolicyConfigurable(authorizer, accessPolicy);
+
+ final AccessPolicySummary accessPolicySummaryDTO = new AccessPolicySummary();
+ accessPolicySummaryDTO.setIdentifier(accessPolicy.getIdentifier());
+ accessPolicySummaryDTO.setAction(accessPolicy.getAction().toString());
+ accessPolicySummaryDTO.setResource(accessPolicy.getResource());
+ accessPolicySummaryDTO.setConfigurable(isConfigurable);
+ return accessPolicySummaryDTO;
+ }
+
+ private static Resource resourceToDTO(org.apache.nifi.registry.authorization.Resource resource) {
+ if (resource == null) {
+ return null;
+ }
+ Resource resourceDto = new Resource();
+ resourceDto.setIdentifier(resource.getIdentifier());
+ resourceDto.setName(resource.getName());
+ return resourceDto;
+ }
+
+ private static Tenant tenantToDTO(org.apache.nifi.registry.authorization.User user) {
+ if (user == null) {
+ return null;
+ }
+ return new Tenant(user.getIdentifier(), user.getIdentity());
+ }
+
+ private static Tenant tenantToDTO(org.apache.nifi.registry.authorization.Group group) {
+ if (group == null) {
+ return null;
+ }
+ return new Tenant(group.getIdentifier(), group.getName());
+ }
+
+ private static org.apache.nifi.registry.authorization.User userFromDTO(
+ final org.apache.nifi.registry.model.authorization.User userDTO) {
+ if (userDTO == null) {
+ return null;
+ }
+ return new org.apache.nifi.registry.authorization.User.Builder()
+ .identifier(userDTO.getIdentifier() != null ? userDTO.getIdentifier() : UUID.randomUUID().toString())
+ .identity(userDTO.getIdentity())
+ .build();
+ }
+
+ private static org.apache.nifi.registry.model.authorization.User userToDTO(
+ final org.apache.nifi.registry.authorization.User user,
+ final Collection<? extends Tenant> userGroups,
+ final Collection<? extends AccessPolicySummary> accessPolicies) {
+
+ if (user == null) {
+ return null;
+ }
+ User userDTO = new User(user.getIdentifier(), user.getIdentity());
+ userDTO.addUserGroups(userGroups);
+ userDTO.addAccessPolicies(accessPolicies);
+ return userDTO;
+ }
+
+ private static org.apache.nifi.registry.authorization.Group userGroupFromDTO(
+ final org.apache.nifi.registry.model.authorization.UserGroup userGroupDTO) {
+ if (userGroupDTO == null) {
+ return null;
+ }
+ org.apache.nifi.registry.authorization.Group.Builder groupBuilder = new org.apache.nifi.registry.authorization.Group.Builder()
+ .identifier(userGroupDTO.getIdentifier() != null ? userGroupDTO.getIdentifier() : UUID.randomUUID().toString())
+ .name(userGroupDTO.getIdentity());
+ Set<Tenant> users = userGroupDTO.getUsers();
+ if (users != null) {
+ groupBuilder.addUsers(users.stream().map(Tenant::getIdentifier).collect(Collectors.toSet()));
+ }
+ return groupBuilder.build();
+ }
+
+ private static org.apache.nifi.registry.model.authorization.UserGroup userGroupToDTO(
+ final org.apache.nifi.registry.authorization.Group userGroup,
+ final Collection<? extends Tenant> users,
+ final Collection<? extends AccessPolicySummary> accessPolicies) {
+ if (userGroup == null) {
+ return null;
+ }
+ UserGroup userGroupDTO = new UserGroup(userGroup.getIdentifier(), userGroup.getName());
+ userGroupDTO.addUsers(users);
+ userGroupDTO.addAccessPolicies(accessPolicies);
+ return userGroupDTO;
+ }
+
+ private static org.apache.nifi.registry.authorization.AccessPolicy accessPolicyFromDTO(
+ final org.apache.nifi.registry.model.authorization.AccessPolicy accessPolicyDTO) {
+ org.apache.nifi.registry.authorization.AccessPolicy.Builder accessPolicyBuilder =
+ new org.apache.nifi.registry.authorization.AccessPolicy.Builder()
+ .identifier(accessPolicyDTO.getIdentifier() != null ? accessPolicyDTO.getIdentifier() : UUID.randomUUID().toString())
+ .resource(accessPolicyDTO.getResource())
+ .action(RequestAction.valueOfValue(accessPolicyDTO.getAction()));
+
+ Set<Tenant> dtoUsers = accessPolicyDTO.getUsers();
+ if (accessPolicyDTO.getUsers() != null) {
+ accessPolicyBuilder.addUsers(dtoUsers.stream().map(Tenant::getIdentifier).collect(Collectors.toSet()));
+ }
+
+ Set<Tenant> dtoUserGroups = accessPolicyDTO.getUserGroups();
+ if (dtoUserGroups != null) {
+ accessPolicyBuilder.addGroups(dtoUserGroups.stream().map(Tenant::getIdentifier).collect(Collectors.toSet()));
+ }
+
+ return accessPolicyBuilder.build();
+ }
+
+ private static org.apache.nifi.registry.model.authorization.AccessPolicy accessPolicyToDTO(
+ final org.apache.nifi.registry.authorization.AccessPolicy accessPolicy,
+ final Collection<? extends Tenant> userGroups,
+ final Collection<? extends Tenant> users,
+ final Boolean isConfigurable) {
+
+ if (accessPolicy == null) {
+ return null;
+ }
+
+ final AccessPolicy accessPolicyDTO = new AccessPolicy();
+ accessPolicyDTO.setIdentifier(accessPolicy.getIdentifier());
+ accessPolicyDTO.setAction(accessPolicy.getAction().toString());
+ accessPolicyDTO.setResource(accessPolicy.getResource());
+ accessPolicyDTO.setConfigurable(isConfigurable);
+ accessPolicyDTO.addUsers(users);
+ accessPolicyDTO.addUserGroups(userGroups);
+ return accessPolicyDTO;
+ }
+
+ private static AccessPolicyProvider createExceptionThrowingAccessPolicyProvider() {
+
+ return new AccessPolicyProvider() {
+ @Override
+ public Set<org.apache.nifi.registry.authorization.AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public org.apache.nifi.registry.authorization.AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public org.apache.nifi.registry.authorization.AccessPolicy getAccessPolicy(String resourceIdentifier, RequestAction action) throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public UserGroupProvider getUserGroupProvider() {
+ return new UserGroupProvider() {
+ @Override
+ public Set<org.apache.nifi.registry.authorization.User> getUsers() throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public org.apache.nifi.registry.authorization.User getUser(String identifier) throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public org.apache.nifi.registry.authorization.User getUserByIdentity(String identity) throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public Set<Group> getGroups() throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public Group getGroup(String identifier) throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public UserAndGroups getUserAndGroups(String identity) throws AuthorizationAccessException {
+ throw new IllegalStateException(MSG_NON_MANAGED_AUTHORIZER);
+ }
+
+ @Override
+ public void initialize(UserGroupProviderInitializationContext initializationContext) throws AuthorizerCreationException {
+
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+
+ }
+ };
+ }
+
+ @Override
+ public void initialize(AccessPolicyProviderInitializationContext initializationContext) throws AuthorizerCreationException {
+ }
+
+ @Override
+ public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+ }
+ };
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/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 3c17cee..2a85c84 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
@@ -96,6 +96,15 @@ public interface MetadataService {
List<BucketItemEntity> getBucketItems(QueryParameters queryParameters, BucketEntity bucket);
/**
+ * Retrieves items for the given buckets.
+ *
+ * @param bucketIds the ids of buckets to retrieve items for
+ * @param queryParameters the parameters for retrieving the items, or null
+ * @return the set of items for the bucket
+ */
+ List<BucketItemEntity> getBucketItems(QueryParameters queryParameters, Set<String> bucketIds);
+
+ /**
* Creates a versioned flow in the given bucket.
*
* @param flow the versioned flow to create
@@ -107,10 +116,11 @@ public interface MetadataService {
/**
* Retrieves the versioned flow with the given id.
*
+ * @param bucketIdentifier the identifier of the bucket storing the flow
* @param flowIdentifier the identifier of the flow to retrieve
* @return the versioned flow with the given id, or null if no flow with the given id exists
*/
- FlowEntity getFlowById(String flowIdentifier);
+ FlowEntity getFlowById(String bucketIdentifier, String flowIdentifier);
/**
* Retrieves the versioned flows with the given name. The name comparison must be case-insensitive.
@@ -144,6 +154,15 @@ public interface MetadataService {
List<FlowEntity> getFlows(QueryParameters queryParameters);
/**
+ * Retrieves items for the given buckets.
+ *
+ * @param bucketIds the ids of buckets to retrieve items for
+ * @param queryParameters the parameters for retrieving the items, or null
+ * @return the set of items for the bucket
+ */
+ List<FlowEntity> getFlows(QueryParameters queryParameters, Set<String> bucketIds);
+
+ /**
* Creates a versioned flow snapshot.
*
* @param flowSnapshot the snapshot to create
@@ -155,11 +174,12 @@ public interface MetadataService {
/**
* Retrieves the snapshot for the given flow identifier and snapshot version.
*
+ * @param bucketIdentifier the identifier of the bucket storign the flow
* @param flowIdentifier the identifier of the flow the snapshot belongs to
* @param version the version of the snapshot
* @return the versioned flow snapshot for the given flow identifier and version, or null if none exists
*/
- FlowSnapshotEntity getFlowSnapshot(String flowIdentifier, Integer version);
+ FlowSnapshotEntity getFlowSnapshot(String bucketIdentifier, String flowIdentifier, Integer version);
/**
* Deletes the flow snapshot.
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/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 fc067e6..f0fc927 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
@@ -261,6 +261,21 @@ public class RegistryService {
}
}
+ public List<BucketItem> getBucketItems(final QueryParameters queryParameters, final Set<String> bucketIdentifiers) {
+ if (bucketIdentifiers == null || bucketIdentifiers.isEmpty()) {
+ throw new IllegalArgumentException("Bucket Identifiers cannot be null or empty");
+ }
+
+ readLock.lock();
+ try {
+ final List<BucketItem> bucketItems = new ArrayList<>();
+ metadataService.getBucketItems(queryParameters, bucketIdentifiers).stream().forEach(b -> addBucketItem(bucketItems, b));
+ return bucketItems;
+ } finally {
+ readLock.unlock();
+ }
+ }
+
private void addBucketItem(final List<BucketItem> bucketItems, final BucketItemEntity itemEntity) {
if (itemEntity instanceof FlowEntity) {
final FlowEntity flowEntity = (FlowEntity) itemEntity;
@@ -326,14 +341,14 @@ public class RegistryService {
}
}
- public VersionedFlow getFlow(final String flowIdentifier, final boolean verbose) {
+ public VersionedFlow getFlow(final String bucketIdentifier, final String flowIdentifier, final boolean verbose) {
if (StringUtils.isBlank(flowIdentifier)) {
throw new IllegalArgumentException("Flow Identifier cannot be null or blank");
}
readLock.lock();
try {
- final FlowEntity flowEntity = metadataService.getFlowById(flowIdentifier);
+ final FlowEntity flowEntity = metadataService.getFlowById(bucketIdentifier, flowIdentifier);
if (flowEntity == null) {
throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + flowIdentifier);
}
@@ -375,6 +390,17 @@ public class RegistryService {
}
}
+ public List<VersionedFlow> getFlows(final QueryParameters queryParameters, final Set<String> bucketIds) {
+ readLock.lock();
+ try {
+ // return non-verbose set of all flows
+ final List<FlowEntity> flows = metadataService.getFlows(queryParameters, bucketIds);
+ return flows.stream().map(f -> DataModelMapper.map(f, false)).collect(Collectors.toList());
+ } finally {
+ readLock.unlock();
+ }
+ }
+
public VersionedFlow updateFlow(final VersionedFlow versionedFlow) {
if (versionedFlow == null) {
throw new IllegalArgumentException("VersionedFlow cannot be null");
@@ -384,10 +410,14 @@ public class RegistryService {
throw new IllegalArgumentException("VersionedFlow identifier cannot be null or blank");
}
+ if (StringUtils.isBlank(versionedFlow.getBucketIdentifier())) {
+ throw new IllegalArgumentException("VersionedFlow bucket identifier cannot be null or blank");
+ }
+
writeLock.lock();
try {
// ensure a flow with the given id exists
- final FlowEntity existingFlow = metadataService.getFlowById(versionedFlow.getIdentifier());
+ final FlowEntity existingFlow = metadataService.getFlowById(versionedFlow.getBucketIdentifier(), versionedFlow.getIdentifier());
if (existingFlow == null) {
throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + versionedFlow.getIdentifier());
}
@@ -422,7 +452,10 @@ public class RegistryService {
}
}
- public VersionedFlow deleteFlow(final String flowIdentifier) {
+ public VersionedFlow deleteFlow(final String bucketIdentifier, final String flowIdentifier) {
+ if (StringUtils.isBlank(bucketIdentifier)) {
+ throw new IllegalArgumentException("Bucket Identifier cannot be null or blank");
+ }
if (StringUtils.isBlank(flowIdentifier)) {
throw new IllegalArgumentException("Flow Identifier cannot be null or blank");
}
@@ -430,7 +463,7 @@ public class RegistryService {
writeLock.lock();
try {
// ensure the flow exists
- final FlowEntity existingFlow = metadataService.getFlowById(flowIdentifier);
+ final FlowEntity existingFlow = metadataService.getFlowById(bucketIdentifier, flowIdentifier);
if (existingFlow == null) {
throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + flowIdentifier);
}
@@ -472,7 +505,7 @@ public class RegistryService {
}
// ensure the flow exists
- final FlowEntity existingFlow = metadataService.getFlowById(snapshotMetadata.getFlowIdentifier());
+ final FlowEntity existingFlow = metadataService.getFlowById(snapshotMetadata.getBucketIdentifier(), snapshotMetadata.getFlowIdentifier());
if (existingFlow == null) {
throw new ResourceNotFoundException("VersionedFlow does not exist for identifier: " + snapshotMetadata.getFlowIdentifier());
}
@@ -518,9 +551,13 @@ public class RegistryService {
}
}
- public VersionedFlowSnapshot getFlowSnapshot(final String flowIdentifier, final Integer version) {
+ public VersionedFlowSnapshot getFlowSnapshot(final String bucketIdentifier, final String flowIdentifier, final Integer version) {
+ if (StringUtils.isBlank(bucketIdentifier)) {
+ throw new IllegalArgumentException("Bucket identifier cannot be null or blank");
+ }
+
if (StringUtils.isBlank(flowIdentifier)) {
- throw new IllegalArgumentException("Flow Identifier cannot be null or blank");
+ throw new IllegalArgumentException("Flow identifier cannot be null or blank");
}
if (version == null) {
@@ -530,17 +567,13 @@ public class RegistryService {
readLock.lock();
try {
// ensure the snapshot exists
- final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(flowIdentifier, version);
+ final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(bucketIdentifier, flowIdentifier, version);
if (snapshotEntity == null) {
throw new ResourceNotFoundException("VersionedFlowSnapshot does not exist for flow " + flowIdentifier + " and version " + version);
}
- final FlowEntity flow = snapshotEntity.getFlow();
- final String flowId = flow.getId();
- final String bucketId = flow.getBucket().getId();
-
// get the serialized bytes of the snapshot
- final byte[] serializedSnapshot = flowPersistenceProvider.getSnapshot(bucketId, flowId, version);
+ final byte[] serializedSnapshot = flowPersistenceProvider.getSnapshot(bucketIdentifier, flowIdentifier, version);
if (serializedSnapshot == null || serializedSnapshot.length == 0) {
throw new IllegalStateException("No serialized content found for snapshot with flow identifier "
@@ -554,9 +587,13 @@ public class RegistryService {
}
}
- public VersionedFlowSnapshotMetadata deleteFlowSnapshot(final String flowIdentifier, final Integer version) {
+ public VersionedFlowSnapshotMetadata deleteFlowSnapshot(final String bucketIdentifier, final String flowIdentifier, final Integer version) {
+ if (StringUtils.isBlank(bucketIdentifier)) {
+ throw new IllegalArgumentException("Bucket identifier cannot be null or blank");
+ }
+
if (StringUtils.isBlank(flowIdentifier)) {
- throw new IllegalArgumentException("Flow Identifier cannot be null or blank");
+ throw new IllegalArgumentException("Flow identifier cannot be null or blank");
}
if (version == null) {
@@ -566,18 +603,14 @@ public class RegistryService {
writeLock.lock();
try {
// ensure the snapshot exists
- final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(flowIdentifier, version);
+ final FlowSnapshotEntity snapshotEntity = metadataService.getFlowSnapshot(bucketIdentifier, flowIdentifier, version);
if (snapshotEntity == null) {
throw new ResourceNotFoundException("VersionedFlowSnapshot does not exist for flow "
+ flowIdentifier + " and version " + version);
}
- final FlowEntity flow = snapshotEntity.getFlow();
- final String flowId = flow.getId();
- final String bucketId = flow.getBucket().getId();
-
// delete the content of the snapshot
- flowPersistenceProvider.deleteSnapshot(bucketId, flowId, version);
+ flowPersistenceProvider.deleteSnapshot(bucketIdentifier, flowIdentifier, version);
// delete the snapshot itself
metadataService.deleteFlowSnapshot(snapshotEntity);
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java
index 3c62a9d..9f30f75 100644
--- a/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java
+++ b/nifi-registry-framework/src/main/java/org/apache/nifi/registry/service/params/QueryParameters.java
@@ -26,6 +26,8 @@ import java.util.List;
*/
public class QueryParameters {
+ public static final QueryParameters EMPTY_PARAMETERS = new QueryParameters.Builder().build();
+
private final Integer pageNum;
private final Integer numRows;
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-framework/src/main/xsd/authorizers.xsd
----------------------------------------------------------------------
diff --git a/nifi-registry-framework/src/main/xsd/authorizers.xsd b/nifi-registry-framework/src/main/xsd/authorizers.xsd
new file mode 100644
index 0000000..278ff09
--- /dev/null
+++ b/nifi-registry-framework/src/main/xsd/authorizers.xsd
@@ -0,0 +1,67 @@
+<?xml version="1.0"?>
+<!--
+ ~ 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.
+ -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- user group providers type -->
+ <xs:complexType name="UserGroupProvider">
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="class" type="xs:string"/>
+ <xs:element name="property" type="Prop" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- access policy provider type -->
+ <xs:complexType name="AccessPolicyProvider">
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="class" type="xs:string"/>
+ <xs:element name="property" type="Prop" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- authorizers type -->
+ <xs:complexType name="Authorizer">
+ <xs:sequence>
+ <xs:element name="identifier" type="xs:string"/>
+ <xs:element name="class" type="xs:string"/>
+ <xs:element name="classpath" type="xs:string" minOccurs="0"/>
+ <xs:element name="property" type="Prop" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <!-- Name/Value properties-->
+ <xs:complexType name="Prop">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute name="name" type="xs:string"></xs:attribute>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <!-- authorizers -->
+ <xs:element name="authorizers">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="userGroupProvider" type="UserGroupProvider" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="accessPolicyProvider" type="AccessPolicyProvider" minOccurs="0" maxOccurs="unbounded"/>
+ <xs:element name="authorizer" type="Authorizer" minOccurs="0" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+</xs:schema>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/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 d4b42cf..2efa320 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
@@ -356,8 +356,8 @@ public class TestRegistryService {
@Test(expected = ResourceNotFoundException.class)
public void testGetFlowDoesNotExist() {
- when(metadataService.getFlowById(any(String.class))).thenReturn(null);
- registryService.getFlow("flow1", false);
+ when(metadataService.getFlowById(any(String.class), any(String.class))).thenReturn(null);
+ registryService.getFlow("bucket1","flow1", false);
}
@Test
@@ -376,9 +376,9 @@ public class TestRegistryService {
flowEntity.setModified(new Date());
flowEntity.setBucket(existingBucket);
- when(metadataService.getFlowById(flowEntity.getId())).thenReturn(flowEntity);
+ when(metadataService.getFlowById(existingBucket.getId(), flowEntity.getId())).thenReturn(flowEntity);
- final VersionedFlow versionedFlow = registryService.getFlow(flowEntity.getId(), false);
+ final VersionedFlow versionedFlow = registryService.getFlow(existingBucket.getId(), flowEntity.getId(), false);
assertNotNull(versionedFlow);
assertEquals(flowEntity.getId(), versionedFlow.getIdentifier());
assertEquals(flowEntity.getName(), versionedFlow.getName());
@@ -475,9 +475,10 @@ public class TestRegistryService {
@Test(expected = ResourceNotFoundException.class)
public void testUpdateFlowDoesNotExist() {
final VersionedFlow versionedFlow = new VersionedFlow();
+ versionedFlow.setBucketIdentifier("b1");
versionedFlow.setIdentifier("flow1");
- when(metadataService.getFlowById(versionedFlow.getIdentifier())).thenReturn(null);
+ when(metadataService.getFlowById(versionedFlow.getBucketIdentifier(), versionedFlow.getIdentifier())).thenReturn(null);
registryService.updateFlow(versionedFlow);
}
@@ -498,7 +499,7 @@ public class TestRegistryService {
flowToUpdate.setModified(new Date());
flowToUpdate.setBucket(existingBucket);
- when(metadataService.getFlowById(flowToUpdate.getId())).thenReturn(flowToUpdate);
+ when(metadataService.getFlowById(existingBucket.getId(), flowToUpdate.getId())).thenReturn(flowToUpdate);
final FlowEntity otherFlow = new FlowEntity();
otherFlow.setId("flow2");
@@ -512,6 +513,7 @@ public class TestRegistryService {
final VersionedFlow versionedFlow = new VersionedFlow();
versionedFlow.setIdentifier(flowToUpdate.getId());
+ versionedFlow.setBucketIdentifier(existingBucket.getId());
versionedFlow.setName(otherFlow.getName());
registryService.updateFlow(versionedFlow);
@@ -533,12 +535,13 @@ public class TestRegistryService {
flowToUpdate.setModified(new Date());
flowToUpdate.setBucket(existingBucket);
- when(metadataService.getFlowById(flowToUpdate.getId())).thenReturn(flowToUpdate);
+ when(metadataService.getFlowById(existingBucket.getId(), flowToUpdate.getId())).thenReturn(flowToUpdate);
when(metadataService.getFlowsByName(flowToUpdate.getName())).thenReturn(Collections.singletonList(flowToUpdate));
doAnswer(updateFlowAnswer()).when(metadataService).updateFlow(any(FlowEntity.class));
final VersionedFlow versionedFlow = new VersionedFlow();
+ versionedFlow.setBucketIdentifier(flowToUpdate.getBucket().getId());
versionedFlow.setIdentifier(flowToUpdate.getId());
versionedFlow.setName("New Flow Name");
versionedFlow.setDescription("This is a new description");
@@ -560,8 +563,8 @@ public class TestRegistryService {
@Test(expected = ResourceNotFoundException.class)
public void testDeleteFlowDoesNotExist() {
- when(metadataService.getFlowById(any(String.class))).thenReturn(null);
- registryService.deleteFlow("flow1");
+ when(metadataService.getFlowById(any(String.class), any(String.class))).thenReturn(null);
+ registryService.deleteFlow("b1", "flow1");
}
@Test
@@ -580,10 +583,10 @@ public class TestRegistryService {
flowToDelete.setModified(new Date());
flowToDelete.setBucket(existingBucket);
- when(metadataService.getFlowById(flowToDelete.getId())).thenReturn(flowToDelete);
+ when(metadataService.getFlowById(existingBucket.getId(), flowToDelete.getId())).thenReturn(flowToDelete);
when(metadataService.getFlowsByName(flowToDelete.getName())).thenReturn(Collections.singletonList(flowToDelete));
- final VersionedFlow deletedFlow = registryService.deleteFlow(flowToDelete.getId());
+ final VersionedFlow deletedFlow = registryService.deleteFlow(existingBucket.getId(), flowToDelete.getId());
assertNotNull(deletedFlow);
assertEquals(flowToDelete.getId(), deletedFlow.getIdentifier());
@@ -662,7 +665,7 @@ public class TestRegistryService {
when(metadataService.getBucketById(existingBucket.getId())).thenReturn(existingBucket);
- when(metadataService.getFlowById(snapshot.getSnapshotMetadata().getFlowIdentifier())).thenReturn(null);
+ when(metadataService.getFlowById(existingBucket.getId(), snapshot.getSnapshotMetadata().getFlowIdentifier())).thenReturn(null);
registryService.createFlowSnapshot(snapshot);
}
@@ -701,7 +704,7 @@ public class TestRegistryService {
existingFlow.setSnapshots(Collections.singleton(existingSnapshot));
- when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow);
+ when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow);
registryService.createFlowSnapshot(snapshot);
}
@@ -740,7 +743,7 @@ public class TestRegistryService {
existingFlow.setSnapshots(Collections.singleton(existingSnapshot));
- when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow);
+ when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow);
// set the version to something that is not the next one-up version
snapshot.getSnapshotMetadata().setVersion(100);
@@ -768,7 +771,7 @@ public class TestRegistryService {
existingFlow.setModified(new Date());
existingFlow.setBucket(existingBucket);
- when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow);
+ when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow);
final VersionedFlowSnapshot createdSnapshot = registryService.createFlowSnapshot(snapshot);
assertNotNull(createdSnapshot);
@@ -799,7 +802,7 @@ public class TestRegistryService {
existingFlow.setModified(new Date());
existingFlow.setBucket(existingBucket);
- when(metadataService.getFlowById(existingFlow.getId())).thenReturn(existingFlow);
+ when(metadataService.getFlowById(existingBucket.getId(), existingFlow.getId())).thenReturn(existingFlow);
// set the first version to something other than 1
snapshot.getSnapshotMetadata().setVersion(100);
@@ -808,18 +811,20 @@ public class TestRegistryService {
@Test(expected = ResourceNotFoundException.class)
public void testGetSnapshotDoesNotExistInMetadataProvider() {
+ final String bucketId = "b1";
final String flowId = "flow1";
final Integer version = 1;
- when(metadataService.getFlowSnapshot(flowId, version)).thenReturn(null);
- registryService.getFlowSnapshot(flowId, version);
+ when(metadataService.getFlowSnapshot(bucketId, flowId, version)).thenReturn(null);
+ registryService.getFlowSnapshot(bucketId, flowId, version);
}
@Test(expected = IllegalStateException.class)
public void testGetSnapshotDoesNotExistInPersistenceProvider() {
final FlowSnapshotEntity existingSnapshot = createFlowSnapshotEntity();
final FlowSnapshotEntityKey key = existingSnapshot.getId();
+ final String bucketId = existingSnapshot.getFlow().getBucket().getId();
- when(metadataService.getFlowSnapshot(key.getFlowId(), key.getVersion())).thenReturn(existingSnapshot);
+ when(metadataService.getFlowSnapshot(bucketId, key.getFlowId(), key.getVersion())).thenReturn(existingSnapshot);
when(flowPersistenceProvider.getSnapshot(
existingSnapshot.getFlow().getBucket().getId(),
@@ -827,15 +832,16 @@ public class TestRegistryService {
existingSnapshot.getId().getVersion()
)).thenReturn(null);
- registryService.getFlowSnapshot(existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion());
+ registryService.getFlowSnapshot(bucketId, existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion());
}
@Test
public void testGetSnapshotExists() {
final FlowSnapshotEntity existingSnapshot = createFlowSnapshotEntity();
final FlowSnapshotEntityKey key = existingSnapshot.getId();
+ final String bucketId = existingSnapshot.getFlow().getBucket().getId();
- when(metadataService.getFlowSnapshot(key.getFlowId(), key.getVersion()))
+ when(metadataService.getFlowSnapshot(bucketId, key.getFlowId(), key.getVersion()))
.thenReturn(existingSnapshot);
// return a non-null, non-zero-length array so something gets passed to the serializer
@@ -849,27 +855,29 @@ public class TestRegistryService {
when(snapshotSerializer.deserialize(any(InputStream.class))).thenReturn(snapshotToDeserialize);
final VersionedFlowSnapshot returnedSnapshot = registryService.getFlowSnapshot(
- existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion());
+ bucketId, existingSnapshot.getFlow().getId(), existingSnapshot.getId().getVersion());
assertNotNull(returnedSnapshot);
}
@Test(expected = ResourceNotFoundException.class)
public void testDeleteSnapshotDoesNotExist() {
+ final String bucketId = "b1";
final String flowId = "flow1";
final Integer version = 1;
- when(metadataService.getFlowSnapshot(flowId, version)).thenReturn(null);
- registryService.deleteFlowSnapshot(flowId, version);
+ when(metadataService.getFlowSnapshot(bucketId, flowId, version)).thenReturn(null);
+ registryService.deleteFlowSnapshot(bucketId, flowId, version);
}
@Test
public void testDeleteSnapshotExists() {
final FlowSnapshotEntity existingSnapshot = createFlowSnapshotEntity();
final FlowSnapshotEntityKey key = existingSnapshot.getId();
+ final String bucketId = existingSnapshot.getFlow().getBucket().getId();
- when(metadataService.getFlowSnapshot(key.getFlowId(), key.getVersion()))
+ when(metadataService.getFlowSnapshot(bucketId, key.getFlowId(), key.getVersion()))
.thenReturn(existingSnapshot);
- final VersionedFlowSnapshotMetadata deletedSnapshot = registryService.deleteFlowSnapshot(key.getFlowId(), key.getVersion());
+ final VersionedFlowSnapshotMetadata deletedSnapshot = registryService.deleteFlowSnapshot(bucketId, key.getFlowId(), key.getVersion());
assertNotNull(deletedSnapshot);
assertEquals(existingSnapshot.getId().getFlowId(), deletedSnapshot.getFlowIdentifier());
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-jetty/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-registry-jetty/pom.xml b/nifi-registry-jetty/pom.xml
index e47a354..8961ae1 100644
--- a/nifi-registry-jetty/pom.xml
+++ b/nifi-registry-jetty/pom.xml
@@ -30,11 +30,6 @@
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
- <groupId>org.apache.nifi.registry</groupId>
- <artifactId>nifi-registry-security</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- </dependency>
- <dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
----------------------------------------------------------------------
diff --git a/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
index 6aac4a6..b3ebf9d 100644
--- a/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
+++ b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/NiFiRegistryProperties.java
@@ -17,7 +17,11 @@
package org.apache.nifi.registry.properties;
import java.io.File;
+import java.util.Enumeration;
+import java.util.HashSet;
import java.util.Properties;
+import java.util.Set;
+
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,7 +47,11 @@ public class NiFiRegistryProperties extends Properties {
public static final String SECURITY_TRUSTSTORE_TYPE = "nifi.registry.security.truststoreType";
public static final String SECURITY_TRUSTSTORE_PASSWD = "nifi.registry.security.truststorePasswd";
public static final String SECURITY_NEED_CLIENT_AUTH = "nifi.registry.security.needClientAuth";
- public static final String SECURITY_AUTHORIZED_USERS = "nifi.registry.security.authorized.users";
+ public static final String SECURITY_AUTHORIZERS_CONFIGURATION_FILE = "nifi.registry.security.authorizers.configuration.file";
+ public static final String SECURITY_AUTHORIZER = "nifi.registry.security.authorizer";
+ public static final String SECURITY_IDENTITY_MAPPING_PATTERN_PREFIX = "nifi.registry.security.identity.mapping.pattern.";
+ public static final String SECURITY_IDENTITY_MAPPING_VALUE_PREFIX = "nifi.registry.security.identity.mapping.value.";
+
public static final String PROVIDERS_CONFIGURATION_FILE = "nifi.registry.providers.configuration.file";
@@ -54,6 +62,7 @@ public class NiFiRegistryProperties extends Properties {
public static final String DEFAULT_WEB_WORKING_DIR = "./work/jetty";
public static final String DEFAULT_WAR_DIR = "./lib";
public static final String DEFAULT_PROVIDERS_CONFIGURATION_FILE = "./conf/providers.xml";
+ public static final String DEFAULT_SECURITY_AUTHORIZERS_CONFIGURATION_FILE = "./conf/authorizers.xml";
public int getWebThreads() {
int webThreads = 200;
@@ -142,14 +151,6 @@ public class NiFiRegistryProperties extends Properties {
return new File(getProperty(WEB_WORKING_DIR, DEFAULT_WEB_WORKING_DIR));
}
- public File getAuthorizedUsersFile() {
- final String authorizedUsersFile = getProperty(SECURITY_AUTHORIZED_USERS);
- if (StringUtils.isBlank(authorizedUsersFile)) {
- return null;
- }
- return new File(authorizedUsersFile);
- }
-
public File getProvidersConfigurationFile() {
final String value = getProperty(PROVIDERS_CONFIGURATION_FILE);
if (StringUtils.isBlank(value)) {
@@ -167,4 +168,28 @@ public class NiFiRegistryProperties extends Properties {
return getProperty(DATABASE_URL_APPEND);
}
+
+ public File getAuthorizersConfigurationFile() {
+ final String value = getProperty(SECURITY_AUTHORIZERS_CONFIGURATION_FILE);
+ if (StringUtils.isBlank(value)) {
+ return new File(DEFAULT_SECURITY_AUTHORIZERS_CONFIGURATION_FILE);
+ } else {
+ return new File(value);
+ }
+ }
+
+ /**
+ * Retrieves all known property keys.
+ *
+ * @return all known property keys
+ */
+ public Set<String> getPropertyKeys() {
+ Set<String> propertyNames = new HashSet<>();
+ Enumeration e = this.propertyNames();
+ for (; e.hasMoreElements(); ){
+ propertyNames.add((String) e.nextElement());
+ }
+
+ return propertyNames;
+ }
}
http://git-wip-us.apache.org/repos/asf/nifi-registry/blob/785cb81f/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java
----------------------------------------------------------------------
diff --git a/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java
new file mode 100644
index 0000000..df3bbe6
--- /dev/null
+++ b/nifi-registry-properties/src/main/java/org/apache/nifi/registry/properties/util/IdentityMapping.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.registry.properties.util;
+
+import java.util.regex.Pattern;
+
+/**
+ * Holder to pass around the key, pattern, and replacement from an identity mapping in NiFiProperties.
+ */
+public class IdentityMapping {
+
+ private final String key;
+ private final Pattern pattern;
+ private final String replacementValue;
+
+ public IdentityMapping(String key, Pattern pattern, String replacementValue) {
+ this.key = key;
+ this.pattern = pattern;
+ this.replacementValue = replacementValue;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public Pattern getPattern() {
+ return pattern;
+ }
+
+ public String getReplacementValue() {
+ return replacementValue;
+ }
+
+}