Package com.sun.xml.ws.rx.mc.runtime

Source Code of com.sun.xml.ws.rx.mc.runtime.ResponseStorage

/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2010-2013 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License").  You
* may not use this file except in compliance with the License.  You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt.  See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license."  If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above.  However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
package com.sun.xml.ws.rx.mc.runtime;

import com.sun.istack.NotNull;
import com.sun.istack.logging.Logger;
import com.sun.xml.ws.api.ha.HaInfo;
import com.sun.xml.ws.api.ha.HighAvailabilityProvider;
import com.sun.xml.ws.commons.ha.HaContext;
import com.sun.xml.ws.commons.ha.StickyKey;
import com.sun.xml.ws.rx.ha.HighlyAvailableMap;
import com.sun.xml.ws.rx.ha.HighlyAvailableMap.StickyReplicationManager;
import com.sun.xml.ws.rx.ha.ReplicationManager;
import com.sun.xml.ws.rx.mc.localization.LocalizationMessages;
import com.sun.xml.ws.rx.message.jaxws.JaxwsMessage;
import com.sun.xml.ws.rx.message.jaxws.JaxwsMessage.JaxwsMessageState;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import org.glassfish.ha.store.api.BackingStore;
import org.glassfish.ha.store.api.BackingStoreFactory;

final class ResponseStorage {

    private static final Logger LOGGER = Logger.getLogger(ResponseStorage.class);

    private static final class PendingMessageDataReplicationManager implements ReplicationManager<String, JaxwsMessage> {

        private final BackingStore<StickyKey, JaxwsMessageState> messageStateStore;
        private final String loggerProlog;

        public PendingMessageDataReplicationManager(final String endpointUid) {
            this.messageStateStore = HighAvailabilityProvider.INSTANCE.createBackingStore(
                    HighAvailabilityProvider.INSTANCE.getBackingStoreFactory(HighAvailabilityProvider.StoreType.IN_MEMORY),
                    endpointUid + "_MC_PENDING_MESSAGE_DATA_STORE",
                    StickyKey.class,
                    JaxwsMessageState.class);

            this.loggerProlog = "[MC message data manager endpointUid: " + endpointUid + "]: ";

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Created pending message backing store");
            }
        }

        public JaxwsMessage load(final String key) {
            final JaxwsMessageState state = HighAvailabilityProvider.loadFrom(messageStateStore, new StickyKey(key), null);

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Message state loaded from pending message backing store for key [" + key + "]: " + ((state == null) ? null : state.toString()));
            }

