This is an automated email from the ASF dual-hosted git repository. bbende pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nifi.git
commit a126d0a6b6ae0d59c6b1deee3ef5252cb6d3e33b Author: Tamas Palfy <[email protected]> AuthorDate: Thu Jun 11 14:28:06 2020 +0200 NIFI-7442 Added missing use cases (list users and user groups), made update-access-policy use case more in line with the NiFi side. Added some tests. Additional refactor, documentation revision. This closes #4329. --- nifi-docs/src/main/asciidoc/toolkit-guide.adoc | 2 +- .../java/org/apache/nifi/toolkit/cli/CLIMain.java | 2 +- .../client/JerseyExtendedNiFiRegistryClient.java | 45 ++- .../cli/impl/client/NiFiRegistryClientFactory.java | 6 +- .../cli/impl/client/registry/PoliciesClient.java | 35 +-- .../cli/impl/client/registry/TenantsClient.java | 62 ++-- .../registry/impl/AbstractCRUDJerseyClient.java | 91 ++++++ .../client/registry/impl/JerseyPoliciesClient.java | 52 ++-- .../client/registry/impl/JerseyTenantsClient.java | 89 ++---- .../toolkit/cli/impl/command/CommandOption.java | 1 - .../command/registry/NiFiRegistryCommandGroup.java | 12 +- .../policy/CreateOrUpdateAccessPolicy.java | 129 +++++++++ .../GetAccessPolicy.java} | 54 +--- .../{CreateUser.java => AbstractListTenants.java} | 40 +-- .../impl/command/registry/tenant/CreateUser.java | 2 +- .../command/registry/tenant/CreateUserGroup.java | 11 +- .../command/registry/tenant/ListUserGroups.java | 47 ++++ .../impl/command/registry/tenant/ListUsers.java | 47 ++++ .../impl/command/registry/tenant/TenantHelper.java | 74 +---- .../impl/command/registry/tenant/UpdatePolicy.java | 112 -------- .../impl/command/registry/tenant/UpdateUser.java | 16 +- .../command/registry/tenant/UpdateUserGroup.java | 24 +- .../impl/result/registry/AccessPolicyResult.java | 59 ++++ .../cli/impl/result/registry/UserGroupsResult.java | 82 ++++++ .../cli/impl/result/registry/UsersResult.java | 67 +++++ .../impl/command/registry/RegistryManualIT.java | 311 +++++++++++++++++++++ .../command/registry/tenant/TestTenantHelper.java | 153 ++++++++++ 27 files changed, 1170 insertions(+), 455 deletions(-) diff --git a/nifi-docs/src/main/asciidoc/toolkit-guide.adoc b/nifi-docs/src/main/asciidoc/toolkit-guide.adoc index 44df219..c112fbb 100644 --- a/nifi-docs/src/main/asciidoc/toolkit-guide.adoc +++ b/nifi-docs/src/main/asciidoc/toolkit-guide.adoc @@ -110,7 +110,7 @@ The following are available commands: registry update-user registry create-user-group registry update-user-group - registry create-policy + registry get-policy registry update-policy session keys session show diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/CLIMain.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/CLIMain.java index 200d6ea..cc6b8f4 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/CLIMain.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/CLIMain.java @@ -136,7 +136,7 @@ public class CLIMain { * * @param args the args passed in from the command line */ - private static int runSingleCommand(final String[] args) { + public static int runSingleCommand(final String[] args) { final Context context = createContext(System.out, false); final Map<String,Command> topLevelCommands = CommandFactory.createTopLevelCommands(context); final Map<String,CommandGroup> commandGroups = CommandFactory.createCommandGroups(context); diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/JerseyExtendedNiFiRegistryClient.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/JerseyExtendedNiFiRegistryClient.java index edf0300..589ac97 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/JerseyExtendedNiFiRegistryClient.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/JerseyExtendedNiFiRegistryClient.java @@ -69,17 +69,16 @@ public class JerseyExtendedNiFiRegistryClient implements ExtendedNiFiRegistryCli static final int DEFAULT_CONNECT_TIMEOUT = 10000; static final int DEFAULT_READ_TIMEOUT = 10000; - private final NiFiRegistryClient payload; + private final NiFiRegistryClient delegate; private final Client client; private final WebTarget baseTarget; private final TenantsClient tenantsClient; private final PoliciesClient policiesClient; - public JerseyExtendedNiFiRegistryClient(final NiFiRegistryClient payload, final NiFiRegistryClient.Builder builder) { - this.payload = payload; + public JerseyExtendedNiFiRegistryClient(final NiFiRegistryClient delegate, final NiFiRegistryClientConfig registryClientConfig) { + this.delegate = delegate; // Copied from JerseyNiFiRegistryClient! - final NiFiRegistryClientConfig registryClientConfig = builder.getConfig(); if (registryClientConfig == null) { throw new IllegalArgumentException("NiFiRegistryClientConfig cannot be null"); } @@ -158,97 +157,97 @@ public class JerseyExtendedNiFiRegistryClient implements ExtendedNiFiRegistryCli @Override public BucketClient getBucketClient() { - return payload.getBucketClient(); + return delegate.getBucketClient(); } @Override public BucketClient getBucketClient(final String... proxiedEntity) { - return payload.getBucketClient(proxiedEntity); + return delegate.getBucketClient(proxiedEntity); } @Override public FlowClient getFlowClient() { - return payload.getFlowClient(); + return delegate.getFlowClient(); } @Override public FlowClient getFlowClient(final String... proxiedEntity) { - return payload.getFlowClient(proxiedEntity); + return delegate.getFlowClient(proxiedEntity); } @Override public FlowSnapshotClient getFlowSnapshotClient() { - return payload.getFlowSnapshotClient(); + return delegate.getFlowSnapshotClient(); } @Override public FlowSnapshotClient getFlowSnapshotClient(final String... proxiedEntity) { - return payload.getFlowSnapshotClient(proxiedEntity); + return delegate.getFlowSnapshotClient(proxiedEntity); } @Override public ItemsClient getItemsClient() { - return payload.getItemsClient(); + return delegate.getItemsClient(); } @Override public ItemsClient getItemsClient(final String... proxiedEntity) { - return payload.getItemsClient(proxiedEntity); + return delegate.getItemsClient(proxiedEntity); } @Override public UserClient getUserClient() { - return payload.getUserClient(); + return delegate.getUserClient(); } @Override public UserClient getUserClient(final String... proxiedEntity) { - return payload.getUserClient(proxiedEntity); + return delegate.getUserClient(proxiedEntity); } @Override public BundleClient getBundleClient() { - return payload.getBundleClient(); + return delegate.getBundleClient(); } @Override public BundleClient getBundleClient(final String... proxiedEntity) { - return payload.getBundleClient(proxiedEntity); + return delegate.getBundleClient(proxiedEntity); } @Override public BundleVersionClient getBundleVersionClient() { - return payload.getBundleVersionClient(); + return delegate.getBundleVersionClient(); } @Override public BundleVersionClient getBundleVersionClient(final String... proxiedEntity) { - return payload.getBundleVersionClient(proxiedEntity); + return delegate.getBundleVersionClient(proxiedEntity); } @Override public ExtensionRepoClient getExtensionRepoClient() { - return payload.getExtensionRepoClient(); + return delegate.getExtensionRepoClient(); } @Override public ExtensionRepoClient getExtensionRepoClient(final String... proxiedEntity) { - return payload.getExtensionRepoClient(proxiedEntity); + return delegate.getExtensionRepoClient(proxiedEntity); } @Override public ExtensionClient getExtensionClient() { - return payload.getExtensionClient(); + return delegate.getExtensionClient(); } @Override public ExtensionClient getExtensionClient(final String... proxiedEntity) { - return payload.getExtensionClient(proxiedEntity); + return delegate.getExtensionClient(proxiedEntity); } @Override public void close() throws IOException { - payload.close(); + delegate.close(); if (this.client != null) { try { diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/NiFiRegistryClientFactory.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/NiFiRegistryClientFactory.java index cbdfd36..a2acbd0 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/NiFiRegistryClientFactory.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/NiFiRegistryClientFactory.java @@ -99,9 +99,9 @@ public class NiFiRegistryClientFactory implements ClientFactory<NiFiRegistryClie } } - final NiFiRegistryClientConfig builder = clientConfigBuilder.build(); - final NiFiRegistryClient client = new JerseyNiFiRegistryClient.Builder().config(builder).build(); - final ExtendedNiFiRegistryClient extendedClient = new JerseyExtendedNiFiRegistryClient(client, new JerseyNiFiRegistryClient.Builder().config(builder)); + final NiFiRegistryClientConfig clientConfig = clientConfigBuilder.build(); + final NiFiRegistryClient client = new JerseyNiFiRegistryClient.Builder().config(clientConfig).build(); + final ExtendedNiFiRegistryClient extendedClient = new JerseyExtendedNiFiRegistryClient(client, clientConfig); // if a proxied entity was specified then return a wrapped client, otherwise return the regular client if (!StringUtils.isBlank(proxiedEntity)) { diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/PoliciesClient.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/PoliciesClient.java index be481a8..fe614f5 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/PoliciesClient.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/PoliciesClient.java @@ -22,43 +22,44 @@ import org.apache.nifi.registry.client.NiFiRegistryException; import java.io.IOException; /** - * Provides API for the services might be called from registry related to access policies. + * Provides API for access policies related services available in NiFi Registry. */ public interface PoliciesClient { /** - * Returns with a given access policy. + * Returns a given access policy. * - * @param id The identifier of the access policy. + * @param resource The action allowed by the access policy. + * @param action The resource managed by the access policy. * * @return The access policy. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ - AccessPolicy getPolicy(String id) throws NiFiRegistryException, IOException; + AccessPolicy getAccessPolicy(String action, String resource) throws NiFiRegistryException, IOException; /** - * Creates a new access policy within the registry. + * Creates a new access policy. * - * @param policy The attributes of the access policy. Note: identifier will be ignored and generated. + * @param policy The access policy to be created. Note: identifier will be ignored and assigned by NiFi Registry. * - * @return The access policy after store, containing it's identifier. + * @return The created access with an assigned identifier. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ - AccessPolicy createPolicy(AccessPolicy policy) throws NiFiRegistryException, IOException; + AccessPolicy createAccessPolicy(AccessPolicy policy) throws NiFiRegistryException, IOException; /** * Updates an existing access policy. * - * @param policy The updated attributes of the access policy. + * @param policy The access policy with new attributes. * - * @return The stored access policy. + * @return The updated access policy. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ - AccessPolicy updatePolicy(AccessPolicy policy) throws NiFiRegistryException, IOException; + AccessPolicy updateAccessPolicy(AccessPolicy policy) throws NiFiRegistryException, IOException; } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/TenantsClient.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/TenantsClient.java index 5ad56f8..ab4c17b 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/TenantsClient.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/TenantsClient.java @@ -24,41 +24,41 @@ import java.io.IOException; import java.util.List; /** - * Provides API for the services might be called from registry related to tenants. + * Provides API for tenant (user/group) related services available in NiFi Registry. */ public interface TenantsClient { /** - * Returns all the users. + * Returns all users. * - * @return The list of users in the registry. + * @return The list of users. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ List<User> getUsers() throws NiFiRegistryException, IOException; /** - * Returns a given user based on id. + * Returns a user with a given identifier. * * @param id Identifier of the user. * * @return The user. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ User getUser(String id) throws NiFiRegistryException, IOException; /** - * Creates a new user in the registry. + * Creates a new user in NiFi Registry. * - * @param user The new user. Note: identifier will be ignored and generated. + * @param user The new user. Note: identifier will be ignored and assigned be NiFi Registry. * - * @return The user after store, containing it's identifier. + * @return The created user with an assigned identifier. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ User createUser(User user) throws NiFiRegistryException, IOException; @@ -67,56 +67,56 @@ public interface TenantsClient { * * @param user The user with the new attributes. * - * @return The user after store. + * @return The updated user. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ User updateUser(User user) throws NiFiRegistryException, IOException; /** - * Returns all the user groups. + * Returns all user groups. * * @return The list of user groups. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ List<UserGroup> getUserGroups() throws NiFiRegistryException, IOException; /** - * Returns the given user group based on identifier. + * Returns a user group with a given identifier. * - * @param id The user group's identifier. + * @param id Identifier of the user group. * * @return The user group. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ UserGroup getUserGroup(String id) throws NiFiRegistryException, IOException; /** - * Creates a new user group in the registry. + * Creates a new user group. * - * @param group The user group to store. Note: identifier will be ignored and generated. + * @param group The user group to be created. Note: identifier will be ignored and assigned by NiFi Registry. * - * @return The stored user group, containing id. + * @return The created user group with an assigned identifier. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry.@throws IOException + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ UserGroup createUserGroup(UserGroup group) throws NiFiRegistryException, IOException; /** * Updates an existing user group. * - * @param group The user group with the new attributes. + * @param group The user group with new attributes. * * @return The user group after store. * - * @throws NiFiRegistryException Thrown in case os unsuccessful execution. - * @throws IOException Thrown when there is an issue with communicating the registry. + * @throws NiFiRegistryException Thrown in case of unsuccessful execution. + * @throws IOException Thrown when there is an issue while communicating with NiFi Registry. */ UserGroup updateUserGroup(UserGroup group) throws NiFiRegistryException, IOException; } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/AbstractCRUDJerseyClient.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/AbstractCRUDJerseyClient.java new file mode 100644 index 0000000..4aef09b --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/AbstractCRUDJerseyClient.java @@ -0,0 +1,91 @@ +/* + * 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.toolkit.cli.impl.client.registry.impl; + +import org.apache.nifi.registry.client.NiFiRegistryException; +import org.apache.nifi.registry.client.impl.AbstractJerseyClient; +import org.apache.nifi.util.StringUtils; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.util.Map; + +public class AbstractCRUDJerseyClient extends AbstractJerseyClient { + protected final WebTarget baseTarget; + + public AbstractCRUDJerseyClient(final WebTarget baseTarget, final Map<String, String> headers) { + super(headers); + this.baseTarget = baseTarget; + } + + protected <T> T get( + String id, + Class<T> entityType, + String entityTypeName, + String entityPath + ) throws NiFiRegistryException, IOException { + if (StringUtils.isBlank(id)) { + throw new IllegalArgumentException(entityTypeName + " id cannot be blank"); + } + + return executeAction("Error retrieving " + entityTypeName.toLowerCase(), () -> { + final WebTarget target = baseTarget.path(entityPath).path(id); + return getRequestBuilder(target).get(entityType); + }); + } + + protected <T> T create( + T entity, + Class<T> entityType, + String entityTypeName, + String entityPath + ) throws NiFiRegistryException, IOException { + if (entity == null) { + throw new IllegalArgumentException(entityTypeName + " cannot be null"); + } + + return executeAction("Error creating " + entityTypeName.toLowerCase(), () -> { + final WebTarget target = baseTarget.path(entityPath); + + return getRequestBuilder(target).post( + Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), entityType + ); + }); + } + + protected <T> T update( + T entity, + String id, + Class<T> entityType, + String entityTypeName, + String entityPath + ) throws NiFiRegistryException, IOException { + if (entity == null) { + throw new IllegalArgumentException(entityTypeName + " cannot be null"); + } + + return executeAction("Error updating " + entityTypeName.toLowerCase(), () -> { + final WebTarget target = baseTarget.path(entityPath).path(id); + + return getRequestBuilder(target).put( + Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE), entityType + ); + }); + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyPoliciesClient.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyPoliciesClient.java index ee7a806..282234a 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyPoliciesClient.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyPoliciesClient.java @@ -16,67 +16,47 @@ */ package org.apache.nifi.toolkit.cli.impl.client.registry.impl; +import org.apache.commons.lang3.StringUtils; import org.apache.nifi.registry.authorization.AccessPolicy; import org.apache.nifi.registry.client.NiFiRegistryException; -import org.apache.nifi.registry.client.impl.AbstractJerseyClient; import org.apache.nifi.toolkit.cli.impl.client.registry.PoliciesClient; -import org.apache.nifi.util.StringUtils; -import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; import java.io.IOException; import java.util.Collections; import java.util.Map; -public class JerseyPoliciesClient extends AbstractJerseyClient implements PoliciesClient { - private final WebTarget policiesTarget; - - public JerseyPoliciesClient(final WebTarget baseTarget, final Map<String, String> headers) { - super(headers); - this.policiesTarget = baseTarget.path("/policies"); - } +public class JerseyPoliciesClient extends AbstractCRUDJerseyClient implements PoliciesClient { + public static final String ACCESS_POLICY = "Access policy"; + public static final String POLICIES_PATH = "policies"; public JerseyPoliciesClient(final WebTarget baseTarget) { this(baseTarget, Collections.emptyMap()); } + public JerseyPoliciesClient(final WebTarget baseTarget, final Map<String, String> headers) { + super(baseTarget, headers); + } + @Override - public AccessPolicy getPolicy(final String id) throws NiFiRegistryException, IOException { - if (StringUtils.isBlank(id)) { - throw new IllegalArgumentException("Access policy id cannot be null"); + public AccessPolicy getAccessPolicy(String action, String resource) throws NiFiRegistryException, IOException { + if (StringUtils.isBlank(resource) || StringUtils.isBlank(action)) { + throw new IllegalArgumentException("Resource and action cannot be null"); } return executeAction("Error retrieving access policy", () -> { - final WebTarget target = policiesTarget.path("{id}").resolveTemplate("id", id); + final WebTarget target = baseTarget.path(POLICIES_PATH).path(action).path(resource); return getRequestBuilder(target).get(AccessPolicy.class); }); } @Override - public AccessPolicy createPolicy(final AccessPolicy policy) throws NiFiRegistryException, IOException { - if (policy == null) { - throw new IllegalArgumentException("Access policy cannot be null"); - } - - return executeAction("Error creating access policy", () -> { - return getRequestBuilder(policiesTarget).post( - Entity.entity(policy, MediaType.APPLICATION_JSON_TYPE), AccessPolicy.class - ); - }); + public AccessPolicy createAccessPolicy(final AccessPolicy policy) throws NiFiRegistryException, IOException { + return create(policy, AccessPolicy.class, ACCESS_POLICY, POLICIES_PATH); } @Override - public AccessPolicy updatePolicy(final AccessPolicy policy) throws NiFiRegistryException, IOException { - if (policy == null) { - throw new IllegalArgumentException("Access policy cannot be null"); - } - - return executeAction("Error creating access policy", () -> { - final WebTarget target = policiesTarget.path("{id}").resolveTemplate("id", policy.getIdentifier()); - return getRequestBuilder(target).put( - Entity.entity(policy, MediaType.APPLICATION_JSON_TYPE), AccessPolicy.class - ); - }); + public AccessPolicy updateAccessPolicy(final AccessPolicy policy) throws NiFiRegistryException, IOException { + return update(policy, policy.getIdentifier(), AccessPolicy.class, ACCESS_POLICY, POLICIES_PATH); } } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyTenantsClient.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyTenantsClient.java index a135702..d59d8f8 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyTenantsClient.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/client/registry/impl/JerseyTenantsClient.java @@ -19,128 +19,73 @@ package org.apache.nifi.toolkit.cli.impl.client.registry.impl; import org.apache.nifi.registry.authorization.User; import org.apache.nifi.registry.authorization.UserGroup; import org.apache.nifi.registry.client.NiFiRegistryException; -import org.apache.nifi.registry.client.impl.AbstractJerseyClient; import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; -import org.apache.nifi.util.StringUtils; -import javax.ws.rs.client.Entity; import javax.ws.rs.client.WebTarget; -import javax.ws.rs.core.MediaType; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -public class JerseyTenantsClient extends AbstractJerseyClient implements TenantsClient { - private final WebTarget tenantsTarget; +public class JerseyTenantsClient extends AbstractCRUDJerseyClient implements TenantsClient { + public static final String USER = "User"; + public static final String USERS_PATH = "users"; - public JerseyTenantsClient(final WebTarget baseTarget, final Map<String, String> headers) { - super(headers); - this.tenantsTarget = baseTarget.path("/tenants"); - } + public static final String USER_GROUP = "User group"; + public static final String USER_GROUPS_PATH = "user-groups"; public JerseyTenantsClient(final WebTarget baseTarget) { this(baseTarget, Collections.emptyMap()); } + public JerseyTenantsClient(final WebTarget baseTarget, final Map<String, String> headers) { + super(baseTarget.path("/tenants"), headers); + } + @Override public List<User> getUsers() throws NiFiRegistryException, IOException { return executeAction("Error retrieving users", () -> { - final WebTarget target = tenantsTarget.path("users"); + final WebTarget target = baseTarget.path(USERS_PATH); return Arrays.asList(getRequestBuilder(target).get(User[].class)); }); } @Override public User getUser(final String id) throws NiFiRegistryException, IOException { - if (StringUtils.isBlank(id)) { - throw new IllegalArgumentException("User id cannot be null"); - } - - return executeAction("Error retrieving user", () -> { - final WebTarget target = tenantsTarget.path("users/{id}").resolveTemplate("id", id); - return getRequestBuilder(target).get(User.class); - }); + return get(id, User.class, USER, USERS_PATH); } @Override public User createUser(final User user) throws NiFiRegistryException, IOException { - if (user == null) { - throw new IllegalArgumentException("User cannot be null"); - } - - return executeAction("Error creating user", () -> { - final WebTarget target = tenantsTarget.path("users"); - - return getRequestBuilder(target).post( - Entity.entity(user, MediaType.APPLICATION_JSON_TYPE), User.class - ); - }); + return create(user, User.class, USER, USERS_PATH); } @Override public User updateUser(final User user) throws NiFiRegistryException, IOException { - if (user == null) { - throw new IllegalArgumentException("User cannot be null"); - } - - return executeAction("Error updating user", () -> { - final WebTarget target = tenantsTarget.path("users/{id}").resolveTemplate("id", user.getIdentifier()); - - return getRequestBuilder(target).put( - Entity.entity(user, MediaType.APPLICATION_JSON_TYPE), User.class - ); - }); + return update(user, user.getIdentifier(), User.class, USER, USERS_PATH); } @Override public List<UserGroup> getUserGroups() throws NiFiRegistryException, IOException { return executeAction("Error retrieving users", () -> { - final WebTarget target = tenantsTarget.path("user-groups"); + final WebTarget target = baseTarget.path(USER_GROUPS_PATH); return Arrays.asList(getRequestBuilder(target).get(UserGroup[].class)); }); } @Override public UserGroup getUserGroup(final String id) throws NiFiRegistryException, IOException { - if (StringUtils.isBlank(id)) { - throw new IllegalArgumentException("User group id cannot be null"); - } - - return executeAction("Error retrieving user group", () -> { - final WebTarget target = tenantsTarget.path("user-groups/{id}").resolveTemplate("id", id); - return getRequestBuilder(target).get(UserGroup.class); - }); + return get(id, UserGroup.class, USER_GROUP, USER_GROUPS_PATH); } @Override public UserGroup createUserGroup(final UserGroup group) throws NiFiRegistryException, IOException { - if (group == null) { - throw new IllegalArgumentException("User group cannot be null"); - } - - return executeAction("Error creating group", () -> { - final WebTarget target = tenantsTarget.path("user-groups"); - - return getRequestBuilder(target).post( - Entity.entity(group, MediaType.APPLICATION_JSON_TYPE), UserGroup.class - ); - }); + return create(group, UserGroup.class, USER_GROUP, USER_GROUPS_PATH); } @Override public UserGroup updateUserGroup(final UserGroup group) throws NiFiRegistryException, IOException { - if (group == null) { - throw new IllegalArgumentException("User group cannot be null"); - } - - return executeAction("Error creating group", () -> { - final WebTarget target = tenantsTarget.path("user-groups/{id}").resolveTemplate("id", group.getIdentifier()); - - return getRequestBuilder(target).put( - Entity.entity(group, MediaType.APPLICATION_JSON_TYPE), UserGroup.class - ); - }); + return update(group, group.getIdentifier(), UserGroup.class, USER_GROUP, USER_GROUPS_PATH); } } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java index eb5b28d..2af6dbf 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/CommandOption.java @@ -102,7 +102,6 @@ public enum CommandOption { GROUP_ID_LIST("gil", "groupIdList", "The comma-separated user group id list", true), // NiFi - Access Policies - POLICY_ID("pi", "accessPolicyIdentifier", "The identifier of an access policy", true), POLICY_RESOURCE("por", "accessPolicyResource", "The resource of an access policy", true), POLICY_ACTION("poa", "accessPolicyAction", "The action of an access policy (read or write)", true), OVERWRITE_POLICY("owp", "overwritePolicy", "Overwrite the user list and group list for the access policy", false), diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java index 8b9c93f..5580c16 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/NiFiRegistryCommandGroup.java @@ -39,10 +39,12 @@ import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ListFlowVersions; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.ListFlows; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.SyncFlowVersions; import org.apache.nifi.toolkit.cli.impl.command.registry.flow.TransferFlowVersion; -import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.CreatePolicy; +import org.apache.nifi.toolkit.cli.impl.command.registry.policy.GetAccessPolicy; import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.CreateUser; import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.CreateUserGroup; -import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.UpdatePolicy; +import org.apache.nifi.toolkit.cli.impl.command.registry.policy.CreateOrUpdateAccessPolicy; +import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.ListUserGroups; +import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.ListUsers; import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.UpdateUser; import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.UpdateUserGroup; import org.apache.nifi.toolkit.cli.impl.command.registry.user.CurrentUser; @@ -86,12 +88,14 @@ public class NiFiRegistryCommandGroup extends AbstractCommandGroup { commandList.add(new GetBundleChecksum()); commandList.add(new ListExtensionTags()); commandList.add(new ListExtensions()); + commandList.add(new ListUsers()); commandList.add(new CreateUser()); commandList.add(new UpdateUser()); + commandList.add(new ListUserGroups()); commandList.add(new CreateUserGroup()); commandList.add(new UpdateUserGroup()); - commandList.add(new CreatePolicy()); - commandList.add(new UpdatePolicy()); + commandList.add(new GetAccessPolicy()); + commandList.add(new CreateOrUpdateAccessPolicy()); return new ArrayList<>(commandList); } } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/policy/CreateOrUpdateAccessPolicy.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/policy/CreateOrUpdateAccessPolicy.java new file mode 100644 index 0000000..9a4f977 --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/policy/CreateOrUpdateAccessPolicy.java @@ -0,0 +1,129 @@ +/* + * 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.toolkit.cli.impl.command.registry.policy; + +import org.apache.commons.cli.ParseException; +import org.apache.commons.lang3.StringUtils; +import org.apache.nifi.registry.authorization.AccessPolicy; +import org.apache.nifi.registry.authorization.Tenant; +import org.apache.nifi.registry.client.NiFiRegistryClient; +import org.apache.nifi.registry.client.NiFiRegistryException; +import org.apache.nifi.toolkit.cli.api.Context; +import org.apache.nifi.toolkit.cli.impl.client.ExtendedNiFiRegistryClient; +import org.apache.nifi.toolkit.cli.impl.client.registry.PoliciesClient; +import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; +import org.apache.nifi.toolkit.cli.impl.command.CommandOption; +import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand; +import org.apache.nifi.toolkit.cli.impl.command.registry.tenant.TenantHelper; +import org.apache.nifi.toolkit.cli.impl.result.VoidResult; + +import java.io.IOException; +import java.util.Properties; +import java.util.Set; + +/** + * Command for creating a new or updating an existing policy. + */ +public class CreateOrUpdateAccessPolicy extends AbstractNiFiRegistryCommand<VoidResult> { + + public CreateOrUpdateAccessPolicy() { + super("update-policy", VoidResult.class); + } + + @Override + public String getDescription() { + return "Updates the access policy for the given resource and action, or creates the policy " + + "if it doesn't exist. In stand-alone mode this command will not produce all of " + + "the output seen in interactive mode unless the --verbose argument is specified."; + } + + @Override + protected void doInitialize(final Context context) { + // Required + addOption(CommandOption.POLICY_RESOURCE.createOption()); + addOption(CommandOption.POLICY_ACTION.createOption()); + + // Optional + addOption(CommandOption.USER_NAME_LIST.createOption()); + addOption(CommandOption.USER_ID_LIST.createOption()); + addOption(CommandOption.GROUP_NAME_LIST.createOption()); + addOption(CommandOption.GROUP_ID_LIST.createOption()); + addOption(CommandOption.OVERWRITE_POLICY.createOption()); + } + + @Override + public VoidResult doExecute(final NiFiRegistryClient client, final Properties properties) throws IOException, NiFiRegistryException, ParseException { + if (!(client instanceof ExtendedNiFiRegistryClient)) { + throw new IllegalArgumentException("This command needs extended registry client!"); + } + final ExtendedNiFiRegistryClient extendedClient = (ExtendedNiFiRegistryClient) client; + + final PoliciesClient policiesClient = extendedClient.getPoliciesClient(); + final TenantsClient tenantsClient = extendedClient.getTenantsClient(); + + final String action = getRequiredArg(properties, CommandOption.POLICY_ACTION); + final String resource = getRequiredArg(properties, CommandOption.POLICY_RESOURCE); + + AccessPolicy currentPolicy; + try { + currentPolicy = policiesClient.getAccessPolicy(action, resource); + } catch (NiFiRegistryException e) { + currentPolicy = null; + } + + if (currentPolicy == null) { + currentPolicy = new AccessPolicy(); + + currentPolicy.setAction(action); + currentPolicy.setResource(resource); + + setUsers(currentPolicy, properties, tenantsClient); + setGroups(currentPolicy, properties, tenantsClient); + + policiesClient.createAccessPolicy(currentPolicy); + } else { + setUsers(currentPolicy, properties, tenantsClient); + setGroups(currentPolicy, properties, tenantsClient); + + policiesClient.updateAccessPolicy(currentPolicy); + } + + return VoidResult.getInstance(); + } + + private void setUsers(AccessPolicy accessPolicy, Properties properties, TenantsClient tenantsClient) throws IOException, NiFiRegistryException { + String userNames = getArg(properties, CommandOption.USER_NAME_LIST); + String userIds = getArg(properties, CommandOption.USER_ID_LIST); + + if (StringUtils.isNotBlank(userNames) || StringUtils.isNotBlank(userIds)) { + Set<Tenant> existingUsers = TenantHelper.selectExistingTenants(userNames, userIds, tenantsClient.getUsers()); + + accessPolicy.setUsers(existingUsers); + } + } + + private void setGroups(AccessPolicy accessPolicy, Properties properties, TenantsClient tenantsClient) throws IOException, NiFiRegistryException { + String groupNames = getArg(properties, CommandOption.GROUP_NAME_LIST); + String groupIds = getArg(properties, CommandOption.GROUP_ID_LIST); + + if (StringUtils.isNotBlank(groupNames) || StringUtils.isNotBlank(groupIds)) { + Set<Tenant> existingGroups = TenantHelper.selectExistingTenants(groupNames, groupIds, tenantsClient.getUserGroups()); + + accessPolicy.setUserGroups(existingGroups); + } + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreatePolicy.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/policy/GetAccessPolicy.java similarity index 54% rename from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreatePolicy.java rename to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/policy/GetAccessPolicy.java index 5ab45aa..278e540 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreatePolicy.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/policy/GetAccessPolicy.java @@ -14,84 +14,56 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.apache.nifi.toolkit.cli.impl.command.registry.tenant; +package org.apache.nifi.toolkit.cli.impl.command.registry.policy; import org.apache.commons.cli.ParseException; import org.apache.nifi.registry.authorization.AccessPolicy; -import org.apache.nifi.registry.authorization.Tenant; import org.apache.nifi.registry.client.NiFiRegistryClient; import org.apache.nifi.registry.client.NiFiRegistryException; import org.apache.nifi.toolkit.cli.api.Context; import org.apache.nifi.toolkit.cli.impl.client.ExtendedNiFiRegistryClient; import org.apache.nifi.toolkit.cli.impl.client.registry.PoliciesClient; -import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; import org.apache.nifi.toolkit.cli.impl.command.CommandOption; import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand; -import org.apache.nifi.toolkit.cli.impl.result.StringResult; +import org.apache.nifi.toolkit.cli.impl.result.registry.AccessPolicyResult; import java.io.IOException; import java.util.Properties; -import java.util.Set; /** - * Command for creating an access policy. + * Command to get the configuration of an access policy. */ -public class CreatePolicy extends AbstractNiFiRegistryCommand<StringResult> { - - public CreatePolicy() { - super("create-policy", StringResult.class); +public class GetAccessPolicy extends AbstractNiFiRegistryCommand<AccessPolicyResult> { + public GetAccessPolicy() { + super("get-policy", AccessPolicyResult.class); } @Override public String getDescription() { - return "Creates new access policy"; + return "Retrieves the configuration for an access policy."; } @Override protected void doInitialize(final Context context) { - // Required addOption(CommandOption.POLICY_RESOURCE.createOption()); addOption(CommandOption.POLICY_ACTION.createOption()); - - // Optional - addOption(CommandOption.USER_NAME_LIST.createOption()); - addOption(CommandOption.USER_ID_LIST.createOption()); - addOption(CommandOption.GROUP_NAME_LIST.createOption()); - addOption(CommandOption.GROUP_ID_LIST.createOption()); } @Override - public StringResult doExecute(final NiFiRegistryClient client, final Properties properties) - throws IOException, NiFiRegistryException, ParseException { - + public AccessPolicyResult doExecute(final NiFiRegistryClient client, final Properties properties) throws IOException, NiFiRegistryException, ParseException { if (!(client instanceof ExtendedNiFiRegistryClient)) { throw new IllegalArgumentException("This command needs extended registry client!"); } - final ExtendedNiFiRegistryClient extendedClient = (ExtendedNiFiRegistryClient) client; + final PoliciesClient policiesClient = extendedClient.getPoliciesClient(); - final TenantsClient tenantsClient = extendedClient.getTenantsClient(); - final String resource = getRequiredArg(properties, CommandOption.POLICY_RESOURCE); final String action = getRequiredArg(properties, CommandOption.POLICY_ACTION); + final String resource = getRequiredArg(properties, CommandOption.POLICY_RESOURCE); - final Set<Tenant> users = TenantHelper.getExistingUsers( - tenantsClient, - getArg(properties, CommandOption.USER_NAME_LIST), - getArg(properties, CommandOption.USER_ID_LIST)); - - final Set<Tenant> userGroups = TenantHelper.getExistingGroups( - tenantsClient, - getArg(properties, CommandOption.GROUP_NAME_LIST), - getArg(properties, CommandOption.GROUP_ID_LIST)); - - final AccessPolicy policy = new AccessPolicy(); - policy.setAction(action); - policy.setResource(resource); - policy.setUsers(users); - policy.setUserGroups(userGroups); + final AccessPolicy accessPolicy = policiesClient.getAccessPolicy(action, resource); - final AccessPolicy createdPolicy = policiesClient.createPolicy(policy); - return new StringResult(createdPolicy.getIdentifier(), getContext().isInteractive()); + return new AccessPolicyResult(getResultType(properties), accessPolicy); } + } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/AbstractListTenants.java similarity index 60% copy from nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java copy to nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/AbstractListTenants.java index baf61f0..58b631f 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/AbstractListTenants.java @@ -17,41 +17,31 @@ package org.apache.nifi.toolkit.cli.impl.command.registry.tenant; import org.apache.commons.cli.ParseException; -import org.apache.nifi.registry.authorization.User; +import org.apache.nifi.registry.authorization.Tenant; import org.apache.nifi.registry.client.NiFiRegistryClient; import org.apache.nifi.registry.client.NiFiRegistryException; -import org.apache.nifi.toolkit.cli.api.Context; +import org.apache.nifi.toolkit.cli.api.Result; import org.apache.nifi.toolkit.cli.impl.client.ExtendedNiFiRegistryClient; import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; -import org.apache.nifi.toolkit.cli.impl.command.CommandOption; import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand; -import org.apache.nifi.toolkit.cli.impl.result.StringResult; import java.io.IOException; import java.util.Properties; /** - * Command for creating a user. + * Abstract command to get the list of tenants of a specific type. + * + * @param <T> The type of tenants in the result. + * @param <R> The type of the result object. */ -public class CreateUser extends AbstractNiFiRegistryCommand<StringResult> { - - public CreateUser() { - super("create-user", StringResult.class); - } - - @Override - public String getDescription() { - return "Creates new user."; +public abstract class AbstractListTenants<T extends Tenant, R extends Result> extends AbstractNiFiRegistryCommand<R> { + public AbstractListTenants(String name, Class<R> resultClass) { + super(name, resultClass); } @Override - protected void doInitialize(final Context context) { - addOption(CommandOption.USER_NAME.createOption()); - } - - @Override - public StringResult doExecute(final NiFiRegistryClient client, final Properties properties) - throws IOException, NiFiRegistryException, ParseException { + public R doExecute(final NiFiRegistryClient client, final Properties properties) + throws IOException, NiFiRegistryException, ParseException { if (!(client instanceof ExtendedNiFiRegistryClient)) { throw new IllegalArgumentException("This command needs extended registry client!"); @@ -60,10 +50,8 @@ public class CreateUser extends AbstractNiFiRegistryCommand<StringResult> { final ExtendedNiFiRegistryClient extendedClient = (ExtendedNiFiRegistryClient) client; final TenantsClient tenantsClient = extendedClient.getTenantsClient(); - final String userName = getRequiredArg(properties, CommandOption.USER_NAME); - final User user = new User(null, userName); - final User createdUser = tenantsClient.createUser(user); - - return new StringResult(createdUser.getIdentifier(), getContext().isInteractive()); + return getTenants(properties, tenantsClient); } + + protected abstract R getTenants(Properties properties, TenantsClient tenantsClient) throws NiFiRegistryException, IOException; } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java index baf61f0..21ac38a 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUser.java @@ -41,7 +41,7 @@ public class CreateUser extends AbstractNiFiRegistryCommand<StringResult> { @Override public String getDescription() { - return "Creates new user."; + return "Creates a new user."; } @Override diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUserGroup.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUserGroup.java index fced142..212ba72 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUserGroup.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/CreateUserGroup.java @@ -69,13 +69,14 @@ public class CreateUserGroup extends AbstractNiFiRegistryCommand<StringResult> { final String groupName = getRequiredArg(properties, CommandOption.UG_NAME); - final Set<Tenant> tenants = TenantHelper.getExistingUsers( - tenantsClient, - getArg(properties, CommandOption.USER_NAME_LIST), - getArg(properties, CommandOption.USER_ID_LIST)); + Set<Tenant> users = TenantHelper.selectExistingTenants( + getArg(properties, CommandOption.USER_NAME_LIST), + getArg(properties, CommandOption.USER_ID_LIST), + tenantsClient.getUsers() + ); final UserGroup group = new UserGroup(null, groupName); - group.setUsers(tenants); + group.setUsers(users); final UserGroup createdGroup = tenantsClient.createUserGroup(group); return new StringResult(createdGroup.getIdentifier(), getContext().isInteractive()); diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/ListUserGroups.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/ListUserGroups.java new file mode 100644 index 0000000..c8dd38e --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/ListUserGroups.java @@ -0,0 +1,47 @@ +/* + * 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.toolkit.cli.impl.command.registry.tenant; + +import org.apache.nifi.registry.authorization.UserGroup; +import org.apache.nifi.registry.client.NiFiRegistryException; +import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; +import org.apache.nifi.toolkit.cli.impl.result.registry.UserGroupsResult; + +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +/** + * Command to get the list of user groups. + */ +public class ListUserGroups extends AbstractListTenants<UserGroup, UserGroupsResult> { + public ListUserGroups() { + super("list-user-groups", UserGroupsResult.class); + } + + @Override + public String getDescription() { + return "Retrieves the list of user group."; + } + + @Override + protected UserGroupsResult getTenants(Properties properties, TenantsClient tenantsClient) throws NiFiRegistryException, IOException { + List<UserGroup> userGroups = tenantsClient.getUserGroups(); + + return new UserGroupsResult(getResultType(properties), userGroups); + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/ListUsers.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/ListUsers.java new file mode 100644 index 0000000..52877ab --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/ListUsers.java @@ -0,0 +1,47 @@ +/* + * 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.toolkit.cli.impl.command.registry.tenant; + +import org.apache.nifi.registry.authorization.User; +import org.apache.nifi.registry.client.NiFiRegistryException; +import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; +import org.apache.nifi.toolkit.cli.impl.result.registry.UsersResult; + +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +/** + * Command to get the list of users. + */ +public class ListUsers extends AbstractListTenants<User, UsersResult> { + public ListUsers() { + super("list-users", UsersResult.class); + } + + @Override + public String getDescription() { + return "Retrieves the list of user."; + } + + @Override + protected UsersResult getTenants(Properties properties, TenantsClient tenantsClient) throws NiFiRegistryException, IOException { + List<User> users = tenantsClient.getUsers(); + + return new UsersResult(getResultType(properties), users); + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TenantHelper.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TenantHelper.java index 64415f9..97a2df1 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TenantHelper.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TenantHelper.java @@ -16,78 +16,28 @@ */ package org.apache.nifi.toolkit.cli.impl.command.registry.tenant; -import org.apache.commons.lang3.StringUtils; import org.apache.nifi.registry.authorization.Tenant; -import org.apache.nifi.registry.authorization.User; -import org.apache.nifi.registry.authorization.UserGroup; -import org.apache.nifi.registry.client.NiFiRegistryException; -import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; -import java.io.IOException; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; +import java.util.stream.Collectors; -final class TenantHelper { - private static final String SEPARATOR = ","; +public final class TenantHelper { + private TenantHelper() {} - private TenantHelper() { - // no op - } - - public static Set<Tenant> getExistingUsers(final TenantsClient client, final String userNamesArgument, final String userIdsArgument) - throws IOException, NiFiRegistryException { - final Set<Tenant> result = new HashSet<>(); - - final Set<String> userNames = StringUtils.isNotBlank(userNamesArgument) - ? new HashSet<>(Arrays.asList(userNamesArgument.split(SEPARATOR))) - : Collections.emptySet(); - - final Set<String> userIds = StringUtils.isNotBlank(userIdsArgument) - ? new HashSet<>(Arrays.asList(userIdsArgument.split(SEPARATOR))) - : Collections.emptySet(); - - if (userNames.isEmpty() && userIds.isEmpty()) { - return result; - } - - final List<User> users = client.getUsers(); - - for (final User user : users) { - if (userNames.contains(user.getIdentity()) || userIds.contains(user.getIdentifier())) { - result.add(user); - } - } - - return result; - } - - public static Set<Tenant> getExistingGroups(final TenantsClient client, final String userGroupNamesArgument, final String userGroupIdsArgument) - throws IOException, NiFiRegistryException { - final Set<Tenant> result = new HashSet<>(); - - final Set<String> userGroupNames = StringUtils.isNotBlank(userGroupNamesArgument) - ? new HashSet<>(Arrays.asList(userGroupNamesArgument.split(SEPARATOR))) - : Collections.emptySet(); - - final Set<String> userGroupIds = StringUtils.isNotBlank(userGroupIdsArgument) - ? new HashSet<>(Arrays.asList(userGroupIdsArgument.split(SEPARATOR))) - : Collections.emptySet(); - - if (userGroupNames.isEmpty() && userGroupIds.isEmpty()) { - return result; - } + public static <T extends Tenant> Set<Tenant> selectExistingTenants(final String names, final String ids, List<T> allTenants) { + String separator = ","; - final List<UserGroup> usersGroups = client.getUserGroups(); + Set<String> nameSet = new HashSet<>(Arrays.asList(Optional.ofNullable(names).orElse("").split(separator))); + Set<String> idSet = new HashSet<>(Arrays.asList(Optional.ofNullable(ids).orElse("").split(separator))); - for (final UserGroup userGroup : usersGroups) { - if (userGroupNames.contains(userGroup.getIdentity()) || userGroupIds.contains(userGroup.getIdentifier())) { - result.add(userGroup); - } - } + Set<Tenant> existingTentants = allTenants.stream() + .filter(tenant -> nameSet.contains(tenant.getIdentity()) || idSet.contains(tenant.getIdentifier())) + .collect(Collectors.toSet()); - return result; + return existingTentants; } } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdatePolicy.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdatePolicy.java deleted file mode 100644 index f30f3cf..0000000 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdatePolicy.java +++ /dev/null @@ -1,112 +0,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. - */ -package org.apache.nifi.toolkit.cli.impl.command.registry.tenant; - -import org.apache.commons.cli.ParseException; -import org.apache.commons.lang3.StringUtils; -import org.apache.nifi.registry.authorization.AccessPolicy; -import org.apache.nifi.registry.authorization.Tenant; -import org.apache.nifi.registry.client.NiFiRegistryClient; -import org.apache.nifi.registry.client.NiFiRegistryException; -import org.apache.nifi.toolkit.cli.api.Context; -import org.apache.nifi.toolkit.cli.impl.client.ExtendedNiFiRegistryClient; -import org.apache.nifi.toolkit.cli.impl.client.registry.PoliciesClient; -import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; -import org.apache.nifi.toolkit.cli.impl.command.CommandOption; -import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand; -import org.apache.nifi.toolkit.cli.impl.result.StringResult; - -import java.io.IOException; -import java.util.Properties; -import java.util.Set; - -/** - * Command for update an existing policy. - */ -public class UpdatePolicy extends AbstractNiFiRegistryCommand<StringResult> { - - public UpdatePolicy() { - super("update-policy", StringResult.class); - } - - @Override - public String getDescription() { - return "Updates an existing access policy."; - } - - @Override - protected void doInitialize(final Context context) { - // Required - addOption(CommandOption.POLICY_ID.createOption()); - - // Optional - addOption(CommandOption.POLICY_RESOURCE.createOption()); - addOption(CommandOption.POLICY_ACTION.createOption()); - addOption(CommandOption.USER_NAME_LIST.createOption()); - addOption(CommandOption.USER_ID_LIST.createOption()); - addOption(CommandOption.GROUP_NAME_LIST.createOption()); - addOption(CommandOption.GROUP_ID_LIST.createOption()); - } - - @Override - public StringResult doExecute(final NiFiRegistryClient client, final Properties properties) - throws IOException, NiFiRegistryException, ParseException { - - if (!(client instanceof ExtendedNiFiRegistryClient)) { - throw new IllegalArgumentException("This command needs extended registry client!"); - } - - final ExtendedNiFiRegistryClient extendedClient = (ExtendedNiFiRegistryClient) client; - final PoliciesClient policiesClient = extendedClient.getPoliciesClient(); - final TenantsClient tenantsClient = extendedClient.getTenantsClient(); - - final String policyId = getRequiredArg(properties, CommandOption.POLICY_ID); - final String resource = getArg(properties, CommandOption.POLICY_RESOURCE); - final String action = getArg(properties, CommandOption.POLICY_ACTION); - - final AccessPolicy existingPolicy = policiesClient.getPolicy(policyId); - - if (StringUtils.isNotBlank(resource)) { - existingPolicy.setResource(resource); - } - - if (StringUtils.isNotBlank(action)) { - existingPolicy.setAction(action); - } - - final Set<Tenant> users = TenantHelper.getExistingUsers( - tenantsClient, - getArg(properties, CommandOption.USER_NAME_LIST), - getArg(properties, CommandOption.USER_ID_LIST)); - - if (StringUtils.isNotBlank(getArg(properties, CommandOption.USER_NAME_LIST)) || StringUtils.isNotBlank(getArg(properties, CommandOption.USER_ID_LIST))) { - existingPolicy.setUsers(users); - } - - final Set<Tenant> userGroups = TenantHelper.getExistingGroups( - tenantsClient, - getArg(properties, CommandOption.GROUP_NAME_LIST), - getArg(properties, CommandOption.GROUP_ID_LIST)); - - if (StringUtils.isNotBlank(getArg(properties, CommandOption.GROUP_NAME_LIST)) || StringUtils.isNotBlank(getArg(properties, CommandOption.GROUP_ID_LIST))) { - existingPolicy.setUserGroups(userGroups); - } - - final AccessPolicy updatedPolicy = policiesClient.updatePolicy(existingPolicy); - return new StringResult(updatedPolicy.getIdentifier(), getContext().isInteractive()); - } -} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUser.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUser.java index c41f1ba..d2c8a05 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUser.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUser.java @@ -26,18 +26,17 @@ import org.apache.nifi.toolkit.cli.impl.client.ExtendedNiFiRegistryClient; import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; import org.apache.nifi.toolkit.cli.impl.command.CommandOption; import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand; -import org.apache.nifi.toolkit.cli.impl.result.StringResult; +import org.apache.nifi.toolkit.cli.impl.result.VoidResult; import java.io.IOException; import java.util.Properties; /** - * Command for update an existing user. + * Command for updating an existing user. */ -public class UpdateUser extends AbstractNiFiRegistryCommand<StringResult> { - +public class UpdateUser extends AbstractNiFiRegistryCommand<VoidResult> { public UpdateUser() { - super("update-user", StringResult.class); + super("update-user", VoidResult.class); } @Override @@ -55,7 +54,7 @@ public class UpdateUser extends AbstractNiFiRegistryCommand<StringResult> { } @Override - public StringResult doExecute(final NiFiRegistryClient client, final Properties properties) + public VoidResult doExecute(final NiFiRegistryClient client, final Properties properties) throws IOException, NiFiRegistryException, ParseException { if (!(client instanceof ExtendedNiFiRegistryClient)) { @@ -73,7 +72,8 @@ public class UpdateUser extends AbstractNiFiRegistryCommand<StringResult> { existingUser.setIdentity(userName); } - final User updatedUser = tenantsClient.updateUser(existingUser); - return new StringResult(updatedUser.getIdentifier(), getContext().isInteractive()); + tenantsClient.updateUser(existingUser); + + return VoidResult.getInstance(); } } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUserGroup.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUserGroup.java index d29a843..45b0ff2 100644 --- a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUserGroup.java +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/UpdateUserGroup.java @@ -27,7 +27,7 @@ import org.apache.nifi.toolkit.cli.impl.client.ExtendedNiFiRegistryClient; import org.apache.nifi.toolkit.cli.impl.client.registry.TenantsClient; import org.apache.nifi.toolkit.cli.impl.command.CommandOption; import org.apache.nifi.toolkit.cli.impl.command.registry.AbstractNiFiRegistryCommand; -import org.apache.nifi.toolkit.cli.impl.result.StringResult; +import org.apache.nifi.toolkit.cli.impl.result.VoidResult; import java.io.IOException; import java.util.Properties; @@ -36,10 +36,10 @@ import java.util.Set; /** * Command for update an existing user group. */ -public class UpdateUserGroup extends AbstractNiFiRegistryCommand<StringResult> { +public class UpdateUserGroup extends AbstractNiFiRegistryCommand<VoidResult> { public UpdateUserGroup() { - super("update-user-group", StringResult.class); + super("update-user-group", VoidResult.class); } @Override @@ -59,7 +59,7 @@ public class UpdateUserGroup extends AbstractNiFiRegistryCommand<StringResult> { } @Override - public StringResult doExecute(final NiFiRegistryClient client, final Properties properties) + public VoidResult doExecute(final NiFiRegistryClient client, final Properties properties) throws IOException, NiFiRegistryException, ParseException { if (!(client instanceof ExtendedNiFiRegistryClient)) { throw new IllegalArgumentException("This command needs extended registry client!"); @@ -78,14 +78,16 @@ public class UpdateUserGroup extends AbstractNiFiRegistryCommand<StringResult> { } // Update group members - final Set<Tenant> tenants = TenantHelper.getExistingUsers( - tenantsClient, - getArg(properties, CommandOption.USER_NAME_LIST), - getArg(properties, CommandOption.USER_ID_LIST)); + Set<Tenant> users = TenantHelper.selectExistingTenants( + getArg(properties, CommandOption.USER_NAME_LIST), + getArg(properties, CommandOption.USER_ID_LIST), + tenantsClient.getUsers() + ); - existingGroup.setUsers(tenants); + existingGroup.setUsers(users); - final UserGroup updatedGroup = tenantsClient.updateUserGroup(existingGroup); - return new StringResult(updatedGroup.getIdentifier(), getContext().isInteractive()); + tenantsClient.updateUserGroup(existingGroup); + + return VoidResult.getInstance(); } } diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/AccessPolicyResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/AccessPolicyResult.java new file mode 100644 index 0000000..c394601 --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/AccessPolicyResult.java @@ -0,0 +1,59 @@ +/* + * 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.toolkit.cli.impl.result.registry; + +import org.apache.commons.lang3.Validate; +import org.apache.nifi.registry.authorization.AccessPolicy; +import org.apache.nifi.registry.authorization.Tenant; +import org.apache.nifi.toolkit.cli.api.ResultType; +import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult; + +import java.io.IOException; +import java.io.PrintStream; +import java.util.Set; +import java.util.stream.Collectors; + +public class AccessPolicyResult extends AbstractWritableResult<AccessPolicy> { + private final AccessPolicy accessPolicy; + + public AccessPolicyResult(ResultType resultType, AccessPolicy accessPolicy) { + super(resultType); + this.accessPolicy = accessPolicy; + Validate.notNull(accessPolicy); + } + + @Override + public AccessPolicy getResult() { + return accessPolicy; + } + + @Override + protected void writeSimpleResult(PrintStream output) throws IOException { + output.printf("Resource: %s\nAction : %s\nUsers : %s\nGroups : %s\n", + accessPolicy.getResource(), + accessPolicy.getAction(), + joinTenantIdentities(accessPolicy.getUsers()), + joinTenantIdentities(accessPolicy.getUserGroups()) + ); + } + + private String joinTenantIdentities(Set<Tenant> tenants) { + return tenants.stream() + .map(tenant -> tenant.getIdentity()) + .collect(Collectors.joining(", ")); + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/UserGroupsResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/UserGroupsResult.java new file mode 100644 index 0000000..d517cef --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/UserGroupsResult.java @@ -0,0 +1,82 @@ +/* + * 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.toolkit.cli.impl.result.registry; + +import org.apache.commons.lang3.Validate; +import org.apache.nifi.registry.authorization.Tenant; +import org.apache.nifi.registry.authorization.UserGroup; +import org.apache.nifi.toolkit.cli.api.ResultType; +import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult; +import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter; +import org.apache.nifi.toolkit.cli.impl.result.writer.Table; +import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter; + +import java.io.PrintStream; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Result for a list of users. + */ +public class UserGroupsResult extends AbstractWritableResult<List<UserGroup>> { + private final List<UserGroup> userGroups; + + public UserGroupsResult(final ResultType resultType, final List<UserGroup> userGroups) { + super(resultType); + this.userGroups = userGroups; + Validate.notNull(userGroups); + } + + @Override + public List<UserGroup> getResult() { + return userGroups; + } + + @Override + protected void writeSimpleResult(final PrintStream output) { + if (userGroups.isEmpty()) { + return; + } + + final Table table = new Table.Builder() + .column("#", 3, 3, false) + .column("Name", 20, 36, true) + .column("Id", 36, 36, false) + .column("Users", 36, 200, false) + .build(); + + for (int userIndex = 0; userIndex < userGroups.size(); ++userIndex) { + final UserGroup userGroup = userGroups.get(userIndex); + table.addRow( + String.valueOf(userIndex + 1), + userGroup.getIdentity(), + userGroup.getIdentifier(), + joinTenantIdentities(userGroup.getUsers()) + ); + } + + final TableWriter tableWriter = new DynamicTableWriter(); + tableWriter.write(table, output); + } + + private String joinTenantIdentities(Set<Tenant> tenants) { + return tenants.stream() + .map(tenant -> tenant.getIdentity()) + .collect(Collectors.joining("; ")); + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/UsersResult.java b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/UsersResult.java new file mode 100644 index 0000000..4d19a3b --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/main/java/org/apache/nifi/toolkit/cli/impl/result/registry/UsersResult.java @@ -0,0 +1,67 @@ +/* + * 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.toolkit.cli.impl.result.registry; + +import org.apache.commons.lang3.Validate; +import org.apache.nifi.registry.authorization.User; +import org.apache.nifi.toolkit.cli.api.ResultType; +import org.apache.nifi.toolkit.cli.impl.result.AbstractWritableResult; +import org.apache.nifi.toolkit.cli.impl.result.writer.DynamicTableWriter; +import org.apache.nifi.toolkit.cli.impl.result.writer.Table; +import org.apache.nifi.toolkit.cli.impl.result.writer.TableWriter; + +import java.io.PrintStream; +import java.util.List; + +/** + * Result for a list of users. + */ +public class UsersResult extends AbstractWritableResult<List<User>> { + private final List<User> users; + + public UsersResult(ResultType resultType, List<User> users) { + super(resultType); + this.users = users; + Validate.notNull(users); + } + + @Override + public List<User> getResult() { + return users; + } + + @Override + protected void writeSimpleResult(final PrintStream output) { + if (users.isEmpty()) { + return; + } + + final Table table = new Table.Builder() + .column("#", 3, 3, false) + .column("Name", 20, 36, true) + .column("Id", 36, 36, false) + .build(); + + for (int userIndex = 0; userIndex < users.size(); ++userIndex) { + final User user = users.get(userIndex); + table.addRow(String.valueOf(userIndex + 1), user.getIdentity(), user.getIdentifier()); + } + + final TableWriter tableWriter = new DynamicTableWriter(); + tableWriter.write(table, output); + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/command/registry/RegistryManualIT.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/command/registry/RegistryManualIT.java new file mode 100644 index 0000000..a8e0e5c --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/command/registry/RegistryManualIT.java @@ -0,0 +1,311 @@ +/* + * 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.toolkit.cli.impl.command.registry; + +import org.apache.nifi.toolkit.cli.CLIMain; +import org.apache.nifi.util.StringUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintStream; +import java.util.StringJoiner; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class RegistryManualIT { + public static final String TRUSTSTORE = ""; + public static final String TRUSTSTORE_PASSWD = ""; + + public static final String KEYSTORE = ""; + public static final String KEYSTORE_PASSWD = ""; + + private String basicSettings = "--baseUrl https://localhost:18443 --verbose"; + private String securitySettings = "--truststore " + TRUSTSTORE + + " --truststoreType jks --truststorePasswd " + TRUSTSTORE_PASSWD + + " --keystore " + KEYSTORE + + " --keystorePasswd " + KEYSTORE_PASSWD + + " --keystoreType PKCS12"; + + private static final String TEST_USER_NAME = "testUser"; + private static final String TEST_USER_GROUP_NAME = "testUserGroup"; + private String testUserId; + private String testUserGroupId; + + private PrintStream originalStdOut; + private ByteArrayOutputStream out; + + @Before + public void setUp() throws Exception { + assertFalse("truststore not set", StringUtils.isBlank(TRUSTSTORE)); + assertFalse("truststorePasswd not set", StringUtils.isBlank(TRUSTSTORE_PASSWD)); + assertFalse("keystore not set", StringUtils.isBlank(KEYSTORE)); + assertFalse("keystorePassed not set", StringUtils.isBlank(KEYSTORE_PASSWD)); + } + + @After + public void tearDown() throws Exception { + resetStdOut(); + } + + @Ignore("Run first and only once") + @Test + public void testCreateUser() throws Exception { + String userName = TEST_USER_NAME; + + runRegistryCommand("create-user", + "--userName " + userName + ); + + testListUsers(userName); + } + + @Ignore("Run first and only once") + @Test + public void testCreateUseGroup() throws Exception { + String expectedUserGroup = TEST_USER_GROUP_NAME; + + runRegistryCommand("create-user-group", + "--userGroupName " + expectedUserGroup + + " --userNameList " + TEST_USER_NAME + + " --userIdList " + testUserId + ); + + testListUserGroup(expectedUserGroup); + } + + @Test + public void testListUsers() throws Exception { + testListUsers(TEST_USER_NAME); + } + + @Test + public void testUpdateUser() throws Exception { + String originalUserName = TEST_USER_NAME; + String updatedUserName = "updatedTestUser"; + + testListUsers(originalUserName); + + runRegistryCommand("update-user", + "--userName " + updatedUserName + + " --userId " + testUserId + ); + + testListUsers(updatedUserName); + + runRegistryCommand("update-user", + "--userName " + originalUserName + + " --userId " + testUserId + ); + + testListUsers(originalUserName); + } + + @Test + public void testListUserGroups() throws Exception { + testListUserGroup(TEST_USER_GROUP_NAME); + } + + @Test + public void testUpdateUserGroup() throws Exception { + runRegistryCommand("update-user-group", + "--userGroupName " + TEST_USER_GROUP_NAME + + " --userNameList " + TEST_USER_NAME + + " --userIdLis " + testUserId + + " --userGroupId " + testUserGroupId + ); + + testListUserGroup(TEST_USER_GROUP_NAME); + } + + @Test + public void testGetAccessPolicy() throws Exception { + String action = "read"; + String resource = "/testResource"; + + testGetAccessPolicy(action, resource); + } + + @Test + public void testCreateOrUpdateAccessPolicy() throws Exception { + String action = "read"; + String resource = "/testResource"; + + runRegistryCommand("update-policy", + "--accessPolicyResource " + resource + + " --accessPolicyAction " + action + + " --userNameList " + TEST_USER_NAME + + " --userIdList " + testUserId + + " --groupNameList " + TEST_USER_GROUP_NAME + + " --groupIdList " + testUserGroupId + ); + + testGetAccessPolicy(action, resource); + + // Users are not removed if none is specified + runRegistryCommand("update-policy", + "--accessPolicyResource " + resource + + " --accessPolicyAction " + action + + " --groupNameList " + TEST_USER_GROUP_NAME + + " --groupIdList " + testUserGroupId + ); + + testGetAccessPolicy(action, resource); + + // Groups are not removed if none is specified + runRegistryCommand("update-policy", + "--accessPolicyResource " + resource + + " --accessPolicyAction " + action + + " --userNameList " + TEST_USER_NAME + + " --userIdList " + testUserId + ); + + testGetAccessPolicy(action, resource); + } + + private void testListUsers(String expectedUserName) throws IOException { + runCommand( + "\\s{3,}", + () -> runRegistryCommand("list-users", ""), + words -> { + if (words.length > 2 && words[1].equals(expectedUserName)) { + testUserId = words[2]; + } + }, + () -> { + assertNotNull(testUserId); + assertTrue("User id shouldn't be blank!", !StringUtils.isBlank(testUserId)); + } + ); + } + + private void testListUserGroup(String expectedUserGroupName) throws IOException { + runCommand( + "\\s{3,}", + () -> runRegistryCommand("list-user-groups", ""), + words -> { + if (words.length > 3 && words[1].equals(expectedUserGroupName)) { + testUserGroupId = words[2]; + } + }, + () -> { + assertNotNull(testUserGroupId); + assertTrue("Group id shouldn't be blank!", !StringUtils.isBlank(testUserGroupId)); + } + ); + } + + private void testGetAccessPolicy(String action, String resource) throws IOException { + AtomicReference<String> resourceR = new AtomicReference<>(); + AtomicReference<String> actionR = new AtomicReference<>(); + AtomicReference<String> usersR = new AtomicReference<>(); + AtomicReference<String> groupsR = new AtomicReference<>(); + + runCommand( + "\\s*:\\s+", + () -> runRegistryCommand("get-policy", + "--accessPolicyResource " + resource + + " --accessPolicyAction " + action + ), + words -> { + if (words.length > 1) { + if (words[0].equals("Users")) { + usersR.set(words[1]); + } else if (words[0].equals("Groups")) { + groupsR.set(words[1]); + } else if (words[0].equals("Resource")) { + resourceR.set(words[1]); + } else if (words[0].equals("Action")) { + actionR.set(words[1]); + } + } + }, + () -> { + resourceR.get().equals(resource); + actionR.get().contains(action); + usersR.get().contains(TEST_USER_NAME); + groupsR.get().contains(TEST_USER_GROUP_NAME); + } + ); + } + + private void runCommand(String delimiter, Runnable commandRunner, Consumer<String[]> outputLineHandler, Runnable check) throws IOException { + try { + // GIVEN + startCaptureStdOut(); + + // WHEN + commandRunner.run(); + + // THEN + BufferedReader bufferedOutput = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(out.toByteArray()))); + + String line; + while ((line = bufferedOutput.readLine()) != null) { + originalStdOut.println(line); + + String[] words = line.split(delimiter); + + outputLineHandler.accept(words); + } + + check.run(); + } finally { + resetStdOut(); + } + } + + private void runRegistryCommand(String command, String commandArguments) { + // GIVEN + String arguments = new StringJoiner(" ") + .add("registry") + .add(command) + .add(commandArguments) + .add(basicSettings) + .add(securitySettings) + .toString(); + + String[] args = arguments.split("\\s+"); + + // WHEN + CLIMain.runSingleCommand(args); + + // THEN + } + + private void startCaptureStdOut() { + originalStdOut = System.out; + out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + } + + private void resetStdOut() { + if (originalStdOut != null) { + System.setOut(originalStdOut); + } + } +} diff --git a/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TestTenantHelper.java b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TestTenantHelper.java new file mode 100644 index 0000000..7efe903 --- /dev/null +++ b/nifi-toolkit/nifi-toolkit-cli/src/test/java/org/apache/nifi/toolkit/cli/impl/command/registry/tenant/TestTenantHelper.java @@ -0,0 +1,153 @@ +/* + * 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.toolkit.cli.impl.command.registry.tenant; + +import org.apache.nifi.registry.authorization.Tenant; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static org.junit.Assert.assertEquals; + +public class TestTenantHelper { + @Test + public void testSelectExistingTenantsWithEmptyNamesAndIds() throws Exception { + // GIVEN + String names = ""; + String ids = ""; + + List<Tenant> allTenants = Arrays.asList( + createTenant("__1", "__1"), + createTenant("__2", "__2") + ); + + List<Tenant> expected = Collections.emptyList(); + + // WHEN + // THEN + testSelectExistingTenants(names, ids, allTenants, expected); + } + + @Test + public void testSelectExistingTenantsWithNames() throws Exception { + // GIVEN + String names = "name1,name3"; + String ids = ""; + + Tenant tenantFoundByName1 = createTenant("__1", "name1"); + Tenant tenantNotFound2 = createTenant("__2", "__2"); + Tenant tenantFoundByName3 = createTenant("__3", "name3"); + Tenant tenantNotFound4 = createTenant("__4", "__4"); + + List<Tenant> allTenants = Arrays.asList( + tenantFoundByName1, + tenantNotFound2, + tenantFoundByName3, + tenantNotFound4 + ); + + List<Tenant> expected = Arrays.asList( + tenantFoundByName1, + tenantFoundByName3 + ); + + // WHEN + // THEN + testSelectExistingTenants(names, ids, allTenants, expected); + } + + @Test + public void testSelectExistingTenantsWithIds() throws Exception { + // GIVEN + String names = ""; + String ids = "id1,id2"; + + Tenant tenantFoundById1 = createTenant("id1", "__1"); + Tenant tenantFoundById2 = createTenant("id2", "__2"); + Tenant tenantNotFound3 = createTenant("__3", "__3"); + Tenant tenantNotFound4 = createTenant("__4", "__4"); + + List<Tenant> allTenants = Arrays.asList( + tenantFoundById1, + tenantFoundById2, + tenantNotFound3, + tenantNotFound4 + ); + + List<Tenant> expected = Arrays.asList( + tenantFoundById1, + tenantFoundById2 + ); + + // WHEN + // THEN + testSelectExistingTenants(names, ids, allTenants, expected); + } + + @Test + public void testSelectExistingTenantsWithComplexScenario() throws Exception { + // GIVEN + String names = "name1,name3"; + String ids = "id1,id2"; + + Tenant tenantFoundByIdAndName = createTenant("id1", "name1"); + Tenant tenantFoundById = createTenant("id2", "_2_"); + Tenant tenantFoundByName = createTenant("__3", "name3"); + Tenant tenantNotFound = createTenant("__4", "__4"); + + List<Tenant> allTenants = Arrays.asList( + tenantFoundByIdAndName, + tenantFoundById, + tenantFoundByName, + tenantNotFound + ); + + List<Tenant> expected = Arrays.asList( + tenantFoundByIdAndName, + tenantFoundById, + tenantFoundByName + ); + + // WHEN + // THEN + testSelectExistingTenants(names, ids, allTenants, expected); + } + + private void testSelectExistingTenants(String names, String ids, List<Tenant> allTenants, List<Tenant> expectedTenants) { + // GIVEN + Set<Tenant> expected = new HashSet<>(expectedTenants); + + // WHEN + Set<Tenant> actual = TenantHelper.selectExistingTenants(names, ids, allTenants); + + // THEN + assertEquals(expected, actual); + } + + private Tenant createTenant(String identifier, String identity) { + Tenant tenant = new Tenant(); + + tenant.setIdentifier(identifier); + tenant.setIdentity(identity); + + return tenant; + } +}
