mirror of https://github.com/apache/activemq.git
https://issues.apache.org/jira/browse/AMQ-3422 - producer audit needs string rollback, plus don't fail if we cannot recover producer audit
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1153125 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
44ef96e6d3
commit
14755a19d5
|
@ -189,6 +189,17 @@ public class ActiveMQMessageAuditNoSync implements Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rollback(final String id) {
|
||||
String seed = IdGenerator.getSeedFromId(id);
|
||||
if (seed != null) {
|
||||
BitArrayBin bab = map.get(seed);
|
||||
if (bab != null) {
|
||||
long index = IdGenerator.getSequenceFromId(id);
|
||||
bab.setBit(index, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the message is in order
|
||||
|
|
|
@ -510,12 +510,11 @@ public class MessageDatabase extends ServiceSupport implements BrokerServiceAwar
|
|||
try {
|
||||
ObjectInputStream objectIn = new ObjectInputStream(audit.getAudit().newInput());
|
||||
metadata.producerSequenceIdTracker = (ActiveMQMessageAuditNoSync) objectIn.readObject();
|
||||
} catch (ClassNotFoundException cfe) {
|
||||
IOException ioe = new IOException("Failed to read producerAudit: " + cfe);
|
||||
ioe.initCause(cfe);
|
||||
throw ioe;
|
||||
return journal.getNextLocation(metadata.producerSequenceIdTrackerLocation);
|
||||
} catch (Exception e) {
|
||||
LOG.warn("Cannot recover message audit", e);
|
||||
return journal.getNextLocation(null);
|
||||
}
|
||||
return journal.getNextLocation(metadata.producerSequenceIdTrackerLocation);
|
||||
} else {
|
||||
// got no audit stored so got to recreate via replay from start of the journal
|
||||
return journal.getNextLocation(null);
|
||||
|
@ -546,7 +545,7 @@ public class MessageDatabase extends ServiceSupport implements BrokerServiceAwar
|
|||
MessageKeys keys = sd.orderIndex.remove(tx, sequenceId);
|
||||
sd.locationIndex.remove(tx, keys.location);
|
||||
sd.messageIdIndex.remove(tx, keys.messageId);
|
||||
metadata.producerSequenceIdTracker.rollback(new MessageId(keys.messageId));
|
||||
metadata.producerSequenceIdTracker.rollback(keys.messageId);
|
||||
undoCounter++;
|
||||
// TODO: do we need to modify the ack positions for the pub sub case?
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ public class IdGenerator {
|
|||
if (id != null) {
|
||||
int index = id.lastIndexOf(':');
|
||||
if (index > 0 && (index + 1) < id.length()) {
|
||||
result = id.substring(0, index + 1);
|
||||
result = id.substring(0, index);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
*/
|
||||
package org.apache.activemq;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
@ -119,4 +123,64 @@ public class ActiveMQMessageAuditTest extends TestCase {
|
|||
assertFalse(audit.isDuplicate(id));
|
||||
}
|
||||
}
|
||||
|
||||
public void testSerialization() throws Exception {
|
||||
ActiveMQMessageAuditNoSync audit = new ActiveMQMessageAuditNoSync();
|
||||
|
||||
byte[] bytes = serialize(audit);
|
||||
System.out.println(bytes.length);
|
||||
audit = recover(bytes);
|
||||
|
||||
List<MessageReference> list = new ArrayList<MessageReference>();
|
||||
|
||||
|
||||
for (int j = 0; j < 1000; j++) {
|
||||
ProducerId pid = new ProducerId();
|
||||
pid.setConnectionId("test");
|
||||
pid.setSessionId(0);
|
||||
pid.setValue(j);
|
||||
System.out.println("producer " + j);
|
||||
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
MessageId id = new MessageId();
|
||||
id.setProducerId(pid);
|
||||
id.setProducerSequenceId(i);
|
||||
ActiveMQMessage msg = new ActiveMQMessage();
|
||||
msg.setMessageId(id);
|
||||
list.add(msg);
|
||||
assertFalse(audit.isDuplicate(msg.getMessageId().toString()));
|
||||
|
||||
if (i % 100 == 0) {
|
||||
bytes = serialize(audit);
|
||||
System.out.println(bytes.length);
|
||||
audit = recover(bytes);
|
||||
}
|
||||
|
||||
if (i % 250 == 0) {
|
||||
for (MessageReference message : list) {
|
||||
audit.rollback(message.getMessageId().toString());
|
||||
}
|
||||
list.clear();
|
||||
bytes = serialize(audit);
|
||||
System.out.println(bytes.length);
|
||||
audit = recover(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected byte[] serialize(ActiveMQMessageAuditNoSync audit) throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oout = new ObjectOutputStream(baos);
|
||||
oout.writeObject(audit);
|
||||
oout.flush();
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
protected ActiveMQMessageAuditNoSync recover(byte[] bytes) throws Exception {
|
||||
ObjectInputStream objectIn = new ObjectInputStream(new ByteArrayInputStream(bytes));
|
||||
return (ActiveMQMessageAuditNoSync)objectIn.readObject();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue