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

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

Go to download

Java library for Azure Service Bus. Please note, a newer package com.azure:azure-messaging-servicebus for Azure Service Bus is available as of December 2020. While this package will continue to receive critical bug fixes, we strongly encourage you to upgrade. Read the migration guide at https://aka.ms/azsdk/java/migrate/sb for more details.

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