Package org.apache.qpid.server.store.berkeleydb

Examples of org.apache.qpid.server.store.berkeleydb.DatabaseVisitor


        moveContents(_oldMessageStore.getExchangesDb(), _newMessageStore.getExchangesDb(), "Exchange");

        final List<AMQShortString> topicExchanges = new ArrayList<AMQShortString>();
        final TupleBinding exchangeTB = new ExchangeTB();
       
        DatabaseVisitor exchangeListVisitor = new DatabaseVisitor()
        {          
            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                ExchangeRecord exchangeRec = (ExchangeRecord) exchangeTB.entryToObject(value);
                AMQShortString type = exchangeRec.getType();

                if (ExchangeDefaults.TOPIC_EXCHANGE_CLASS.equals(type))
                {
                    topicExchanges.add(exchangeRec.getNameShortString());
                }
            }
        };
        _oldMessageStore.visitExchanges(exchangeListVisitor);


        //Migrate _queueBindingsDb;
        _logger.info("Queue Bindings");
        moveContents(_oldMessageStore.getBindingsDb(), _newMessageStore.getBindingsDb(), "Queue Binding");

        //Inspect the bindings to gather a list of queues which are probably durable subscriptions, i.e. those
        //which have a colon in their name and are bound to the Topic exchanges above
        final List<AMQShortString> durableSubQueues = new ArrayList<AMQShortString>();
        final TupleBinding<BindingKey> bindingTB = _oldMessageStore.getBindingTupleBindingFactory().getInstance();
       
        DatabaseVisitor durSubQueueListVisitor = new DatabaseVisitor()
        {          
            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                BindingKey bindingRec = (BindingKey) bindingTB.entryToObject(key);
                AMQShortString queueName = bindingRec.getQueueName();
                AMQShortString exchangeName = bindingRec.getExchangeName();
               
                if (topicExchanges.contains(exchangeName) && queueName.asString().contains(":"))
                {
                    durableSubQueues.add(queueName);
                }
            }
        };
        _oldMessageStore.visitBindings(durSubQueueListVisitor);


        //Migrate _queueDb;
        _logger.info("Queues");

        // hold the list of existing queue names
        final List<AMQShortString> existingQueues = new ArrayList<AMQShortString>();

        final TupleBinding<QueueRecord> queueTupleBinding = _oldMessageStore.getQueueTupleBindingFactory().getInstance();

        DatabaseVisitor queueVisitor = new DatabaseVisitor()
        {
            public void visit(DatabaseEntry key, DatabaseEntry value) throws AMQStoreException
            {
                QueueRecord queueRec = (QueueRecord) queueTupleBinding.entryToObject(value);
                AMQShortString queueName = queueRec.getNameShortString();

                //if the queue name is in the gathered list then set its exclusivity true
                if (durableSubQueues.contains(queueName))
                {
                    _logger.info("Marking as possible DurableSubscription backing queue: " + queueName);
                    queueRec.setExclusive(true);
                }
               
                //The simple call to createQueue with the QueueRecord object is sufficient for a v2->v3 upgrade as
                //the extra 'exclusive' property in v3 will be defaulted to false in the record creation.
                _newMessageStore.createQueue(queueRec);

                _count++;
                existingQueues.add(queueName);
            }
        };
        _oldMessageStore.visitQueues(queueVisitor);

        logCount(queueVisitor.getVisitedCount(), "Queue");


        // Look for persistent messages stored for non-durable queues
        _logger.info("Checking for messages previously sent to non-durable queues");

        // track all message delivery to existing queues
        final HashSet<Long> queueMessages = new HashSet<Long>();

        // hold all non existing queues and their messages IDs
        final HashMap<String, HashSet<Long>> phantomMessageQueues = new HashMap<String, HashSet<Long>>();

        // delivery DB visitor to check message delivery and identify non existing queues
        final QueueEntryTB queueEntryTB = new QueueEntryTB();
        DatabaseVisitor messageDeliveryCheckVisitor = new DatabaseVisitor()
        {
            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                QueueEntryKey entryKey = (QueueEntryKey) queueEntryTB.entryToObject(key);
                Long messageId = entryKey.getMessageId();
                AMQShortString queueName = entryKey.getQueueName();
                if (!existingQueues.contains(queueName))
                {
                    String name = queueName.asString();
                    HashSet<Long> messages = phantomMessageQueues.get(name);
                    if (messages == null)
                    {
                        messages = new HashSet<Long>();
                        phantomMessageQueues.put(name, messages);
                    }
                    messages.add(messageId);
                    _count++;
                }
                else
                {
                    queueMessages.add(messageId);
                }
            }
        };
        _oldMessageStore.visitDelivery(messageDeliveryCheckVisitor);

        if (phantomMessageQueues.isEmpty())
        {
            _logger.info("No such messages were found");
        }
        else
        {
            _logger.info("Found " + messageDeliveryCheckVisitor.getVisitedCount()+ " such messages in total");

            for (Entry<String, HashSet<Long>> phantomQueue : phantomMessageQueues.entrySet())
            {
                String queueName = phantomQueue.getKey();
                HashSet<Long> messages = phantomQueue.getValue();

                _logger.info(MessageFormat.format("There are {0} messages which were previously delivered to non-durable queue ''{1}''",messages.size(), queueName));

                boolean createQueue;
                if(!_interactive)
                {
                    createQueue = true;
                    _logger.info("Running in batch-mode, marking queue as durable to ensure retention of the messages.");
                }
                else
                {
                    createQueue = userInteract("Do you want to make this queue durable?\n"
                                             + "NOTE: Answering No will result in these messages being discarded!");
                }

                if (createQueue)
                {
                    for (Long messageId : messages)
                    {
                        queueMessages.add(messageId);
                    }
                    AMQShortString name = new AMQShortString(queueName);
                    existingQueues.add(name);
                    QueueRecord record = new QueueRecord(name, null, false, null);
                    _newMessageStore.createQueue(record);
                }
            }
        }


        //Migrate _messageMetaDataDb;
        _logger.info("Message MetaData");
       
        final Database newMetaDataDB = _newMessageStore.getMetaDataDb();
        final TupleBinding<Object> oldMetaDataTupleBinding = _oldMessageStore.getMetaDataTupleBindingFactory().getInstance();
        final TupleBinding<Object> newMetaDataTupleBinding = _newMessageStore.getMetaDataTupleBindingFactory().getInstance();
       
        DatabaseVisitor metaDataVisitor = new DatabaseVisitor()
        {
            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                _count++;
                MessageMetaData metaData = (MessageMetaData) oldMetaDataTupleBinding.entryToObject(value);

                // get message id
                Long messageId = TupleBinding.getPrimitiveBinding(Long.class).entryToObject(key);

                // ONLY copy data if message is delivered to existing queue
                if (!queueMessages.contains(messageId))
                {
                    return;
                }
                DatabaseEntry newValue = new DatabaseEntry();
                newMetaDataTupleBinding.objectToEntry(metaData, newValue);
               
                newMetaDataDB.put(null, key, newValue);
            }
        };
        _oldMessageStore.visitMetaDataDb(metaDataVisitor);

        logCount(metaDataVisitor.getVisitedCount(), "Message MetaData");


        //Migrate _messageContentDb;
        _logger.info("Message Contents");
        final Database newContentDB = _newMessageStore.getContentDb();
       
        final TupleBinding<MessageContentKey> oldContentKeyTupleBinding = new MessageContentKeyTB_4();
        final TupleBinding<MessageContentKey> newContentKeyTupleBinding = new MessageContentKeyTB_5();
        final TupleBinding contentTB = new ContentTB();
       
        DatabaseVisitor contentVisitor = new DatabaseVisitor()
        {
            long _prevMsgId = -1; //Initialise to invalid value
            int _bytesSeenSoFar = 0;
           
            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                _count++;

                //determine the msgId of the current entry
                MessageContentKey_4 contentKey = (MessageContentKey_4) oldContentKeyTupleBinding.entryToObject(key);
                long msgId = contentKey.getMessageId();

                // ONLY copy data if message is delivered to existing queue
                if (!queueMessages.contains(msgId))
                {
                    return;
                }
                //if this is a new message, restart the byte offset count.
                if(_prevMsgId != msgId)
                {
                    _bytesSeenSoFar = 0;
                }

                //determine the content size
                ByteBuffer content = (ByteBuffer) contentTB.entryToObject(value);
                int contentSize = content.limit();

                //create the new key: id + previously seen data count
                MessageContentKey_5 newKey = new MessageContentKey_5(msgId, _bytesSeenSoFar);
                DatabaseEntry newKeyEntry = new DatabaseEntry();
                newContentKeyTupleBinding.objectToEntry(newKey, newKeyEntry);

                DatabaseEntry newValueEntry = new DatabaseEntry();
                contentTB.objectToEntry(content, newValueEntry);

                newContentDB.put(null, newKeyEntry, newValueEntry);

                _prevMsgId = msgId;
                _bytesSeenSoFar += contentSize;
            }
        };
        _oldMessageStore.visitContentDb(contentVisitor);

        logCount(contentVisitor.getVisitedCount(), "Message Content");


        //Migrate _deliveryDb;
        _logger.info("Delivery Records");
        final Database deliveryDb =_newMessageStore.getDeliveryDb();
        DatabaseVisitor deliveryDbVisitor = new DatabaseVisitor()
        {

            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                _count++;
View Full Code Here


     * @throws DatabaseException If there is a problem with the loading of the data
     */
    private void moveContents(Database oldDatabase, final Database newDatabase, String contentName) throws AMQException, DatabaseException
    {

        DatabaseVisitor moveVisitor = new DatabaseVisitor()
        {
            public void visit(DatabaseEntry key, DatabaseEntry value) throws DatabaseException
            {
                _count++;
                newDatabase.put(null, key, value);
            }
        };

        _oldMessageStore.visitDatabase(oldDatabase, moveVisitor);

        logCount(moveVisitor.getVisitedCount(), contentName);
    }
View Full Code Here

TOP

Related Classes of org.apache.qpid.server.store.berkeleydb.DatabaseVisitor

Copyright © 2018 www.massapicom. 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.