All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.nifi.toolkit.client.impl.AbstractJerseyClient Maven / Gradle / Ivy

The newest version!
/*
 * 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.client.impl;

import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.client.Invocation;
import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.toolkit.client.NiFiClientException;
import org.apache.nifi.toolkit.client.RequestConfig;

import java.io.IOException;
import java.util.Collections;
import java.util.Map;

/**
 * Base class for the client operations to share exception handling.
 *
 * Sub-classes should always execute a request from getRequestBuilder(target) to
 * ensure proper headers are sent.
 */
public class AbstractJerseyClient {

    private static final RequestConfig EMPTY_REQUEST_CONFIG = () -> Collections.emptyMap();

    private final RequestConfig requestConfig;

    public AbstractJerseyClient(final RequestConfig requestConfig) {
        this.requestConfig = (requestConfig == null ? EMPTY_REQUEST_CONFIG : requestConfig);
    }

    protected RequestConfig getRequestConfig() {
        return this.requestConfig;
    }

    /**
     * Creates a new Invocation.Builder for the given WebTarget with the headers
     * added to the builder.
     *
     * @param webTarget the target for the request
     * @return the builder for the target with the headers added
     */
    protected Invocation.Builder getRequestBuilder(final WebTarget webTarget) {
        final Invocation.Builder requestBuilder = webTarget.request();

        final Map headers = requestConfig.getHeaders();
        headers.entrySet().stream().forEach(e -> requestBuilder.header(e.getKey(), e.getValue()));

        return requestBuilder;
    }

    /**
     * Executes the given action and returns the result.
     *
     * @param action       the action to execute
     * @param errorMessage the message to use if a NiFiRegistryException is thrown
     * @param           the return type of the action
     * @return the result of the action
     * @throws NiFiClientException if any exception other than IOException is
     *                             encountered
     * @throws IOException         if an I/O error occurs communicating with the
     *                             registry
     */
    protected  T executeAction(final String errorMessage, final NiFiAction action) throws NiFiClientException, IOException {
        try {
            return action.execute();
        } catch (final Exception e) {
            final Throwable ioeCause = getIOExceptionCause(e);

            if (ioeCause == null) {
                final StringBuilder errorMessageBuilder = new StringBuilder(errorMessage);

                // see if we have a WebApplicationException, and if so add the response body to
                // the error message
                if (e instanceof WebApplicationException) {
                    final Response response = ((WebApplicationException) e).getResponse();
                    final String responseBody = response.readEntity(String.class);
                    errorMessageBuilder.append(": ").append(responseBody);
                }

                throw new NiFiClientException(errorMessageBuilder.toString(), e);
            } else {
                throw (IOException) ioeCause;
            }
        }
    }

    /**
     * An action to execute with the given return type.
     *
     * @param  the return type of the action
     */
    protected interface NiFiAction {

        T execute() throws IOException;

    }

    /**
     * @param e an exception that was encountered interacting with the registry
     * @return the IOException that caused this exception, or null if the an
     *         IOException did not cause this exception
     */
    protected Throwable getIOExceptionCause(final Throwable e) {
        if (e == null) {
            return null;
        }

        if (e instanceof IOException) {
            return e;
        }

        return getIOExceptionCause(e.getCause());
    }

    /**
     * Gets the filename from the content disposition header.
     *
     * @param response a response
     * @return the filename value
     */
    protected String getContentDispositionFilename(final Response response) {
        final String contentDispositionHeader = response.getHeaderString("Content-Disposition");
        if (StringUtils.isBlank(contentDispositionHeader)) {
            throw new IllegalStateException("Content-Disposition header was blank or missing");
        }

        final int equalsIndex = contentDispositionHeader.lastIndexOf("=");
        final String filenameValue = contentDispositionHeader.substring(equalsIndex + 1).trim();

        final StringBuilder filename = new StringBuilder(filenameValue);
        if (!filename.isEmpty() && filename.charAt(0) == '"') {
            filename.deleteCharAt(0);
        }
        if (!filename.isEmpty() && filename.charAt(filename.length() - 1) == '"') {
            filename.setLength(filename.length() - 1);
        }
        return filename.toString();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy