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

com.microsoft.azure.documentdb.internal.directconnectivity.ReplicatedResourceClient Maven / Gradle / Ivy

/*
 * Copyright (c) Microsoft Corporation.  All rights reserved.
 */

package com.microsoft.azure.documentdb.internal.directconnectivity;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.concurrent.ExecutorService;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;

import com.microsoft.azure.documentdb.DocumentClientException;
import com.microsoft.azure.documentdb.internal.AuthorizationTokenProvider;
import com.microsoft.azure.documentdb.internal.DatabaseAccountConfigurationProvider;
import com.microsoft.azure.documentdb.internal.DocumentServiceRequest;
import com.microsoft.azure.documentdb.internal.HttpConstants;
import com.microsoft.azure.documentdb.internal.SessionContainer;

class ReplicatedResourceClient {
    static final boolean GLOBAL_STRONG_ENABLED = true;

    private SessionContainer sessionContainer;
    private ConsistencyReader consistencyReader;
    private ConsistencyWriter consistencyWriter;

    public ReplicatedResourceClient(GlobalAddressResolver globalAddressResolver,
                                    SessionContainer sessionContainer,
                                    TransportClient transportClient,
                                    DatabaseAccountConfigurationProvider databaseAccountConfigurationProvider,
                                    AuthorizationTokenProvider authorizationTokenProvider,
                                    ExecutorService executorService,
                                    boolean useMultipleWriteLocations) {
        this.sessionContainer = sessionContainer;
        this.consistencyReader = new ConsistencyReader(
                globalAddressResolver,
                this.sessionContainer,
                transportClient,
                databaseAccountConfigurationProvider,
                authorizationTokenProvider,
                executorService);
        this.consistencyWriter = new ConsistencyWriter(
                globalAddressResolver,
                this.sessionContainer,
                transportClient,
                databaseAccountConfigurationProvider,
                authorizationTokenProvider,
                executorService,
                useMultipleWriteLocations);
    }

    public StoreResponse invoke(DocumentServiceRequest request) throws DocumentClientException {
        try {
            switch (request.getOperationType()) {
                case Create:
                case Replace:
                case Delete:
                case ExecuteJavaScript:
                case Upsert:
                case Recreate:
                    return this.consistencyWriter.write(request);

                case Read:
                case ReadFeed:
                case Query:
                case SqlQuery:
                case Head:
                case HeadFeed:
                    return this.consistencyReader.read(request);
                default:
                    throw new IllegalStateException("Unsupported operation type");
            }
        } catch (DocumentClientException e) {
            if (e.getStatusCode() == HttpStatus.SC_GONE
                    && (e.getSubStatusCode() == null || e.getSubStatusCode() != HttpConstants.SubStatusCodes.COMPLETING_SPLIT)) {
                // Clear the session token, because the collection name might be reused.
                this.sessionContainer.clearToken(request);
            }
            if (request.getClientSideRequestStatistics() != null) {
                e.setClientSideRequestStatistics(request.getClientSideRequestStatistics());
            }
            throw e;
        }
    }

    static URI resolvePrimaryUri(DocumentServiceRequest request, AddressCache addressCache) throws DocumentClientException {
        AddressInformation[] replicaAddresses = resolveAddresses(request, addressCache);
        return resolvePrimaryUri(request, replicaAddresses);
    }

    static URI resolvePrimaryUri(DocumentServiceRequest request, AddressInformation[] replicaAddresses) throws DocumentClientException {
        try {
            if (request.getDefaultReplicaIndex() != null) {
                if (request.getDefaultReplicaIndex() >= 0
                        && request.getDefaultReplicaIndex() < replicaAddresses.length) {
                    return new URI(replicaAddresses[request.getDefaultReplicaIndex()].getPhysicalUri());
                }
            } else {
                for (int i = 0; i < replicaAddresses.length; i++) {
                    if (replicaAddresses[i].isPrimary()) {
                        return new URI(replicaAddresses[i].getPhysicalUri());
                    }
                }
            }
        } catch (URISyntaxException e) {
            throw new IllegalStateException("Invalid replica address");
        }

        throw new DocumentClientException(HttpStatus.SC_GONE, "The requested resource is no longer available at the server.");
    }

    static AddressInformation[] resolveAddresses(DocumentServiceRequest request, AddressCache addressCache) throws DocumentClientException {
        AddressInformation[] allResolvedAddresses = addressCache.resolve(request);
        ArrayList publicResolvedAddresses = new ArrayList();
        ArrayList internalResolvedAddresses = new ArrayList();

        for (int i = 0; i < allResolvedAddresses.length; i++) {
            AddressInformation address = allResolvedAddresses[i];
            if (!StringUtils.isEmpty(address.getPhysicalUri())) {
                if (address.isPublic()) {
                    publicResolvedAddresses.add(address);
                } else {
                    internalResolvedAddresses.add(address);
                }
            }
        }

        if (internalResolvedAddresses.size() > 0) {
            AddressInformation[] result = new AddressInformation[internalResolvedAddresses.size()];
            internalResolvedAddresses.toArray(result);
            return result;
        } else {
            AddressInformation[] result = new AddressInformation[publicResolvedAddresses.size()];
            publicResolvedAddresses.toArray(result);
            return result;
        }
    }

    String getLastReadAddress() {
        return consistencyReader.getLastReadAddress();
    }

    void setLastReadAddress(String lastReadAddress) {
        consistencyReader.setLastReadAddress(lastReadAddress);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy