exceptionfactory commented on code in PR #7884: URL: https://github.com/apache/nifi/pull/7884#discussion_r1386864555
########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") + .description("Access Token using for authentication against the 1Password APIs.") + .sensitive(true) + .required(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .build(); + + private List<PropertyDescriptor> properties; Review Comment: This list can be removed in favor of the `DESCRIPTORS` field. ```suggestion ``` ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") + .description("Access Token using for authentication against the 1Password APIs.") + .sensitive(true) + .required(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .build(); + + private List<PropertyDescriptor> properties; + private volatile WebClientServiceProvider webClientServiceProvider; + + private static final String GET_VAULTS = "/v1/vaults/"; + private static final String CONTENT_TYPE = "Content-type"; + private static final String APPLICATION_JSON = "application/json"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer "; + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private static final List<PropertyDescriptor> DESCRIPTORS = Arrays.asList( + WEB_CLIENT_SERVICE_PROVIDER, + CONNECT_SERVER, + ACCESS_TOKEN + ); + + @Override + protected void init(final ParameterProviderInitializationContext config) { + this.properties = DESCRIPTORS; + } Review Comment: This method can be removed and `getSupportedPropertyDescriptors()` can return `DESCRIPTORS` directly. ```suggestion ``` ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") + .description("Access Token using for authentication against the 1Password APIs.") + .sensitive(true) + .required(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .build(); + + private List<PropertyDescriptor> properties; + private volatile WebClientServiceProvider webClientServiceProvider; + + private static final String GET_VAULTS = "/v1/vaults/"; + private static final String CONTENT_TYPE = "Content-type"; + private static final String APPLICATION_JSON = "application/json"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer "; + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private static final List<PropertyDescriptor> DESCRIPTORS = Arrays.asList( + WEB_CLIENT_SERVICE_PROVIDER, + CONNECT_SERVER, + ACCESS_TOKEN + ); + + @Override + protected void init(final ParameterProviderInitializationContext config) { + this.properties = DESCRIPTORS; + } + + @Override + protected List<PropertyDescriptor> getSupportedPropertyDescriptors() { + return properties; + } + + @Override + public List<ConfigVerificationResult> verify(final ConfigurationContext context, final ComponentLog verificationLogger) { + final List<ConfigVerificationResult> results = new ArrayList<>(); + + webClientServiceProvider = context.getProperty(WEB_CLIENT_SERVICE_PROVIDER).asControllerService(WebClientServiceProvider.class); + + final String connectServer = context.getProperty(CONNECT_SERVER).getValue(); + final String accessToken = context.getProperty(ACCESS_TOKEN).getValue(); + + try { + final JsonNode vaultList = getVaultList(connectServer, accessToken); + + results.add(new ConfigVerificationResult.Builder() + .outcome(ConfigVerificationResult.Outcome.SUCCESSFUL) + .verificationStepName("Listing Vaults") + .explanation(String.format("Listed Vaults [%d]", vaultList.size())) + .build()); + } catch (final IllegalArgumentException | IOException e) { + verificationLogger.error("Listing Vaults failed", e); + results.add(new ConfigVerificationResult.Builder() + .outcome(ConfigVerificationResult.Outcome.FAILED) + .verificationStepName("Listing Vaults") + .explanation("Listing Vaults failed: " + e.getMessage()) + .build()); + } + return results; + } + + private JsonNode getVaultList(String connectServer, String accessToken) throws IOException { + final HttpResponseEntity getVaultList = webClientServiceProvider.getWebClientService() + .get() + .uri(URI.create(connectServer + GET_VAULTS)) Review Comment: Instead of using string concatenation, the `WebClientServiceProvider` has a method named `getHttpUriBuilder()` that can be used. The `HttpUriBuilder` takes a base `scheme`, `host`, and `port`, and then path segments can be appended. See examples in the `ShopifyRestService` or `SchemaRegistryApiClient` for Apicurio as examples/ ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") + .description("Access Token using for authentication against the 1Password APIs.") + .sensitive(true) + .required(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .build(); + + private List<PropertyDescriptor> properties; + private volatile WebClientServiceProvider webClientServiceProvider; + + private static final String GET_VAULTS = "/v1/vaults/"; + private static final String CONTENT_TYPE = "Content-type"; + private static final String APPLICATION_JSON = "application/json"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer "; + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private static final List<PropertyDescriptor> DESCRIPTORS = Arrays.asList( Review Comment: This should use `List.of()` to create an immutable List. ```suggestion private static final List<PropertyDescriptor> DESCRIPTORS = List.of( ``` ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") + .description("Access Token using for authentication against the 1Password APIs.") + .sensitive(true) + .required(true) + .addValidator(StandardValidators.NON_EMPTY_VALIDATOR) + .build(); + + private List<PropertyDescriptor> properties; + private volatile WebClientServiceProvider webClientServiceProvider; + + private static final String GET_VAULTS = "/v1/vaults/"; + private static final String CONTENT_TYPE = "Content-type"; + private static final String APPLICATION_JSON = "application/json"; + private static final String AUTHORIZATION_HEADER_NAME = "Authorization"; + private static final String AUTHORIZATION_HEADER_VALUE = "Bearer "; + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private static final List<PropertyDescriptor> DESCRIPTORS = Arrays.asList( + WEB_CLIENT_SERVICE_PROVIDER, + CONNECT_SERVER, + ACCESS_TOKEN + ); + + @Override + protected void init(final ParameterProviderInitializationContext config) { + this.properties = DESCRIPTORS; + } + + @Override + protected List<PropertyDescriptor> getSupportedPropertyDescriptors() { + return properties; Review Comment: ```suggestion return DESCRIPTORS; ``` ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") + .description("Access Token using for authentication against the 1Password APIs.") Review Comment: ```suggestion .description("Access Token used for authentication against the 1Password Connect Server API.") ``` ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/main/java/org/apache/nifi/parameter/OnePasswordParameterProvider.java: ########## @@ -0,0 +1,220 @@ +/* + * 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.parameter; + +import org.apache.nifi.annotation.documentation.CapabilityDescription; +import org.apache.nifi.annotation.documentation.Tags; +import org.apache.nifi.components.ConfigVerificationResult; +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.processor.util.StandardValidators; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +@Tags({"1Password"}) +@CapabilityDescription("Fetches parameters from 1Password Connect Server") +public class OnePasswordParameterProvider extends AbstractParameterProvider implements VerifiableParameterProvider { + + + public static final PropertyDescriptor WEB_CLIENT_SERVICE_PROVIDER = new PropertyDescriptor.Builder() + .name("Web Client Service Provider") + .displayName("Web Client Service Provider") + .description("Controller service for HTTP client operations.") + .identifiesControllerService(WebClientServiceProvider.class) + .required(true) + .build(); + public static final PropertyDescriptor CONNECT_SERVER = new PropertyDescriptor.Builder() + .name("Connect Server") + .displayName("Connect Server") + .description("HTTP endpoint of the 1Password Connect Server to connect to. Example: http://localhost:8080") + .required(true) + .addValidator(StandardValidators.URL_VALIDATOR) + .build(); + public static final PropertyDescriptor ACCESS_TOKEN = new PropertyDescriptor.Builder() + .name("access-token") + .displayName("Access Token") Review Comment: ```suggestion .name("Access Token") .displayName("Access Token") ``` ########## nifi-nar-bundles/nifi-standard-bundle/nifi-standard-parameter-providers/src/test/java/org/apache/nifi/parameter/TestOnePasswordParameterProvider.java: ########## @@ -0,0 +1,131 @@ +package org.apache.nifi.parameter;/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.apache.nifi.components.PropertyDescriptor; +import org.apache.nifi.controller.ConfigurationContext; +import org.apache.nifi.logging.ComponentLog; +import org.apache.nifi.reporting.InitializationException; +import org.apache.nifi.util.MockConfigurationContext; +import org.apache.nifi.util.MockParameterProviderInitializationContext; +import org.apache.nifi.web.client.api.HttpRequestBodySpec; +import org.apache.nifi.web.client.api.HttpRequestUriSpec; +import org.apache.nifi.web.client.api.HttpResponseEntity; +import org.apache.nifi.web.client.api.WebClientService; +import org.apache.nifi.web.client.provider.api.WebClientServiceProvider; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeEach; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.when; + +public class TestOnePasswordParameterProvider { + + public static final String WEB_CLIENT = "web-client-service-provider"; + + private OnePasswordParameterProvider parameterProvider; + private MockParameterProviderInitializationContext initializationContext; + + private Map<PropertyDescriptor, String> properties; + + + @BeforeEach + public void init() throws InitializationException { + final WebClientServiceProvider webClient = mock(WebClientServiceProvider.class); + + final OnePasswordParameterProvider rawProvider = new OnePasswordParameterProvider(); + initializationContext = new MockParameterProviderInitializationContext("id", "name", mock(ComponentLog.class)); + initializationContext.addControllerService(webClient, WEB_CLIENT); + rawProvider.initialize(initializationContext); + parameterProvider = spy(rawProvider); + + final WebClientService webClientService = mock(WebClientService.class); + when(webClient.getWebClientService()).thenReturn(webClientService); + + final HttpRequestUriSpec uriSpec = mock(HttpRequestUriSpec.class); + when(webClientService.get()).thenReturn(uriSpec); + + // list vaults + final HttpRequestBodySpec bodySpec = mock(HttpRequestBodySpec.class); + when(uriSpec.uri(argThat(argument -> argument == null || argument.getPath().endsWith("/vaults/")))).thenReturn(bodySpec); + when(bodySpec.header(any(), any())).thenReturn(bodySpec); + final HttpResponseEntity httpEntity = mock(HttpResponseEntity.class); + when(bodySpec.retrieve()).thenReturn(httpEntity); + + final String responseBody = "[{\"attributeVersion\":1,\"contentVersion\":5,\"createdAt\":\"2023-10-13T14:56:48Z\"," + + "\"description\":\"VPN logins, database details, and more.\",\"id\":\"qeo4jajm7azfh3wnsynbmr5lem\",\"items\":1," + + "\"name\":\"Engineering\",\"type\":\"USER_CREATED\",\"updatedAt\":\"2023-10-13T14:57:46Z\"}]"; + InputStream response = new ByteArrayInputStream(responseBody.getBytes()); + when(httpEntity.body()).thenReturn(response); + + // list items + final HttpRequestBodySpec bodySpecItems = mock(HttpRequestBodySpec.class); + when(uriSpec.uri(argThat(argument -> argument == null || argument.getPath().endsWith("/items")))).thenReturn(bodySpecItems); + when(bodySpecItems.header(any(), any())).thenReturn(bodySpecItems); + final HttpResponseEntity httpEntityItems = mock(HttpResponseEntity.class); + when(bodySpecItems.retrieve()).thenReturn(httpEntityItems); + + final String responseBodyItems = "[{\"additionalInformation\":\"localhost\",\"category\":\"DATABASE\",\"createdAt\":\"2023-10-13T16:54:45Z\"," + + "\"id\":\"evsdsvep67jitka2hmbg5tbxry\",\"lastEditedBy\":\"DBJG7MEI5NH6BIUVR3S66OWNSE\",\"title\":\"POSTGRES\"," + + "\"updatedAt\":\"2023-10-13T16:55:47Z\",\"vault\":{\"id\":\"qeo4jajm7azfh3wnsynbmr5lem\",\"name\":\"Engineering\"},\"version\":2}]"; + InputStream responseItems = new ByteArrayInputStream(responseBodyItems.getBytes()); + when(httpEntityItems.body()).thenReturn(responseItems); + + // get item + final HttpRequestBodySpec bodySpecItem = mock(HttpRequestBodySpec.class); + when(uriSpec.uri(argThat(argument -> argument == null || argument.getPath().endsWith("evsdsvep67jitka2hmbg5tbxry")))).thenReturn(bodySpecItem); + when(bodySpecItem.header(any(), any())).thenReturn(bodySpecItem); + final HttpResponseEntity httpEntityItem = mock(HttpResponseEntity.class); + when(bodySpecItem.retrieve()).thenReturn(httpEntityItem); + + final String responseBodyItem = "{\"additionalInformation\":\"localhost\",\"category\":\"DATABASE\",\"createdAt\":\"2023-10-13T16:54:45Z\"," + + "\"fields\":[{\"id\":\"notesPlain\",\"label\":\"notesPlain\",\"purpose\":\"NOTES\",\"type\":\"STRING\"},{\"id\":\"database_type\"," + + "\"label\":\"Type\",\"type\":\"MENU\",\"value\":\"postgresql\"},{\"id\":\"hostname\",\"label\":\"serveur\",\"type\":\"STRING\"," + + "\"value\":\"localhost\"},{\"id\":\"port\",\"label\":\"Port\",\"type\":\"STRING\",\"value\":\"5432\"},{\"id\":\"database\"," + + "\"label\":\"Base de données\",\"type\":\"STRING\",\"value\":\"mydatabase\"},{\"id\":\"username\",\"label\":\"Nom d'utilisateur\"," + + "\"type\":\"STRING\",\"value\":\"postgres\"},{\"id\":\"password\",\"label\":\"mot de passe\",\"type\":\"CONCEALED\"," + + "\"value\":\"thisisabadpassword\"},{\"id\":\"sid\",\"label\":\"SID\",\"type\":\"STRING\"},{\"id\":\"alias\",\"label\":\"Alias\"," + + "\"type\":\"STRING\"},{\"id\":\"options\",\"label\":\"Options de connexion\",\"type\":\"STRING\"}],\"id\":\"evsdsvep67jitka2hmbg5tbxry\"," + + "\"lastEditedBy\":\"DBJG7MEI5NH6BIUVR3S66OWNSE\",\"title\":\"POSTGRES\",\"updatedAt\":\"2023-10-13T16:55:47Z\"," + + "\"vault\":{\"id\":\"qeo4jajm7azfh3wnsynbmr5lem\",\"name\":\"Engineering\"},\"version\":2}"; Review Comment: Is it necessary to include all of these elements? Although this mirrors what 1Password returns, it would be easier to maintain if it included only the fields that the service uses. As this is also rather long, this is a great opportunity to using the newer [String text block](https://www.baeldung.com/java-text-blocks) language feature. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
