blob: 3e64badfb30c0be39d2b3eeeece24e385cfdd691 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.registry.client.impl;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.registry.bucket.BucketItem;
import org.apache.nifi.registry.client.AccessClient;
import org.apache.nifi.registry.client.BucketClient;
import org.apache.nifi.registry.client.BundleClient;
import org.apache.nifi.registry.client.BundleVersionClient;
import org.apache.nifi.registry.client.ExtensionClient;
import org.apache.nifi.registry.client.ExtensionRepoClient;
import org.apache.nifi.registry.client.FlowClient;
import org.apache.nifi.registry.client.FlowSnapshotClient;
import org.apache.nifi.registry.client.ItemsClient;
import org.apache.nifi.registry.client.NiFiRegistryClient;
import org.apache.nifi.registry.client.NiFiRegistryClientConfig;
import org.apache.nifi.registry.client.PoliciesClient;
import org.apache.nifi.registry.client.RequestConfig;
import org.apache.nifi.registry.client.TenantsClient;
import org.apache.nifi.registry.client.UserClient;
import org.apache.nifi.registry.client.impl.request.ProxiedEntityRequestConfig;
import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.client.ClientProperties;
import org.glassfish.jersey.client.RequestEntityProcessing;
import org.glassfish.jersey.jackson.internal.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import java.io.IOException;
import java.net.URI;
/**
* A NiFiRegistryClient that uses Jersey Client.
*/
public class JerseyNiFiRegistryClient implements NiFiRegistryClient {
static final String NIFI_REGISTRY_CONTEXT = "nifi-registry-api";
static final int DEFAULT_CONNECT_TIMEOUT = 10000;
static final int DEFAULT_READ_TIMEOUT = 10000;
private final Client client;
private final WebTarget baseTarget;
private final BucketClient bucketClient;
private final FlowClient flowClient;
private final FlowSnapshotClient flowSnapshotClient;
private final ItemsClient itemsClient;
private JerseyNiFiRegistryClient(final NiFiRegistryClient.Builder builder) {
final NiFiRegistryClientConfig registryClientConfig = builder.getConfig();
if (registryClientConfig == null) {
throw new IllegalArgumentException("NiFiRegistryClientConfig cannot be null");
}
String baseUrl = registryClientConfig.getBaseUrl();
if (StringUtils.isBlank(baseUrl)) {
throw new IllegalArgumentException("Base URL cannot be blank");
}
if (baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length() - 1);
}
if (!baseUrl.endsWith(NIFI_REGISTRY_CONTEXT)) {
baseUrl = baseUrl + "/" + NIFI_REGISTRY_CONTEXT;
}
try {
new URI(baseUrl);
} catch (final Exception e) {
throw new IllegalArgumentException("Invalid base URL: " + e.getMessage(), e);
}
final SSLContext sslContext = registryClientConfig.getSslContext();
final HostnameVerifier hostnameVerifier = registryClientConfig.getHostnameVerifier();
final ClientBuilder clientBuilder = ClientBuilder.newBuilder();
if (sslContext != null) {
clientBuilder.sslContext(sslContext);
}
if (hostnameVerifier != null) {
clientBuilder.hostnameVerifier(hostnameVerifier);
}
final int connectTimeout = registryClientConfig.getConnectTimeout() == null ? DEFAULT_CONNECT_TIMEOUT : registryClientConfig.getConnectTimeout();
final int readTimeout = registryClientConfig.getReadTimeout() == null ? DEFAULT_READ_TIMEOUT : registryClientConfig.getReadTimeout();
final ClientConfig clientConfig = new ClientConfig();
clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout);
clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout);
clientConfig.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED);
clientConfig.register(jacksonJaxbJsonProvider());
clientBuilder.withConfig(clientConfig);
this.client = clientBuilder
.register(MultiPartFeature.class)
.build();
this.baseTarget = client.target(baseUrl);
this.bucketClient = new JerseyBucketClient(baseTarget);
this.flowClient = new JerseyFlowClient(baseTarget);
this.flowSnapshotClient = new JerseyFlowSnapshotClient(baseTarget);
this.itemsClient = new JerseyItemsClient(baseTarget);
}
@Override
public BucketClient getBucketClient() {
return this.bucketClient;
}
@Override
public BucketClient getBucketClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyBucketClient(baseTarget, requestConfig);
}
@Override
public BucketClient getBucketClient(RequestConfig requestConfig) {
return new JerseyBucketClient(baseTarget, requestConfig);
}
@Override
public FlowClient getFlowClient() {
return this.flowClient;
}
@Override
public FlowClient getFlowClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyFlowClient(baseTarget, requestConfig);
}
@Override
public FlowClient getFlowClient(RequestConfig requestConfig) {
return new JerseyFlowClient(baseTarget, requestConfig);
}
@Override
public FlowSnapshotClient getFlowSnapshotClient() {
return this.flowSnapshotClient;
}
@Override
public FlowSnapshotClient getFlowSnapshotClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyFlowSnapshotClient(baseTarget, requestConfig);
}
@Override
public FlowSnapshotClient getFlowSnapshotClient(RequestConfig requestConfig) {
return new JerseyFlowSnapshotClient(baseTarget, requestConfig);
}
@Override
public ItemsClient getItemsClient() {
return this.itemsClient;
}
@Override
public ItemsClient getItemsClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyItemsClient(baseTarget, requestConfig);
}
@Override
public ItemsClient getItemsClient(RequestConfig requestConfig) {
return new JerseyItemsClient(baseTarget, requestConfig);
}
@Override
public UserClient getUserClient() {
return new JerseyUserClient(baseTarget);
}
@Override
public UserClient getUserClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyUserClient(baseTarget, requestConfig);
}
@Override
public UserClient getUserClient(RequestConfig requestConfig) {
return new JerseyUserClient(baseTarget, requestConfig);
}
@Override
public BundleClient getBundleClient() {
return new JerseyBundleClient(baseTarget);
}
@Override
public BundleClient getBundleClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyBundleClient(baseTarget, requestConfig);
}
@Override
public BundleClient getBundleClient(RequestConfig requestConfig) {
return new JerseyBundleClient(baseTarget, requestConfig);
}
@Override
public BundleVersionClient getBundleVersionClient() {
return new JerseyBundleVersionClient(baseTarget);
}
@Override
public BundleVersionClient getBundleVersionClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyBundleVersionClient(baseTarget, requestConfig);
}
@Override
public BundleVersionClient getBundleVersionClient(RequestConfig requestConfig) {
return new JerseyBundleVersionClient(baseTarget, requestConfig);
}
@Override
public ExtensionRepoClient getExtensionRepoClient() {
return new JerseyExtensionRepoClient(baseTarget);
}
@Override
public ExtensionRepoClient getExtensionRepoClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyExtensionRepoClient(baseTarget, requestConfig);
}
@Override
public ExtensionRepoClient getExtensionRepoClient(RequestConfig requestConfig) {
return new JerseyExtensionRepoClient(baseTarget, requestConfig);
}
@Override
public ExtensionClient getExtensionClient() {
return new JerseyExtensionClient(baseTarget);
}
@Override
public ExtensionClient getExtensionClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyExtensionClient(baseTarget, requestConfig);
}
@Override
public ExtensionClient getExtensionClient(RequestConfig requestConfig) {
return new JerseyExtensionClient(baseTarget, requestConfig);
}
@Override
public TenantsClient getTenantsClient() {
return new JerseyTenantsClient(baseTarget);
}
@Override
public TenantsClient getTenantsClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyTenantsClient(baseTarget, requestConfig);
}
@Override
public TenantsClient getTenantsClient(RequestConfig requestConfig) {
return new JerseyTenantsClient(baseTarget, requestConfig);
}
@Override
public PoliciesClient getPoliciesClient() {
return new JerseyPoliciesClient(baseTarget);
}
@Override
public PoliciesClient getPoliciesClient(String... proxiedEntity) {
final RequestConfig requestConfig = new ProxiedEntityRequestConfig(proxiedEntity);
return new JerseyPoliciesClient(baseTarget, requestConfig);
}
@Override
public PoliciesClient getPoliciesClient(RequestConfig requestConfig) {
return new JerseyPoliciesClient(baseTarget, requestConfig);
}
@Override
public AccessClient getAccessClient() {
return new JerseyAccessClient(baseTarget);
}
@Override
public void close() throws IOException {
if (this.client != null) {
try {
this.client.close();
} catch (Exception e) {
}
}
}
/**
* Builder for creating a JerseyNiFiRegistryClient.
*/
public static class Builder implements NiFiRegistryClient.Builder {
private NiFiRegistryClientConfig clientConfig;
@Override
public Builder config(final NiFiRegistryClientConfig clientConfig) {
this.clientConfig = clientConfig;
return this;
}
@Override
public NiFiRegistryClientConfig getConfig() {
return clientConfig;
}
@Override
public NiFiRegistryClient build() {
return new JerseyNiFiRegistryClient(this);
}
}
private static JacksonJaxbJsonProvider jacksonJaxbJsonProvider() {
JacksonJaxbJsonProvider jacksonJaxbJsonProvider = new JacksonJaxbJsonProvider();
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyInclusion(JsonInclude.Value.construct(JsonInclude.Include.NON_NULL, JsonInclude.Include.NON_NULL));
mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(mapper.getTypeFactory()));
// Ignore unknown properties so that deployed client remain compatible with future versions of NiFi Registry that add new fields
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
SimpleModule module = new SimpleModule();
module.addDeserializer(BucketItem[].class, new BucketItemDeserializer());
mapper.registerModule(module);
jacksonJaxbJsonProvider.setMapper(mapper);
return jacksonJaxbJsonProvider;
}
}