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

com.microsoft.azure.servicebus.primitives.MiscRequestResponseOperationHandler Maven / Gradle / Ivy

There is a newer version: 3.6.7
Show newest version
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.microsoft.azure.servicebus.primitives;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import com.microsoft.azure.servicebus.TransactionContext;
import org.apache.qpid.proton.amqp.DescribedType;
import org.apache.qpid.proton.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.microsoft.azure.servicebus.rules.RuleDescription;

public final class MiscRequestResponseOperationHandler extends ClientEntity {
    private static final Logger TRACE_LOGGER = LoggerFactory.getLogger(MiscRequestResponseOperationHandler.class);
    
    private final Object requestResonseLinkCreationLock = new Object();
    private final String entityPath;
    private final MessagingEntityType entityType;
    private final MessagingFactory underlyingFactory;
    private RequestResponseLink requestResponseLink;
    private CompletableFuture requestResponseLinkCreationFuture;

    private MiscRequestResponseOperationHandler(MessagingFactory factory, String linkName, String entityPath, MessagingEntityType entityType) {
        super(linkName);

        this.underlyingFactory = factory;
        this.entityPath = entityPath;
        this.entityType = entityType;
    }

    @Deprecated
    public static CompletableFuture create(MessagingFactory factory, String entityPath) {
        return create(factory, entityPath, null);
    }

    public static CompletableFuture create(MessagingFactory factory, String entityPath, MessagingEntityType entityType) {
        MiscRequestResponseOperationHandler requestResponseOperationHandler = new MiscRequestResponseOperationHandler(factory, StringUtil.getShortRandomString(), entityPath, entityType);
        return CompletableFuture.completedFuture(requestResponseOperationHandler);
    }

    private void closeInternals() {
        this.closeRequestResponseLink();
    }

    @Override
    protected CompletableFuture onClose() {
        TRACE_LOGGER.trace("Closing MiscRequestResponseOperationHandler");
        this.closeInternals();
        return CompletableFuture.completedFuture(null);
    }

    private CompletableFuture createRequestResponseLink() {
        synchronized (this.requestResonseLinkCreationLock) {
            if (this.requestResponseLinkCreationFuture == null) {
                this.requestResponseLinkCreationFuture = new CompletableFuture();
                this.underlyingFactory.obtainRequestResponseLinkAsync(this.entityPath, this.entityType).handleAsync((rrlink, ex) -> {
                    if (ex == null) {
                        this.requestResponseLink = rrlink;
                        this.requestResponseLinkCreationFuture.complete(null);
                    } else {
                        Throwable cause = ExceptionUtil.extractAsyncCompletionCause(ex);
                        this.requestResponseLinkCreationFuture.completeExceptionally(cause);
                        // Set it to null so next call will retry rr link creation
                        synchronized (this.requestResonseLinkCreationLock) {
                            this.requestResponseLinkCreationFuture = null;
                        }
                    }
                    return null;
                }, MessagingFactory.INTERNAL_THREAD_POOL);
            }
            
            return this.requestResponseLinkCreationFuture;
        }
    }

    private void closeRequestResponseLink() {
        synchronized (this.requestResonseLinkCreationLock) {
            if (this.requestResponseLinkCreationFuture != null) {
                this.requestResponseLinkCreationFuture.thenRun(() -> {
                    this.underlyingFactory.releaseRequestResponseLink(this.entityPath);
                    this.requestResponseLink = null;
                });
                this.requestResponseLinkCreationFuture = null;
            }
        }
    }

