/*
* 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.artemis.core.persistence.impl.nullpm;
import javax.transaction.xa.Xid;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.activemq.artemis.api.core.Message;
import org.apache.activemq.artemis.api.core.Pair;
import org.apache.activemq.artemis.api.core.SimpleString;
import org.apache.activemq.artemis.core.io.IOCallback;
import org.apache.activemq.artemis.core.io.IOCriticalErrorListener;
import org.apache.activemq.artemis.core.io.SequentialFile;
import org.apache.activemq.artemis.core.journal.Journal;
import org.apache.activemq.artemis.core.journal.JournalLoadInformation;
import org.apache.activemq.artemis.core.paging.PageTransactionInfo;
import org.apache.activemq.artemis.core.paging.PagedMessage;
import org.apache.activemq.artemis.core.paging.PagingManager;
import org.apache.activemq.artemis.core.paging.PagingStore;
import org.apache.activemq.artemis.core.paging.cursor.PagePosition;
import org.apache.activemq.artemis.core.persistence.AddressBindingInfo;
import org.apache.activemq.artemis.core.persistence.GroupingInfo;
import org.apache.activemq.artemis.core.persistence.OperationContext;
import org.apache.activemq.artemis.core.persistence.QueueBindingInfo;
import org.apache.activemq.artemis.core.persistence.QueueStatus;
import org.apache.activemq.artemis.core.persistence.StorageManager;
import org.apache.activemq.artemis.core.persistence.config.PersistedAddressSetting;
import org.apache.activemq.artemis.core.persistence.config.PersistedRoles;
import org.apache.activemq.artemis.core.persistence.impl.PageCountPending;
import org.apache.activemq.artemis.core.postoffice.Binding;
import org.apache.activemq.artemis.core.postoffice.PostOffice;
import org.apache.activemq.artemis.core.replication.ReplicationManager;
import org.apache.activemq.artemis.core.server.LargeServerMessage;
import org.apache.activemq.artemis.core.server.MessageReference;
import org.apache.activemq.artemis.core.server.RouteContextList;
import org.apache.activemq.artemis.core.server.files.FileStoreMonitor;
import org.apache.activemq.artemis.core.server.group.impl.GroupBinding;
import org.apache.activemq.artemis.core.server.impl.AddressInfo;
import org.apache.activemq.artemis.core.server.impl.JournalLoader;
import org.apache.activemq.artemis.core.transaction.ResourceManager;
import org.apache.activemq.artemis.core.transaction.Transaction;
public class NullStorageManager implements StorageManager {
private final AtomicLong idSequence = new AtomicLong(0);
private volatile boolean started;
private final IOCriticalErrorListener ioCriticalErrorListener;
public NullStorageManager(IOCriticalErrorListener ioCriticalErrorListener) {
this.ioCriticalErrorListener = ioCriticalErrorListener;
}
public NullStorageManager() {
this(new IOCriticalErrorListener() {
@Override
public void onIOException(Throwable code, String message, SequentialFile file) {
code.printStackTrace();
}
});
}
@Override
public void criticalError(Throwable error) {
}
@Override
public long storeQueueStatus(long queueID, QueueStatus status) throws Exception {
return 0;
}
@Override
public void deleteQueueStatus(long recordID) throws Exception {
}
@Override
public void injectMonitor(FileStoreMonitor monitor) throws Exception {
}
private static final OperationContext dummyContext = new OperationContext() {
@Override
public void onError(final int errorCode, final String errorMessage) {
}
@Override
public void done() {
}
@Override
public void executeOnCompletion(IOCallback runnable, boolean storeOnly) {
runnable.done();
}
@Override
public void storeLineUp() {
}
@Override
public boolean waitCompletion(final long timeout) throws Exception {
return true;
}
@Override
public void waitCompletion() throws Exception {
}
@Override
public void replicationLineUp() {
}
@Override
public void replicationDone() {
}
@Override
public void pageSyncLineUp() {
}
@Override
public void pageSyncDone() {
}
@Override
public void executeOnCompletion(final IOCallback runnable) {
runnable.done();
}
};
@Override
public void deleteQueueBinding(long tx, final long queueBindingID) throws Exception {
}
@Override
public void addAddressBinding(long tx, AddressInfo addressInfo) throws Exception {
}
@Override
public void deleteAddressBinding(long tx, long addressBindingID) throws Exception {
}
@Override
public void commit(final long txID) throws Exception {
}
@Override
public JournalLoadInformation loadBindingJournal(final List<QueueBindingInfo> queueBindingInfos,
final List<GroupingInfo> groupingInfos,
final List<AddressBindingInfo> addressBindingInfos) throws Exception {
return new JournalLoadInformation();
}
@Override
public void prepare(final long txID, final Xid xid) throws Exception {
}
@Override
public void rollback(final long txID) throws Exception {
}
@Override
public void rollbackBindings(final long txID) throws Exception {
}
@Override
public void commitBindings(final long txID) throws Exception {
}
@Override
public void storeReference(final long queueID, final long messageID, final boolean last) throws Exception {
}
@Override
public void storeReferenceTransactional(final long txID, final long queueID, final long messageID) throws Exception {
}
@Override
public void storeAcknowledge(final long queueID, final long messageID) throws Exception {
}
@Override
public void storeAcknowledgeTransactional(final long txID,
final long queueID,
final long messageiD) throws Exception {
}
@Override
public void deleteMessage(final long messageID) throws Exception {
}
@Override
public void storeMessage(final Message message) throws Exception {
}
@Override
public void storeMessageTransactional(final long txID, final Message message) throws Exception {
}
@Override
public void updateScheduledDeliveryTime(final MessageReference ref) throws Exception {
}
@Override
public void updateScheduledDeliveryTimeTransactional(final long txID, final MessageReference ref) throws Exception {
}
@Override
public void storePageTransaction(final long txID, final PageTransactionInfo pageTransaction) throws Exception {
}
@Override
public void updateDeliveryCount(final MessageReference ref) throws Exception {
}
@Override
public void storeDuplicateID(final SimpleString address, final byte[] duplID, final long recordID) throws Exception {
}
@Override
public void storeDuplicateIDTransactional(final long txID,
final SimpleString address,
final byte[] duplID,
final long recordID) throws Exception {
}
@Override
public void updateDuplicateIDTransactional(final long txID,
final SimpleString address,
final byte[] duplID,
final long recordID) throws Exception {
}
@Override
public long storeHeuristicCompletion(final Xid xid, final boolean isCommit) throws Exception {
return generateID();
}
@Override
public void deleteHeuristicCompletion(final long txID) throws Exception {
}
@Override
public void addQueueBinding(final long tx, final Binding binding) throws Exception {
}
@Override
public LargeServerMessage createLargeMessage() {
return new NullStorageLargeServerMessage();
}
@Override
public LargeServerMessage createLargeMessage(final long id, final Message message) {
NullStorageLargeServerMessage largeMessage = new NullStorageLargeServerMessage();
largeMessage.copyHeadersAndProperties(message);
largeMessage.setMessageID(id);
return largeMessage;
}
@Override
public long generateID() {
long id = idSequence.getAndIncrement();
return id;
}
@Override
public long getCurrentID() {
return idSequence.get();
}
@Override
public synchronized void start() throws Exception {
if (started) {
throw new IllegalStateException("Already started");
}
started = true;
}
@Override
public synchronized void stop() throws Exception {
if (!started) {
throw new IllegalStateException("Not started");
}
idSequence.set(0);
started = false;
}
@Override
public synchronized boolean isStarted() {
return started;
}
@Override
public JournalLoadInformation loadMessageJournal(final PostOffice postOffice,
final PagingManager pagingManager,
final ResourceManager resourceManager,
final Map<Long, QueueBindingInfo> queueInfos,
final Map<SimpleString, List<Pair<byte[], Long>>> duplicateIDMap,
final Set<Pair<Long, Long>> pendingLargeMessages,
List<PageCountPending> pendingNonTXPageCounter,
final JournalLoader journalLoader) throws Exception {
return new JournalLoadInformation();
}
@Override
public void deleteDuplicateIDTransactional(final long txID, final long recordID) throws Exception {
}
@Override
public void deleteDuplicateID(final long recordID) throws Exception {
}
@Override
public void pageClosed(final SimpleString storeName, final int pageNumber) {
}
@Override
public void pageDeleted(final SimpleString storeName, final int pageNumber) {
}
@Override
public void pageWrite(final PagedMessage message, final int pageNumber) {
}
@Override
public void addGrouping(final GroupBinding groupBinding) throws Exception {
}
@Override
public void deleteGrouping(final long tx, final GroupBinding groupBinding) throws Exception {
}
@Override
public boolean waitOnOperations(final long timeout) throws Exception {
return true;
}
@Override
public void afterCompleteOperations(final IOCallback run) {
run.done();
}
@Override
public void afterStoreOperations(IOCallback run) {
run.done();
}
@Override
public void waitOnOperations() throws Exception {
}
@Override
public OperationContext getContext() {
return NullStorageManager.dummyContext;
}
@Override
public OperationContext newContext(final Executor executor) {
return NullStorageManager.dummyContext;
}
@Override
public OperationContext newSingleThreadContext() {
return NullStorageManager.dummyContext;
}
@Override
public void setContext(final OperationContext context) {
}
@Override
public void clearContext() {
}
@Override
public List<PersistedAddressSetting> recoverAddressSettings() throws Exception {
return Collections.emptyList();
}
@Override
public void storeAddressSetting(final PersistedAddressSetting addressSetting) throws Exception {
}
@Override
public List<PersistedRoles> recoverPersistedRoles() throws Exception {
return Collections.emptyList();
}
@Override
public void storeSecurityRoles(final PersistedRoles persistedRoles) throws Exception {
}
@Override
public void deleteAddressSetting(final SimpleString addressMatch) throws Exception {
}
@Override
public void deleteSecurityRoles(final SimpleString addressMatch) throws Exception {
}
@Override
public void deletePageTransactional(final long recordID) throws Exception {
}
@Override
public void updatePageTransaction(final long txID,
final PageTransactionInfo pageTransaction,
final int depage) throws Exception {
}
@Override
public void storeCursorAcknowledge(final long queueID, final PagePosition position) {
}
@Override
public void storeCursorAcknowledgeTransactional(final long txID, final long queueID, final PagePosition position) {
}
@Override
public void deleteCursorAcknowledgeTransactional(final long txID, final long ackID) throws Exception {
}
@Override
public void deleteCursorAcknowledge(long ackID) throws Exception {
}
@Override
public void storePageCompleteTransactional(long txID, long queueID, PagePosition position) throws Exception {
}
@Override
public void deletePageComplete(long ackID) throws Exception {
}
@Override
public long storePageCounter(final long txID, final long queueID, final long value) throws Exception {
return 0;
}
@Override
public long storePendingCounter(long queueID, long pageID, int inc) throws Exception {
return -1;
}
@Override
public void deleteIncrementRecord(final long txID, final long recordID) throws Exception {
}
@Override
public void deletePageCounter(final long txID, final long recordID) throws Exception {
}
@Override
public void deletePendingPageCounter(long txID, long recordID) throws Exception {
}
@Override
public long storePageCounterInc(final long txID, final long queueID, final int add) throws Exception {
return 0;
}
@Override
public long storePageCounterInc(final long queueID, final int add) throws Exception {
return 0;
}
@Override
public void commit(final long txID, final boolean lineUpContext) throws Exception {
}
@Override
public void lineUpContext() {
}
@Override
public void confirmPendingLargeMessageTX(final Transaction transaction,
final long messageID,
final long recordID) throws Exception {
}
@Override
public void confirmPendingLargeMessage(final long recordID) throws Exception {
}
@Override
public void stop(final boolean ioCriticalError, boolean sendFailover) throws Exception {
}
@Override
public Journal getBindingsJournal() {
return null;
}
@Override
public Journal getMessageJournal() {
return null;
}
@Override
public void startReplication(final ReplicationManager replicationManager,
final PagingManager pagingManager,
final String nodeID,
final boolean autoFailBack,
long initialReplicationSyncTimeout) throws Exception {
// no-op
}
@Override
public boolean addToPage(PagingStore store,
Message msg,
Transaction tx,
RouteContextList listCtx) throws Exception {
/**
* Exposing the read-lock here is an encapsulation violation done in order to keep the code
* simpler. The alternative would be to add a second method, say 'verifyPaging', to
* PagingStore.
* <p>
* Adding this second method would also be more surprise prone as it would require a certain
* calling order.
* <p>
* The reasoning is that exposing the lock is more explicit and therefore `less bad`.
*/
return store.page(msg, tx, listCtx, null);
}
@Override
public void stopReplication() {
// no-op
}
@Override
public SequentialFile createFileForLargeMessage(final long messageID, final LargeMessageExtension extension) {
throw new UnsupportedOperationException();
}
@Override
public void addBytesToLargeMessage(SequentialFile appendFile, long messageID, byte[] bytes) throws Exception {
// no-op
}
@Override
public void beforePageRead() throws Exception {
}
@Override
public void afterPageRead() throws Exception {
}
@Override
public ByteBuffer allocateDirectBuffer(final int size) {
return ByteBuffer.allocateDirect(size);
}
@Override
public void freeDirectBuffer(final ByteBuffer buffer) {
// We can just have hope on GC here :-)
}
@Override
public void storeID(final long journalID, final long id) throws Exception {
// no-op
}
@Override
public void readLock() {
// no-op
}
@Override
public void readUnLock() {
// no-op
}
@Override
public void persistIdGenerator() {
// no-op
}
@Override
public void deleteID(long journalD) throws Exception {
}
}