            final JaxwsMessage message = (state == null) ? null : state.toMessage();

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Message state converted to a pending message: " + ((message == null) ? null : message.toString()));
            }
            return message;
        }

        public void save(final String key, final JaxwsMessage value, final boolean isNew) {
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Sending for replication pending message with a key [" + key + "]: " + value.toString() + ", isNew=" + isNew);
            }

            JaxwsMessageState state = value.getState();
            HaInfo haInfo = HaContext.currentHaInfo();
            if (haInfo != null) {
                if (LOGGER.isLoggable(Level.FINER)) {
                    LOGGER.finer(loggerProlog + "Existing HaInfo found, using it for pending message state replication: " + HaContext.asString(haInfo));
                }

                HaContext.udpateReplicaInstance(HighAvailabilityProvider.saveTo(messageStateStore, new StickyKey(key, haInfo.getKey()), state, isNew));
            } else {
                final StickyKey stickyKey = new StickyKey(key);
                final String replicaId = HighAvailabilityProvider.saveTo(messageStateStore, stickyKey, state, isNew);

                haInfo = new HaInfo(stickyKey.getHashKey(), replicaId, false);
                HaContext.updateHaInfo(haInfo);
                if (LOGGER.isLoggable(Level.FINER)) {
                    LOGGER.finer(loggerProlog + "No HaInfo found, created new after pending message state replication: " + HaContext.asString(haInfo));
                }
            }
        }

        public void remove(String key) {
            HighAvailabilityProvider.removeFrom(messageStateStore, new StickyKey(key));
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Removed pending message from the backing store for key [" + key + "]");
            }
        }

        public void close() {
            HighAvailabilityProvider.close(messageStateStore);
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Closed pending message backing store");
            }
        }

        public void destroy() {
            HighAvailabilityProvider.destroy(messageStateStore);
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer(loggerProlog + "Destroyed pending message backing store");
            }
        }
    }
    //
    private final ReentrantReadWriteLock storageLock = new ReentrantReadWriteLock();
    //
    private final HighlyAvailableMap<String, JaxwsMessage> pendingResponses;
    private final HighlyAvailableMap<String, PendingResponseIdentifiers> pendingResponseIdentifiers;
    private final String endpointUid;
    //

    public ResponseStorage(final String endpointUid) {
        StickyReplicationManager<String, PendingResponseIdentifiers> responseIdentifiersManager = null;
        PendingMessageDataReplicationManager responseManager = null;
        if (HighAvailabilityProvider.INSTANCE.isHaEnvironmentConfigured()) {
            final BackingStoreFactory bsf = HighAvailabilityProvider.INSTANCE.getBackingStoreFactory(HighAvailabilityProvider.StoreType.IN_MEMORY);

            responseIdentifiersManager = new StickyReplicationManager<String, PendingResponseIdentifiers>(
                    endpointUid + "_MC_PENDING_MESSAGE_IDENTIFIERS_MAP_MANAGER",
                    HighAvailabilityProvider.INSTANCE.createBackingStore(
                    bsf,
                    endpointUid + "_MC_PENDING_MESSAGE_IDENTIFIERS_STORE",
                    StickyKey.class,
                    PendingResponseIdentifiers.class));

            responseManager = new PendingMessageDataReplicationManager(endpointUid);
        }
        this.pendingResponseIdentifiers = HighlyAvailableMap.create(endpointUid + "_MC_PENDING_MESSAGE_IDENTIFIERS_MAP", responseIdentifiersManager);
        this.pendingResponses = HighlyAvailableMap.create(endpointUid + "_MC_PENDING_MESSAGE_DATA_MAP", responseManager);
        this.endpointUid = endpointUid;

        if (LOGGER.isLoggable(Level.FINER)) {
            LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Response storage initialized");
        }
    }

    void store(@NotNull JaxwsMessage response, @NotNull final String clientUID) {
        try {
            storageLock.writeLock().lock();

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Storing new response for client UID: " + clientUID);
            }

            pendingResponses.put(response.getCorrelationId(), response);

            PendingResponseIdentifiers clientResponses = pendingResponseIdentifiers.get(clientUID);
            if (clientResponses == null) {
                clientResponses = new PendingResponseIdentifiers();
            }
            if (!clientResponses.offer(response.getCorrelationId())) {
                LOGGER.severe(LocalizationMessages.WSMC_0104_ERROR_STORING_RESPONSE(clientUID));
            }
            pendingResponseIdentifiers.put(clientUID, clientResponses);
        } finally {
            storageLock.writeLock().unlock();
        }
    }

    public JaxwsMessage getPendingResponse(@NotNull final String clientUID) {
        try {
            storageLock.writeLock().lock();
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Retrieving stored pending response for client UID: " + clientUID);
            }

            PendingResponseIdentifiers clientResponses = pendingResponseIdentifiers.get(clientUID);
            if (clientResponses != null && !clientResponses.isEmpty()) {
                String messageId = clientResponses.poll();
                if (LOGGER.isLoggable(Level.FINER)) {
                    LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Found registered pending response with message id [" + messageId + "] for client UID: " + clientUID);
                }
                pendingResponseIdentifiers.put(clientUID, clientResponses);

                final JaxwsMessage response = pendingResponses.remove(messageId);
                if (LOGGER.isLoggable(Level.FINER)) {
                    LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Retrieved and removed pending response message data for message id [" + messageId + "]: " + ((response == null) ? null : response.toString()));
                }
                if (response == null) {
                    LOGGER.warning("[WSMC-HA] endpoint UID [" + endpointUid + "]: No penidng response message data found for message id [" + messageId + "]");
                }

                return response;
            }
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: No pedning responses found for client UID: " + clientUID);
            }
            return null;
        } finally {
            storageLock.writeLock().unlock();
        }
    }

    public boolean hasPendingResponse(@NotNull String clientUID) {
        try {
            storageLock.readLock().lock();
            PendingResponseIdentifiers clientResponses = pendingResponseIdentifiers.get(clientUID);
            final boolean result = clientResponses != null && !clientResponses.isEmpty();

            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Pending responses avaliable for client UID [" + clientUID + "]: " + result);
            }

            return result;
        } finally {
            storageLock.readLock().unlock();
        }
    }

    void invalidateLocalCache() {
        if (LOGGER.isLoggable(Level.FINER)) {
            LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Invalidation local caches for the response storage");
        }
        pendingResponseIdentifiers.invalidateCache();
        pendingResponses.invalidateCache();
    }
   
    void dispose() {
        if (LOGGER.isLoggable(Level.FINER)) {
            LOGGER.finer("[WSMC-HA] endpoint UID [" + endpointUid + "]: Disposing the response storage");
        }
       
        pendingResponseIdentifiers.close();
        pendingResponseIdentifiers.destroy();
       
        pendingResponses.close();
        pendingResponses.destroy();
    }
}
TOP

Related Classes of com.sun.xml.ws.rx.mc.runtime.ResponseStorage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.