001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.activemq.store.memory;
018
019import java.io.File;
020import java.io.IOException;
021import java.util.HashSet;
022import java.util.Iterator;
023import java.util.Set;
024import java.util.concurrent.ConcurrentHashMap;
025
026import org.apache.activemq.broker.ConnectionContext;
027import org.apache.activemq.broker.scheduler.JobSchedulerStore;
028import org.apache.activemq.command.ActiveMQDestination;
029import org.apache.activemq.command.ActiveMQQueue;
030import org.apache.activemq.command.ActiveMQTopic;
031import org.apache.activemq.command.ProducerId;
032import org.apache.activemq.store.MessageStore;
033import org.apache.activemq.store.PersistenceAdapter;
034import org.apache.activemq.store.ProxyMessageStore;
035import org.apache.activemq.store.TopicMessageStore;
036import org.apache.activemq.store.TransactionStore;
037import org.apache.activemq.usage.SystemUsage;
038import org.slf4j.Logger;
039import org.slf4j.LoggerFactory;
040
041/**
042 * @org.apache.xbean.XBean
043 *
044 */
045public class MemoryPersistenceAdapter implements PersistenceAdapter {
046    private static final Logger LOG = LoggerFactory.getLogger(MemoryPersistenceAdapter.class);
047
048    MemoryTransactionStore transactionStore;
049    ConcurrentHashMap<ActiveMQDestination, TopicMessageStore> topics = new ConcurrentHashMap<ActiveMQDestination, TopicMessageStore>();
050    ConcurrentHashMap<ActiveMQDestination, MessageStore> queues = new ConcurrentHashMap<ActiveMQDestination, MessageStore>();
051    private boolean useExternalMessageReferences;
052
053    @Override
054    public Set<ActiveMQDestination> getDestinations() {
055        Set<ActiveMQDestination> rc = new HashSet<ActiveMQDestination>(queues.size() + topics.size());
056        for (Iterator<ActiveMQDestination> iter = queues.keySet().iterator(); iter.hasNext();) {
057            rc.add(iter.next());
058        }
059        for (Iterator<ActiveMQDestination> iter = topics.keySet().iterator(); iter.hasNext();) {
060            rc.add(iter.next());
061        }
062        return rc;
063    }
064
065    public static MemoryPersistenceAdapter newInstance(File file) {
066        return new MemoryPersistenceAdapter();
067    }
068
069    @Override
070    public MessageStore createQueueMessageStore(ActiveMQQueue destination) throws IOException {
071        MessageStore rc = queues.get(destination);
072        if (rc == null) {
073            rc = new MemoryMessageStore(destination);
074            if (transactionStore != null) {
075                rc = transactionStore.proxy(rc);
076            }
077            queues.put(destination, rc);
078        }
079        return rc;
080    }
081
082    @Override
083    public TopicMessageStore createTopicMessageStore(ActiveMQTopic destination) throws IOException {
084        TopicMessageStore rc = topics.get(destination);
085        if (rc == null) {
086            rc = new MemoryTopicMessageStore(destination);
087            if (transactionStore != null) {
088                rc = transactionStore.proxy(rc);
089            }
090            topics.put(destination, rc);
091        }
092        return rc;
093    }
094
095    /**
096     * Cleanup method to remove any state associated with the given destination
097     *
098     * @param destination Destination to forget
099     */
100    @Override
101    public void removeQueueMessageStore(ActiveMQQueue destination) {
102        queues.remove(destination);
103    }
104
105    /**
106     * Cleanup method to remove any state associated with the given destination
107     *
108     * @param destination Destination to forget
109     */
110    @Override
111    public void removeTopicMessageStore(ActiveMQTopic destination) {
112        topics.remove(destination);
113    }
114
115    @Override
116    public TransactionStore createTransactionStore() throws IOException {
117        if (transactionStore == null) {
118            transactionStore = new MemoryTransactionStore(this);
119        }
120        return transactionStore;
121    }
122
123    @Override
124    public void beginTransaction(ConnectionContext context) {
125    }
126
127    @Override
128    public void commitTransaction(ConnectionContext context) {
129    }
130
131    @Override
132    public void rollbackTransaction(ConnectionContext context) {
133    }
134
135    @Override
136    public void start() throws Exception {
137    }
138
139    @Override
140    public void stop() throws Exception {
141    }
142
143    @Override
144    public long getLastMessageBrokerSequenceId() throws IOException {
145        return 0;
146    }
147
148    @Override
149    public void deleteAllMessages() throws IOException {
150        for (Iterator<TopicMessageStore> iter = topics.values().iterator(); iter.hasNext();) {
151            MemoryMessageStore store = asMemoryMessageStore(iter.next());
152            if (store != null) {
153                store.delete();
154            }
155        }
156        for (Iterator<MessageStore> iter = queues.values().iterator(); iter.hasNext();) {
157            MemoryMessageStore store = asMemoryMessageStore(iter.next());
158            if (store != null) {
159                store.delete();
160            }
161        }
162
163        if (transactionStore != null) {
164            transactionStore.delete();
165        }
166    }
167
168    public boolean isUseExternalMessageReferences() {
169        return useExternalMessageReferences;
170    }
171
172    public void setUseExternalMessageReferences(boolean useExternalMessageReferences) {
173        this.useExternalMessageReferences = useExternalMessageReferences;
174    }
175
176    protected MemoryMessageStore asMemoryMessageStore(Object value) {
177        if (value instanceof MemoryMessageStore) {
178            return (MemoryMessageStore)value;
179        }
180        if (value instanceof ProxyMessageStore) {
181            MessageStore delegate = ((ProxyMessageStore)value).getDelegate();
182            if (delegate instanceof MemoryMessageStore) {
183                return (MemoryMessageStore) delegate;
184            }
185        }
186        LOG.warn("Expected an instance of MemoryMessageStore but was: " + value);
187        return null;
188    }
189
190    /**
191     * @param usageManager The UsageManager that is controlling the broker's
192     *                memory usage.
193     */
194    @Override
195    public void setUsageManager(SystemUsage usageManager) {
196    }
197
198    @Override
199    public String toString() {
200        return "MemoryPersistenceAdapter";
201    }
202
203    @Override
204    public void setBrokerName(String brokerName) {
205    }
206
207    @Override
208    public void setDirectory(File dir) {
209    }
210
211    @Override
212    public File getDirectory(){
213        return null;
214    }
215
216    @Override
217    public void checkpoint(boolean sync) throws IOException {
218    }
219
220    @Override
221    public long size(){
222        return 0;
223    }
224
225    public void setCreateTransactionStore(boolean create) throws IOException {
226        if (create) {
227            createTransactionStore();
228        }
229    }
230
231    @Override
232    public long getLastProducerSequenceId(ProducerId id) {
233        // memory map does duplicate suppression
234        return -1;
235    }
236
237    @Override
238    public JobSchedulerStore createJobSchedulerStore() throws IOException, UnsupportedOperationException {
239        // We could eventuall implement an in memory scheduler.
240        throw new UnsupportedOperationException();
241    }
242}