/**
*
* Copyright 2004 Hiram Chirino
*
* Licensed 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.activemq.store.jdbc;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import javax.jms.JMSException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.activemq.io.WireFormat;
import org.activemq.message.ActiveMQMessage;
import org.activemq.message.MessageAck;
import org.activemq.service.MessageIdentity;
import org.activemq.store.MessageStore;
import org.activemq.store.RecoveryListener;
import org.activemq.store.jdbc.JDBCAdapter.MessageListResultHandler;
import org.activemq.util.JMSExceptionHelper;
import org.activemq.util.LongSequenceGenerator;
/**
* @version $Revision: 1.1 $
*/
public class JDBCMessageStore implements MessageStore {
private static final Log log = LogFactory.getLog(JDBCMessageStore.class);
protected final WireFormat wireFormat;
protected final String destinationName;
protected final LongSequenceGenerator sequenceGenerator;
protected final JDBCAdapter adapter;
protected final JDBCPersistenceAdapter persistenceAdapter;
public JDBCMessageStore(JDBCPersistenceAdapter persistenceAdapter, JDBCAdapter adapter, WireFormat wireFormat, String destinationName) {
this.persistenceAdapter = persistenceAdapter;
this.adapter = adapter;
this.sequenceGenerator = adapter.getSequenceGenerator();
this.wireFormat = wireFormat;
this.destinationName = destinationName;
}
public void addMessage(ActiveMQMessage message) throws JMSException {
// Serialize the Message..
String messageID = message.getJMSMessageID();
byte data[];
try {
data = wireFormat.toBytes(message);
} catch (IOException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker message: " + messageID + " in container: " + e, e);
}
long seq=sequenceGenerator.getNextSequenceId();
// Get a connection and insert the message into the DB.
Connection c = null;
try {
c = persistenceAdapter.getConnection();
adapter.doAddMessage(c, seq, messageID, destinationName, data, message.getJMSExpiration());
} catch (SQLException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker message: " + messageID + " in container: " + e, e);
} finally {
persistenceAdapter.returnConnection(c);
}
MessageIdentity answer = message.getJMSMessageIdentity();
answer.setSequenceNumber(new Long(seq));
}
public ActiveMQMessage getMessage(MessageIdentity identity) throws JMSException {
long id;
try {
id = getMessageSequenceId(identity);
} catch (JMSException e1) {
return null;
}
// Get a connection and pull the message out of the DB
Connection c = null;
try {
c = persistenceAdapter.getConnection();
byte data[] = adapter.doGetMessage(c, id);
if( data==null )
return null;
ActiveMQMessage answer = (ActiveMQMessage) wireFormat.fromBytes(data);;
answer.setJMSMessageID(identity.getMessageID());
answer.setJMSMessageIdentity(identity);
return answer;
} catch (IOException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker message: " + identity.getMessageID() + " in container: " + e, e);
} catch (SQLException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker message: " + identity.getMessageID() + " in container: " + e, e);
} finally {
persistenceAdapter.returnConnection(c);
}
}
/**
* @param identity
* @return
* @throws JMSException
*/
protected long getMessageSequenceId(MessageIdentity identity) throws JMSException {
Object sequenceNumber = identity.getSequenceNumber();
if (sequenceNumber != null && sequenceNumber.getClass() == Long.class) {
return ((Long) sequenceNumber).longValue();
} else {
// Get a connection and pull the message out of the DB
Connection c = null;
try {
c = persistenceAdapter.getConnection();
Long rc = adapter.getMessageSequenceId(c, identity.getMessageID());
if (rc == null)
throw new JMSException("Could not locate message in database with message id: "
+ identity.getMessageID());
return rc.longValue();
} catch (SQLException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker message: " + identity.getMessageID()
+ " in container: " + e, e);
} finally {
persistenceAdapter.returnConnection(c);
}
}
}
public void removeMessage(MessageAck ack) throws JMSException {
long seq = getMessageSequenceId(ack.getMessageIdentity());
// Get a connection and remove the message from the DB
Connection c = null;
try {
c = persistenceAdapter.getConnection();
adapter.doRemoveMessage(c, seq);
} catch (SQLException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker message: " + ack.getMessageID() + " in container: " + e, e);
} finally {
persistenceAdapter.returnConnection(c);
}
}
public void recover(final RecoveryListener listener) throws JMSException {
// Get all the Message ids out of the database.
Connection c = null;
try {
c = persistenceAdapter.getConnection();
adapter.doRecover(c, destinationName, new MessageListResultHandler() {
public void onMessage(long seq, String messageID) throws JMSException {
listener.recoverMessage(new MessageIdentity(messageID, new Long(seq)));
}
});
} catch (SQLException e) {
throw JMSExceptionHelper.newJMSException("Failed to recover container. Reason: " + e, e);
} finally {
persistenceAdapter.returnConnection(c);
}
}
public void start() throws JMSException {
}
public void stop() throws JMSException {
}
/**
* @see org.activemq.store.MessageStore#removeAllMessages()
*/
public void removeAllMessages() throws JMSException {
// Get a connection and remove the message from the DB
Connection c = null;
try {
c = persistenceAdapter.getConnection();
adapter.doRemoveAllMessages(c, destinationName);
} catch (SQLException e) {
throw JMSExceptionHelper.newJMSException("Failed to broker remove all messages: " + e, e);
} finally {
persistenceAdapter.returnConnection(c);
}
}
}