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

com.bazaarvoice.emodb.blob.client.AbstractBlobStoreClientFactory Maven / Gradle / Ivy

There is a newer version: 6.5.190
Show newest version
package com.bazaarvoice.emodb.blob.client;

import com.bazaarvoice.emodb.blob.api.AuthBlobStore;
import com.bazaarvoice.emodb.blob.api.BlobStore;
import com.bazaarvoice.emodb.client.EmoClient;
import com.bazaarvoice.emodb.client.EmoClientException;
import com.bazaarvoice.emodb.common.dropwizard.discovery.Payload;
import com.bazaarvoice.emodb.common.dropwizard.discovery.ServiceNames;
import com.bazaarvoice.emodb.common.json.JsonStreamingEOFException;
import com.bazaarvoice.ostrich.MultiThreadedServiceFactory;
import com.bazaarvoice.ostrich.ServiceEndPoint;
import com.bazaarvoice.ostrich.pool.ServicePoolBuilder;
import com.google.common.net.HttpHeaders;
import com.google.common.util.concurrent.ThreadFactoryBuilder;

import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

/**
 * Abstract parent class for blob store clients.  Subclasses are expected to create and configure an
 * {@link EmoClient} and then supply it via the constructor.
 */
abstract public class AbstractBlobStoreClientFactory implements MultiThreadedServiceFactory {

    private final String _clusterName;
    private final EmoClient _client;
    private ScheduledExecutorService _connectionManagementService;

    protected AbstractBlobStoreClientFactory(String clusterName, EmoClient client) {
        _clusterName = clusterName;
        _client = client;
    }

    @Override
    public String getServiceName() {
        return getServiceName(_clusterName);
    }

    protected static String getServiceName(String clusterName) {
        return ServiceNames.forNamespaceAndBaseServiceName(clusterName, BlobStoreClient.BASE_SERVICE_NAME);
    }

    @Override
    public void configure(ServicePoolBuilder servicePoolBuilder) {
        // Defaults are ok
    }

    @Override
    public AuthBlobStore create(ServiceEndPoint endPoint) {
        // If the caller didn't provide an explicit connection management service then create a default one now
        // to be shared by all clients generated by this factory.
        if (_connectionManagementService == null) {
            synchronized (this) {
                if (_connectionManagementService == null) {
                    _connectionManagementService = Executors.newSingleThreadScheduledExecutor(
                            new ThreadFactoryBuilder().setNameFormat("blob-store-client-connection-reaper-%d").build());
                }
            }
        }
        Payload payload = Payload.valueOf(endPoint.getPayload());
        return new BlobStoreClient(payload.getServiceUrl(), _client, _connectionManagementService);
    }

    protected void setConnectionManagementService(ScheduledExecutorService connectionManagementService) {
        _connectionManagementService = connectionManagementService;
    }

    @Override
    public void destroy(ServiceEndPoint endPoint, AuthBlobStore service) {
        // Nothing to do
    }

    @Override
    public boolean isRetriableException(Exception e) {
        return (e instanceof EmoClientException &&
                ((EmoClientException) e).getResponse().getStatus() >= 500) ||
                e instanceof JsonStreamingEOFException;
    }

    @Override
    public boolean isHealthy(ServiceEndPoint endPoint) {
        URI adminUrl = Payload.valueOf(endPoint.getPayload()).getAdminUrl();
        return _client.resource(adminUrl).path("/healthcheck")
                .header(HttpHeaders.CONNECTION, "close")
                .head().getStatus() == 200;
    }

    public MultiThreadedServiceFactory usingCredentials(final String apiKey) {
        final AbstractBlobStoreClientFactory authServiceFactory = this;

        return new MultiThreadedServiceFactory() {
            @Override
            public String getServiceName() {
                return authServiceFactory.getServiceName();
            }

            @Override
            public void configure(ServicePoolBuilder servicePoolBuilder) {
                // Defaults are ok
            }

            @Override
            public BlobStore create(ServiceEndPoint endPoint) {
                AuthBlobStore authBlobStore = authServiceFactory.create(endPoint);
                return new BlobStoreAuthenticatorProxy(authBlobStore, apiKey);
            }

            @Override
            public void destroy(ServiceEndPoint endPoint, BlobStore service) {
                // Nothing to do
            }

            @Override
            public boolean isHealthy(ServiceEndPoint endPoint) {
                return authServiceFactory.isHealthy(endPoint);
            }

            @Override
            public boolean isRetriableException(Exception exception) {
                return authServiceFactory.isRetriableException(exception);
            }
        };
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy