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

com.palantir.atlasdb.http.AtlasDbHttpClients Maven / Gradle / Ivy

There is a newer version: 0.1152.0
Show newest version
/*
 * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
 *
 * Licensed 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 com.palantir.atlasdb.http;

import com.google.common.annotations.VisibleForTesting;
import com.palantir.atlasdb.config.AuxiliaryRemotingParameters;
import com.palantir.atlasdb.config.ServerListConfig;
import com.palantir.atlasdb.http.v2.ConjureJavaRuntimeTargetFactory;
import com.palantir.atlasdb.http.v2.DialogueShimFactory;
import com.palantir.atlasdb.http.v2.FastFailoverProxy;
import com.palantir.atlasdb.util.AtlasDbMetrics;
import com.palantir.atlasdb.util.MetricsManager;
import com.palantir.common.proxy.ReplaceIfExceptionMatchingProxy;
import com.palantir.conjure.java.config.ssl.TrustContext;
import com.palantir.dialogue.Channel;
import com.palantir.refreshable.Refreshable;
import com.palantir.tritium.metrics.registry.TaggedMetricRegistry;
import java.net.SocketTimeoutException;
import java.time.Duration;
import java.util.Optional;
import java.util.function.Supplier;

public final class AtlasDbHttpClients {

    private AtlasDbHttpClients() {
        // Utility class
    }

    public static  T createProxy(
            Optional trustContext, String uri, Class type, AuxiliaryRemotingParameters parameters) {
        return wrapWithOkHttpBugHandling(type, () -> ConjureJavaRuntimeTargetFactory.DEFAULT
                .createProxy(trustContext, uri, type, parameters)
                .instance());
    }

    /**
     * Constructs an HTTP-invoking dynamic proxy for the specified type that will cycle through the list of supplied
     * endpoints after encountering an exception or connection failure, using the supplied SSL factory if it is
     * present. Also use the supplied the proxy selector to set the proxy on the clients if present.
     * 

* Failover will continue to cycle through the supplied endpoint list indefinitely. */ public static T createProxyWithFailover( MetricsManager metricsManager, ServerListConfig serverListConfig, Class type, AuxiliaryRemotingParameters parameters) { Supplier clientFactory = () -> instrument( metricsManager.getTaggedRegistry(), ConjureJavaRuntimeTargetFactory.DEFAULT.createProxyWithFailover(serverListConfig, type, parameters), type); return wrapWithOkHttpBugHandling(type, clientFactory); } public static T createLiveReloadingProxyWithFailover( MetricsManager metricsManager, Refreshable serverListConfigRefreshable, Class type, AuxiliaryRemotingParameters clientParameters) { Supplier clientFactory = () -> instrument( metricsManager.getTaggedRegistry(), ConjureJavaRuntimeTargetFactory.DEFAULT.createLiveReloadingProxyWithFailover( serverListConfigRefreshable, type, clientParameters), type); return wrapWithOkHttpBugHandling(type, clientFactory); } public static T createDialogueProxy(TaggedMetricRegistry registry, Class type, Channel channel) { return AtlasDbMetrics.instrumentWithTaggedMetrics( registry, type, createUninstrumentedDialogueProxy(type, channel)); } public static T createUninstrumentedDialogueProxy(Class type, Channel channel) { T proxy = DialogueShimFactory.create(type, channel); return FastFailoverProxy.newProxyInstance(type, () -> proxy); } private static T instrument( TaggedMetricRegistry taggedMetricRegistry, TargetFactory.InstanceAndVersion client, Class clazz) { return AtlasDbMetrics.instrumentWithTaggedMetrics(taggedMetricRegistry, clazz, client.instance()); } /** * Returns a proxy which replaces the underlying proxy if: * 1. We see a SocketTimeoutException * 2. At most once every 20 minutes */ private static T wrapWithOkHttpBugHandling(Class type, Supplier supplier) { return ReplaceIfExceptionMatchingProxy.create( type, supplier, Duration.ofMinutes(20), AtlasDbHttpClients::isPossiblyOkHttpTimeoutBug); } @VisibleForTesting static boolean isPossiblyOkHttpTimeoutBug(Throwable throwable) { if (throwable instanceof SocketTimeoutException) { return true; } Throwable cause = throwable.getCause(); return cause != null && isPossiblyOkHttpTimeoutBug(cause); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy