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}