    public CompletableFuture> getMessageSessionsAsync(Date lastUpdatedTime, int skip, int top, String lastSessionId) {
        TRACE_LOGGER.debug("Getting message sessions from entity '{}' with lastupdatedtime '{}', skip '{}', top '{}', lastsessionid '{}'", this.entityPath, lastUpdatedTime, skip, top, lastSessionId);
        return this.createRequestResponseLink().thenComposeAsync((v) -> {
            HashMap requestBodyMap = new HashMap();
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_LAST_UPDATED_TIME, lastUpdatedTime);
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_SKIP, skip);
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_TOP, top);
            if (lastSessionId != null) {
                requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_LAST_SESSION_ID, lastSessionId);
            }

            Message requestMessage = RequestResponseUtils.createRequestMessageFromPropertyBag(ClientConstants.REQUEST_RESPONSE_GET_MESSAGE_SESSIONS_OPERATION, requestBodyMap, Util.adjustServerTimeout(this.underlyingFactory.getOperationTimeout()));
            CompletableFuture responseFuture = this.requestResponseLink.requestAysnc(requestMessage, TransactionContext.NULL_TXN, this.underlyingFactory.getOperationTimeout());
            return responseFuture.thenComposeAsync((responseMessage) -> {
                CompletableFuture> returningFuture = new CompletableFuture>();
                int statusCode = RequestResponseUtils.getResponseStatusCode(responseMessage);
                if (statusCode == ClientConstants.REQUEST_RESPONSE_OK_STATUS_CODE) {
                    Map responseBodyMap = RequestResponseUtils.getResponseBody(responseMessage);
                    int responseSkip = (int) responseBodyMap.get(ClientConstants.REQUEST_RESPONSE_SKIP);
                    String[] sessionIds = (String[]) responseBodyMap.get(ClientConstants.REQUEST_RESPONSE_SESSIONIDS);
                    TRACE_LOGGER.debug("Received '{}' sessions from entity '{}'. Response skip '{}'", sessionIds.length, this.entityPath, responseSkip);
                    returningFuture.complete(new Pair<>(sessionIds, responseSkip));
                } else if (statusCode == ClientConstants.REQUEST_RESPONSE_NOCONTENT_STATUS_CODE
                            || (statusCode == ClientConstants.REQUEST_RESPONSE_NOTFOUND_STATUS_CODE && ClientConstants.SESSION_NOT_FOUND_ERROR.equals(RequestResponseUtils.getResponseErrorCondition(responseMessage)))) {
                    TRACE_LOGGER.debug("Received no sessions from entity '{}'.", this.entityPath);
                    returningFuture.complete(new Pair<>(new String[0], 0));
                } else {
                    // error response
                    TRACE_LOGGER.debug("Receiving sessions from entity '{}' failed with status code '{}'", this.entityPath, statusCode);
                    returningFuture.completeExceptionally(RequestResponseUtils.genereateExceptionFromResponse(responseMessage));
                }
                return returningFuture;
            }, MessagingFactory.INTERNAL_THREAD_POOL);
        }, MessagingFactory.INTERNAL_THREAD_POOL);
    }

    public CompletableFuture removeRuleAsync(String ruleName) {
        TRACE_LOGGER.debug("Removing rule '{}' from entity '{}'", ruleName, this.entityPath);
        return this.createRequestResponseLink().thenComposeAsync((v) -> {
            HashMap requestBodyMap = new HashMap();
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_RULENAME, ruleName);

            Message requestMessage = RequestResponseUtils.createRequestMessageFromPropertyBag(ClientConstants.REQUEST_RESPONSE_REMOVE_RULE_OPERATION, requestBodyMap, Util.adjustServerTimeout(this.underlyingFactory.getOperationTimeout()));
            CompletableFuture responseFuture = this.requestResponseLink.requestAysnc(requestMessage, TransactionContext.NULL_TXN, this.underlyingFactory.getOperationTimeout());
            return responseFuture.thenComposeAsync((responseMessage) -> {
                CompletableFuture returningFuture = new CompletableFuture();
                int statusCode = RequestResponseUtils.getResponseStatusCode(responseMessage);
                if (statusCode == ClientConstants.REQUEST_RESPONSE_OK_STATUS_CODE) {
                    TRACE_LOGGER.debug("Removed rule '{}' from entity '{}'", ruleName, this.entityPath);
                    returningFuture.complete(null);
                } else {
                    // error response
                    TRACE_LOGGER.info("Removing rule '{}' from entity '{}' failed with status code '{}'", ruleName, this.entityPath, statusCode);
                    returningFuture.completeExceptionally(RequestResponseUtils.genereateExceptionFromResponse(responseMessage));
                }
                return returningFuture;
            }, MessagingFactory.INTERNAL_THREAD_POOL);
        }, MessagingFactory.INTERNAL_THREAD_POOL);
    }

    public CompletableFuture addRuleAsync(RuleDescription ruleDescription) {
        TRACE_LOGGER.debug("Adding rule '{}' to entity '{}'", ruleDescription.getName(), this.entityPath);
        return this.createRequestResponseLink().thenComposeAsync((v) -> {
            HashMap requestBodyMap = new HashMap();
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_RULENAME, ruleDescription.getName());
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_RULEDESCRIPTION, RequestResponseUtils.encodeRuleDescriptionToMap(ruleDescription));

            Message requestMessage = RequestResponseUtils.createRequestMessageFromPropertyBag(ClientConstants.REQUEST_RESPONSE_ADD_RULE_OPERATION, requestBodyMap, Util.adjustServerTimeout(this.underlyingFactory.getOperationTimeout()));
            CompletableFuture responseFuture = this.requestResponseLink.requestAysnc(requestMessage, TransactionContext.NULL_TXN, this.underlyingFactory.getOperationTimeout());
            return responseFuture.thenComposeAsync((responseMessage) -> {
                CompletableFuture returningFuture = new CompletableFuture();
                int statusCode = RequestResponseUtils.getResponseStatusCode(responseMessage);
                if (statusCode == ClientConstants.REQUEST_RESPONSE_OK_STATUS_CODE) {
                    TRACE_LOGGER.debug("Added rule '{}' to entity '{}'", ruleDescription.getName(), this.entityPath);
                    returningFuture.complete(null);
                } else {
                    // error response
                    TRACE_LOGGER.info("Adding rule '{}' to entity '{}' failed with status code '{}'", ruleDescription.getName(), this.entityPath, statusCode);
                    returningFuture.completeExceptionally(RequestResponseUtils.genereateExceptionFromResponse(responseMessage));
                }
                return returningFuture;
            }, MessagingFactory.INTERNAL_THREAD_POOL);
        }, MessagingFactory.INTERNAL_THREAD_POOL);
    }

    public CompletableFuture> getRulesAsync(int skip, int top) {
        TRACE_LOGGER.debug("Fetching rules for entity '{}'", this.entityPath);
        return this.createRequestResponseLink().thenComposeAsync((v) -> {
            HashMap requestBodyMap = new HashMap();
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_SKIP, skip);
            requestBodyMap.put(ClientConstants.REQUEST_RESPONSE_TOP, top);

            Message requestMessage = RequestResponseUtils.createRequestMessageFromPropertyBag(
                    ClientConstants.REQUEST_RESPONSE_GET_RULES_OPERATION,
                    requestBodyMap,
                    Util.adjustServerTimeout(this.underlyingFactory.getOperationTimeout()));
            CompletableFuture responseFuture = this.requestResponseLink.requestAysnc(requestMessage, TransactionContext.NULL_TXN, this.underlyingFactory.getOperationTimeout());
            return responseFuture.thenComposeAsync((responseMessage) -> {
                CompletableFuture> returningFuture = new CompletableFuture<>();

                Collection rules = new ArrayList();
                int statusCode = RequestResponseUtils.getResponseStatusCode(responseMessage);
                if (statusCode == ClientConstants.REQUEST_RESPONSE_OK_STATUS_CODE) {
                    Map responseBodyMap = RequestResponseUtils.getResponseBody(responseMessage);
                    ArrayList rulesMap = (ArrayList) responseBodyMap.get(ClientConstants.REQUEST_RESPONSE_RULES);
                    for (Map ruleMap : rulesMap) {
                        DescribedType ruleDescription = (DescribedType) ruleMap.getOrDefault("rule-description", null);
                        rules.add(RequestResponseUtils.decodeRuleDescriptionMap(ruleDescription));
                    }

                    TRACE_LOGGER.debug("Fetched {} rules from entity '{}'", rules.size(), this.entityPath);
                    returningFuture.complete(rules);
                } else if (statusCode == ClientConstants.REQUEST_RESPONSE_NOCONTENT_STATUS_CODE) {
                    returningFuture.complete(rules);
                } else {
                    // error response
                    TRACE_LOGGER.info("Fetching rules for entity '{}' failed with status code '{}'", this.entityPath, statusCode);
                    returningFuture.completeExceptionally(RequestResponseUtils.genereateExceptionFromResponse(responseMessage));
                }

                return returningFuture;
            }, MessagingFactory.INTERNAL_THREAD_POOL);
        }, MessagingFactory.INTERNAL_THREAD_POOL);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy