
org.jberet.support.io.ArtemisItemReader Maven / Gradle / Ivy
/*
* Copyright (c) 2016 Red Hat, Inc. and/or its affiliates.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.jberet.support.io;
import java.io.Serializable;
import org.apache.activemq.artemis.api.core.ActiveMQException;
import org.apache.activemq.artemis.api.core.client.ClientConsumer;
import org.apache.activemq.artemis.api.core.client.ClientMessage;
import org.jberet.support._private.SupportLogger;
import jakarta.batch.api.BatchProperty;
import jakarta.batch.api.chunk.ItemReader;
import jakarta.enterprise.context.Dependent;
import jakarta.inject.Inject;
import jakarta.inject.Named;
/**
* An implementation of {@code jakarta.batch.api.chunk.ItemReader} that reads data items from a Artemis address.
* It handles the following types of Artemis messages:
*
*
* - if {@link #beanType} is set to {@code org.apache.activemq.artemis.api.core.client.ClientMessage}, the incoming message
* is immediately returned as is from {@link #readItem()}
*
- if the message type is {@code org.apache.activemq.artemis.api.core.client.ClientMessage#TEXT_TYPE}, the string text is
* returned from {@link #readItem()};
*
- otherwise, a byte array is retrieved from the message body buffer, deserialize to an object, and returned
* from {@link #readItem()}
*
*
* This reader ends when either of the following occurs:
*
*
* - {@link #receiveTimeout} (in milliseconds) has elapsed when trying to receive a message from the destination;
*
- the size of the incoming message body is 0;
*
*
*
* @see ArtemisItemWriter
* @see ArtemisItemReaderWriterBase
* @see JmsItemReader
* @since 1.3.0
*/
@Named
@Dependent
public class ArtemisItemReader extends ArtemisItemReaderWriterBase implements ItemReader {
/**
* The number of milliseconds a Artemis {@code ClientConsumer} blocks until a message arrives. Optional property, and
* defaults to 0, which means it blocks indefinitely.
*/
@Inject
@BatchProperty
protected long receiveTimeout;
/**
* The fully-qualified class name of the data item to be returned from {@link #readItem()} method. Optional
* property and defaults to null. If it is specified, its valid value is:
*
*
* - {@code org.apache.activemq.artemis.api.core.client.ClientMessage}: an incoming Artemis message is returned as is.
*
*
* When this property is not specified, {@link #readItem()} method returns an object whose actual type is
* determined by the incoming Artemis message type.
*/
@Inject
@BatchProperty
protected Class beanType;
protected ClientConsumer consumer;
@Override
public void open(final Serializable checkpoint) throws Exception {
super.open(checkpoint);
consumer = session.createConsumer(queueName);
session.start();
}
@Override
public Object readItem() throws Exception {
final Object result;
final ClientMessage message = consumer.receive(receiveTimeout);
if (message == null) { //no more messages after receiveTimeout
return null;
}
final int bodySize = message.getBodySize();
if (bodySize == 0) {
return null;
}
if (beanType == ClientMessage.class) {
return message;
}
final byte messageType = message.getType();
final byte[] bytes = new byte[bodySize];
message.getBodyBuffer().readBytes(bytes);
if (messageType == ClientMessage.TEXT_TYPE) {
result = new String(bytes);
} else {
result = bytesToSerializableObject(bytes);
if (!skipBeanValidation) {
ItemReaderWriterBase.validate(result);
}
}
return result;
}
@Override
public void close() {
super.close();
if (consumer != null) {
try {
consumer.close();
} catch (final ActiveMQException e) {
SupportLogger.LOGGER.tracef(e, "Failed to close Artemis consumer %s%n", consumer);
}
consumer = null;
}
}
}