Package org.apache.activemq.store.jpa

Source Code of org.apache.activemq.store.jpa.JPATopicReferenceStore

/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.activemq.store.jpa;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.command.ActiveMQDestination;
import org.apache.activemq.command.MessageId;
import org.apache.activemq.command.SubscriptionInfo;
import org.apache.activemq.store.MessageRecoveryListener;
import org.apache.activemq.store.TopicReferenceStore;
import org.apache.activemq.store.jpa.model.StoredMessageReference;
import org.apache.activemq.store.jpa.model.StoredSubscription;
import org.apache.activemq.store.jpa.model.StoredSubscription.SubscriptionId;
import org.apache.activemq.util.IOExceptionSupport;

public class JPATopicReferenceStore extends JPAReferenceStore implements TopicReferenceStore {
    private Map<SubscriptionId, AtomicLong> subscriberLastMessageMap = new ConcurrentHashMap<SubscriptionId, AtomicLong>();

    public JPATopicReferenceStore(JPAPersistenceAdapter adapter, ActiveMQDestination destination) {
        super(adapter, destination);
    }

    public void acknowledge(ConnectionContext context, String clientId, String subscriptionName, MessageId messageId) throws IOException {
        EntityManager manager = adapter.beginEntityManager(context);
        try {
            StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
            ss.setLastAckedId(messageId.getBrokerSequenceId());
        } catch (Throwable e) {
            adapter.rollbackEntityManager(context, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(context, manager);
    }

    public void addSubsciption(SubscriptionInfo info, boolean retroactive) throws IOException {
        EntityManager manager = adapter.beginEntityManager(null);
        try {
            StoredSubscription ss = new StoredSubscription();
            ss.setClientId(info.getClientId());
            ss.setSubscriptionName(info.getSubcriptionName());
            ss.setDestination(destinationName);
            ss.setSelector(info.getSelector());
            ss.setSubscribedDestination(info.getSubscribedDestination().getQualifiedName());
            ss.setLastAckedId(-1);

            if (!retroactive) {
                Query query = manager.createQuery("select max(m.id) from StoredMessageReference m");
                Long rc = (Long)query.getSingleResult();
                if (rc != null) {
                    ss.setLastAckedId(rc);
                }
            }

            manager.persist(ss);
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
    }

    public void deleteSubscription(String clientId, String subscriptionName) throws IOException {
        EntityManager manager = adapter.beginEntityManager(null);
        try {
            StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
            manager.remove(ss);
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
    }

    private StoredSubscription findStoredSubscription(EntityManager manager, String clientId, String subscriptionName) {
        Query query = manager.createQuery("select ss from StoredSubscription ss " + "where ss.clientId=?1 " + "and ss.subscriptionName=?2 " + "and ss.destination=?3");
        query.setParameter(1, clientId);
        query.setParameter(2, subscriptionName);
        query.setParameter(3, destinationName);
        List<StoredSubscription> resultList = query.getResultList();
        if (resultList.isEmpty()) {
            return null;
        }
        return resultList.get(0);
    }

    public SubscriptionInfo[] getAllSubscriptions() throws IOException {
        SubscriptionInfo rc[];
        EntityManager manager = adapter.beginEntityManager(null);
        try {
            ArrayList<SubscriptionInfo> l = new ArrayList<SubscriptionInfo>();

            Query query = manager.createQuery("select ss from StoredSubscription ss where ss.destination=?1");
            query.setParameter(1, destinationName);
            for (StoredSubscription ss : (List<StoredSubscription>)query.getResultList()) {
                SubscriptionInfo info = new SubscriptionInfo();
                info.setClientId(ss.getClientId());
                info.setDestination(destination);
                info.setSelector(ss.getSelector());
                info.setSubscriptionName(ss.getSubscriptionName());
                info.setSubscribedDestination(toSubscribedDestination(ss));
                l.add(info);
            }

            rc = new SubscriptionInfo[l.size()];
            l.toArray(rc);
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
        return rc;
    }

    private ActiveMQDestination toSubscribedDestination(StoredSubscription ss) {
        if (ss.getSubscribedDestination() == null) {
            return null;
        }
        return ActiveMQDestination.createDestination(ss.getSubscribedDestination(), ActiveMQDestination.QUEUE_TYPE);
    }

    public int getMessageCount(String clientId, String subscriptionName) throws IOException {
        Long rc;
        EntityManager manager = adapter.beginEntityManager(null);
        try {
            Query query = manager.createQuery("select count(m) FROM StoredMessageReference m, StoredSubscription ss " + "where ss.clientId=?1 " + "and   ss.subscriptionName=?2 "
                                              + "and   ss.destination=?3 " + "and   m.destination=ss.destination and m.id > ss.lastAckedId");
            query.setParameter(1, clientId);
            query.setParameter(2, subscriptionName);
            query.setParameter(3, destinationName);
            rc = (Long)query.getSingleResult();
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
        return rc.intValue();
    }

    public SubscriptionInfo lookupSubscription(String clientId, String subscriptionName) throws IOException {
        SubscriptionInfo rc = null;
        EntityManager manager = adapter.beginEntityManager(null);
        try {
            StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
            if (ss != null) {
                rc = new SubscriptionInfo();
                rc.setClientId(ss.getClientId());
                rc.setDestination(destination);
                rc.setSelector(ss.getSelector());
                rc.setSubscriptionName(ss.getSubscriptionName());
                rc.setSubscribedDestination(toSubscribedDestination(ss));
            }
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
        return rc;
    }

    public void recoverNextMessages(String clientId, String subscriptionName, int maxReturned, MessageRecoveryListener listener) throws Exception {
        EntityManager manager = adapter.beginEntityManager(null);
        try {
            SubscriptionId id = new SubscriptionId();
            id.setClientId(clientId);
            id.setSubscriptionName(subscriptionName);
            id.setDestination(destinationName);

            AtomicLong last = subscriberLastMessageMap.get(id);
            if (last == null) {
                StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);
                last = new AtomicLong(ss.getLastAckedId());
                subscriberLastMessageMap.put(id, last);
            }
            final AtomicLong lastMessageId = last;

            Query query = manager.createQuery("select m from StoredMessageReference m where m.destination=?1 and m.id>?2 order by m.id asc");
            query.setParameter(1, destinationName);
            query.setParameter(2, lastMessageId.get());
            query.setMaxResults(maxReturned);
            int count = 0;
            for (StoredMessageReference m : (List<StoredMessageReference>)query.getResultList()) {
                MessageId mid = new MessageId(m.getMessageId());
                mid.setBrokerSequenceId(m.getId());
                listener.recoverMessageReference(mid);

                lastMessageId.set(m.getId());
                count++;
                if (count >= maxReturned) {
                    return;
                }
            }
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
    }

    public void recoverSubscription(String clientId, String subscriptionName, MessageRecoveryListener listener) throws Exception {
        EntityManager manager = adapter.beginEntityManager(null);
        try {

            StoredSubscription ss = findStoredSubscription(manager, clientId, subscriptionName);

            Query query = manager.createQuery("select m from StoredMessageReference m where m.destination=?1 and m.id>?2 order by m.id asc");
            query.setParameter(1, destinationName);
            query.setParameter(2, ss.getLastAckedId());
            for (StoredMessageReference m : (List<StoredMessageReference>)query.getResultList()) {
                MessageId mid = new MessageId(m.getMessageId());
                mid.setBrokerSequenceId(m.getId());
                listener.recoverMessageReference(mid);
            }
        } catch (Throwable e) {
            adapter.rollbackEntityManager(null, manager);
            throw IOExceptionSupport.create(e);
        }
        adapter.commitEntityManager(null, manager);
    }

    public void resetBatching(String clientId, String subscriptionName) {
        SubscriptionId id = new SubscriptionId();
        id.setClientId(clientId);
        id.setSubscriptionName(subscriptionName);
        id.setDestination(destinationName);
        subscriberLastMessageMap.remove(id);
    }

    public boolean acknowledgeReference(ConnectionContext context,
            String clientId, String subscriptionName, MessageId messageId)
            throws IOException {
        acknowledge(context, clientId, subscriptionName, messageId);
        return true;
    }

}
TOP

Related Classes of org.apache.activemq.store.jpa.JPATopicReferenceStore

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.