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

org.apache.camel.component.servicenow.ServiceNowClient Maven / Gradle / Ivy

There is a newer version: 4.9.0
Show 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.camel.component.servicenow;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Function;

import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;

import javax.net.ssl.SSLContext;

import com.fasterxml.jackson.jakarta.rs.json.JacksonJsonProvider;
import org.apache.camel.CamelContext;
import org.apache.camel.Message;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.component.servicenow.annotations.ServiceNowSysParm;
import org.apache.camel.component.servicenow.auth.AuthenticationRequestFilter;
import org.apache.camel.support.jsse.SSLContextParameters;
import org.apache.camel.util.ObjectHelper;
import org.apache.cxf.configuration.jsse.TLSClientParameters;
import org.apache.cxf.configuration.security.ProxyAuthorizationPolicy;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public final class ServiceNowClient {
    private static final Logger LOGGER = LoggerFactory.getLogger(ServiceNowClient.class);

    private final ServiceNowConfiguration configuration;
    private final WebClient client;

    public ServiceNowClient(CamelContext camelContext, ServiceNowConfiguration configuration) {
        this.configuration = configuration;
        this.client = WebClient.create(
                configuration.getApiUrl(),
                Arrays.asList(
                        new AuthenticationRequestFilter(configuration),
                        new JacksonJsonProvider(configuration.getOrCreateMapper())),
                true);

        configureRequestContext(client);
        configureTls(camelContext, configuration, client);
        configureHttpClientPolicy(configuration, client);
        configureProxyAuthorizationPolicy(configuration, client);
    }

    public ServiceNowClient types(MediaType type) {
        return types(type, type);
    }

    public ServiceNowClient types(MediaType accept, MediaType type) {
        client.accept(accept);
        client.type(type);
        return this;
    }

    public ServiceNowClient path(Object path) {
        if (ObjectHelper.isNotEmpty(path)) {
            client.path(path);
        }

        return this;
    }

    public ServiceNowClient type(MediaType ct) {
        client.type(ct);
        return this;
    }

    public ServiceNowClient type(String type) {
        client.type(type);
        return this;
    }

    public ServiceNowClient accept(MediaType... types) {
        client.accept(types);
        return this;
    }

    public ServiceNowClient accept(String... types) {
        client.accept(types);
        return this;
    }

    public ServiceNowClient query(String name, Object... values) {
        client.query(name, values);
        return this;
    }

    public ServiceNowClient queryF(String name, String format, Object... values) {
        client.query(name, String.format(format, values));
        return this;
    }

    public ServiceNowClient query(ServiceNowParam param, Message message) {
        Object value = param.getHeaderValue(message, configuration);
        if (value != null) {
            client.query(param.getId(), value);
        }

        return this;
    }

    public ServiceNowClient query(Class model) {
        if (model != null) {
            String name;
            String value;

            for (ServiceNowSysParm parm : model.getAnnotationsByType(ServiceNowSysParm.class)) {
                name = parm.name();
                value = parm.value();

                // SysParms defined on model have precedence and replace query param
                // with same name set via Message headers.
                if (ObjectHelper.isNotEmpty(name) && ObjectHelper.isNotEmpty(value)) {
                    LOGGER.debug("Replace query param {} with value {}", name, value);
                    client.replaceQueryParam(name, value);
                }
            }
        }

        return this;
    }

    public Response invoke(String httpMethod) throws Exception {
        return invoke(client, httpMethod, null);
    }

    public Response invoke(String httpMethod, Object body) throws Exception {
        return invoke(client, httpMethod, body);
    }

    public  T trasform(String httpMethod, Function function) throws Exception {
        return function.apply(invoke(client, httpMethod, null));
    }

    public  T trasform(String httpMethod, Object body, Function function) throws Exception {
        return function.apply(invoke(client, httpMethod, body));
    }

    public ServiceNowClient reset() {
        client.back(true);
        client.reset();
        client.resetQuery();

        return this;
    }

    // *******************************
    // Helpers
    // *******************************

    private Response invoke(WebClient client, String httpMethod, Object body) throws Exception {
        Response response = client.invoke(httpMethod, body);
        int code = response.getStatus();

        // Only ServiceNow known error status codes are mapped
        // See http://wiki.servicenow.com/index.php?title=REST_API#REST_Response_HTTP_Status_Codes
        switch (code) {
            case 200:
            case 201:
            case 204:
                // Success
                break;
            case 400:
            case 401:
            case 403:
            case 404:
            case 405:
            case 406:
            case 415:
                ServiceNowExceptionModel model = response.readEntity(ServiceNowExceptionModel.class);
                throw new ServiceNowException(
                        code,
                        model.getStatus(),
                        model.getError().get("message"),
                        model.getError().get("detail"));
            default:
                throw new ServiceNowException(
                        code,
                        response.readEntity(Map.class));
        }

        return response;
    }

    private static void configureRequestContext(
            WebClient client) {

        WebClient.getConfig(client)
                .getRequestContext()
                .put("org.apache.cxf.http.header.split", true);
    }

    private static void configureTls(
            CamelContext camelContext, ServiceNowConfiguration configuration, WebClient client) {

        SSLContextParameters sslContextParams = configuration.getSslContextParameters();
        if (sslContextParams != null) {
            HTTPConduit conduit = WebClient.getConfig(client).getHttpConduit();
            TLSClientParameters tlsClientParams = conduit.getTlsClientParameters();
            if (tlsClientParams == null) {
                tlsClientParams = new TLSClientParameters();
            }

            try {
                SSLContext sslContext = sslContextParams.createSSLContext(camelContext);
                tlsClientParams.setSSLSocketFactory(sslContext.getSocketFactory());

                conduit.setTlsClientParameters(tlsClientParams);
            } catch (IOException | GeneralSecurityException e) {
                throw RuntimeCamelException.wrapRuntimeCamelException(e);
            }
        }
    }

    private static void configureHttpClientPolicy(
            ServiceNowConfiguration configuration, WebClient client) {

        HTTPClientPolicy httpPolicy = configuration.getHttpClientPolicy();
        if (httpPolicy == null) {
            String host = configuration.getProxyHost();
            Integer port = configuration.getProxyPort();

            if (host != null && port != null) {
                httpPolicy = new HTTPClientPolicy();
                httpPolicy.setProxyServer(host);
                httpPolicy.setProxyServerPort(port);
            }
        }

        if (httpPolicy != null) {
            WebClient.getConfig(client).getHttpConduit().setClient(httpPolicy);
        }
    }

    private static void configureProxyAuthorizationPolicy(
            ServiceNowConfiguration configuration, WebClient client) {

        ProxyAuthorizationPolicy proxyPolicy = configuration.getProxyAuthorizationPolicy();
        if (proxyPolicy == null) {
            String username = configuration.getProxyUserName();
            String password = configuration.getProxyPassword();

            if (username != null && password != null) {
                proxyPolicy = new ProxyAuthorizationPolicy();
                proxyPolicy.setAuthorizationType("Basic");
                proxyPolicy.setUserName(username);
                proxyPolicy.setPassword(password);
            }
        }

        if (proxyPolicy != null) {
            WebClient.getConfig(client).getHttpConduit().setProxyAuthorization(proxyPolicy);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy