/* * Copyright (c) 2014-2016 Red Hat, Inc. and/or its affiliates. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cheng Fang - Initial API and implementation */ package org.jberet.support.io; import java.io.Serializable; import java.lang.reflect.Method; import java.util.Map; import javax.batch.api.BatchProperty; import javax.enterprise.inject.Instance; import javax.inject.Inject; import org.hornetq.api.core.HornetQException; import org.hornetq.api.core.SimpleString; import org.hornetq.api.core.TransportConfiguration; import org.hornetq.api.core.client.ClientSession; import org.hornetq.api.core.client.ClientSessionFactory; import org.hornetq.api.core.client.HornetQClient; import org.hornetq.api.core.client.SendAcknowledgementHandler; import org.hornetq.api.core.client.ServerLocator; import org.jberet.support._private.SupportLogger; import org.jberet.support._private.SupportMessages; import static org.jberet.support.io.ArtemisItemReaderWriterBase.*; /** * The base class for {@link org.jberet.support.io.HornetQItemReader} and {@link org.jberet.support.io.HornetQItemWriter}. * * @see HornetQItemReader * @see HornetQItemWriter * @since 1.1.0 * @deprecated As of 1.3.0, replaced by {@link ArtemisItemReaderWriterBase} */ @Deprecated public abstract class HornetQItemReaderWriterBase extends ItemReaderWriterBase { /** * This field holds an optional injection of HornetQ {@code ServerLocator}. When {@link #connectorFactoryParams} is * not specified, and {@link #sessionFactoryInstance} is not satisfied, this field will be queried to obtain an * instance of HornetQ {@code ServerLocator}. The application may implement a * {@code javax.enterprise.inject.Produces} method to satisfy this dependency injection. */ @Inject protected Instance<ServerLocator> serverLocatorInstance; /** * This field holds an optional injection of HornetQ {@code ClientSessionFactory}. If this injection is satisfied, * {@link #serverLocatorInstance} will be ignored. The application may implement a * {@code javax.enterprise.inject.Produces} method to satisfy this dependency injection. */ @Inject protected Instance<ClientSessionFactory> sessionFactoryInstance; /** * Key-value pairs to identify and configure HornetQ {@code org.hornetq.api.core.TransportConfiguration}, which is * used to create HornetQ {@code ServerLocator}. Optional property and defaults to null. When this property is * present, it will be used to create HornetQ {@code ServerLocator}, and the injection fields * {@link #serverLocatorInstance} and {@link #sessionFactoryInstance} will be ignored. Valid keys and values are: * <p> * <ul> * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#FACTORY_CLASS_KEY}, * the fully-qualified class name of a HornetQ connector factory, required if this property is present * <li>any param keys and values appropriate for the above-named HornetQ connector factory class * </ul> * <p> * An example of this property in job xml: * <p> * <property name="connectorFactoryParams" * value="factory-class=org.hornetq.core.remoting.impl.netty.NettyConnectorFactory, host=localhost, port=5445"/> */ @Inject @BatchProperty protected Map connectorFactoryParams; /** * Key-value pairs to configure HornetQ {@code ServerLocator}. Optional property and defaults to null. * Valid keys are: * <p> * <ul> * <li>HA: true or false (default), true if the {@code ServerLocator} receives topology updates from the cluster * <li>Properties in {@code ServerLocator} class that have corresponding setter method, starting with either * upper or lower case character * </ul> * <p> * See the current version of HornetQ {@code ServerLocator} javadoc for supported keys and values, e.g., * <a href="http://docs.jboss.org/hornetq/2.4.0.Final/docs/api/hornetq-client/org/hornetq/api/core/client/ServerLocator.html">ServerLocator</a> * <p> * An example of this property in job xml: * <p> * <property name="serverLocatorParams" value="HA=false, AckBatchSize=5, ProducerMaxRate=10, BlockOnAcknowledge=false, ConfirmationWindowSize=5"/> */ @Inject @BatchProperty protected Map serverLocatorParams; /** * Key-value pairs to identify and configure the target HornetQ queue. Required property. * <p> * The following keys are supported: * <p> * <ul> * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#QUEUE_ADDRESS_KEY}, required * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#QUEUE_DURABLE_KEY}, optional * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#QUEUE_FILTER_KEY}, optional * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#QUEUE_NAME_KEY}, optional * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#QUEUE_SHARED_KEY}, optional * <li>{@value org.jberet.support.io.ArtemisItemReaderWriterBase#QUEUE_TEMPORARY_KEY}, optional * </ul> * <p> * An example of {@code queueParams} property in job xml: * <p> * <property name="queueParams" value="address=example, durable=false"/> */ @Inject @BatchProperty protected Map queueParams; /** * The fully-qualified name of a class that implements {@code org.hornetq.api.core.client.SendAcknowledgementHandler}. * A SendAcknowledgementHandler notifies a client when an message sent asynchronously has been received by the server. * See current version of HornetQ documentation for details, e.g., * <a href="https://docs.jboss.org/hornetq/2.4.0.Final/docs/api/hornetq-client/org/hornetq/api/core/client/SendAcknowledgementHandler.html">SendAcknowledgementHandler</a> * <p> * An example {@code sendAcknowledgementHandler} property in job xml: * <p> * <property name="sendAcknowledgementHandler" value="org.jberet.support.io.HornetQReaderWriterTest$HornetQSendAcknowledgementHandler"/> */ @Inject @BatchProperty protected Class sendAcknowledgementHandler; protected SimpleString queueAddress; protected SimpleString queueName; protected ServerLocator serverLocator; protected ClientSessionFactory sessionFactory; protected ClientSession session; private boolean toCloseServerLocator; private boolean toCloseSessionFactory; public void open(final Serializable checkpoint) throws Exception { if (queueParams == null) { throw SupportMessages.MESSAGES.invalidReaderWriterProperty(null, null, "queueParams"); } queueAddress = SimpleString.toSimpleString((String) queueParams.get(QUEUE_ADDRESS_KEY)); queueName = SimpleString.toSimpleString((String) queueParams.get(QUEUE_NAME_KEY)); if (queueName == null) { queueName = queueAddress; } if (connectorFactoryParams != null) { final String connectorFactoryName = (String) connectorFactoryParams.get(NAME_KEY); if (connectorFactoryName == null) { throw SupportMessages.MESSAGES.invalidReaderWriterProperty(null, connectorFactoryParams.toString(), "connectorFactoryParams"); } connectorFactoryParams.remove(NAME_KEY); boolean withHA = false; if (serverLocatorParams != null) { if (serverLocatorParams.containsKey(SERVER_LOCATOR_HA_KEY)) { withHA = Boolean.parseBoolean((String) serverLocatorParams.get(SERVER_LOCATOR_HA_KEY)); if (serverLocatorParams.size() == 1) { serverLocatorParams = null; } else { serverLocatorParams.remove(SERVER_LOCATOR_HA_KEY); } } } if (withHA) { serverLocator = connectorFactoryParams == null ? HornetQClient.createServerLocatorWithHA(new TransportConfiguration(connectorFactoryName)) : HornetQClient.createServerLocatorWithHA(new TransportConfiguration(connectorFactoryName, connectorFactoryParams)); } else { serverLocator = connectorFactoryParams == null ? HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(connectorFactoryName)) : HornetQClient.createServerLocatorWithoutHA(new TransportConfiguration(connectorFactoryName, connectorFactoryParams)); } toCloseServerLocator = true; } else { if (sessionFactoryInstance.isUnsatisfied()) { serverLocator = serverLocatorInstance.get(); } else { sessionFactory = sessionFactoryInstance.get(); } } if (serverLocatorParams != null && serverLocator != null) { configureServerLocator(); sessionFactory = serverLocator.createSessionFactory(); toCloseSessionFactory = true; } session = sessionFactory.createSession(); if (sendAcknowledgementHandler != null) { session.setSendAcknowledgementHandler((SendAcknowledgementHandler) sendAcknowledgementHandler.newInstance()); } } public Serializable checkpointInfo() throws Exception { return null; } protected void configureServerLocator() throws Exception { for (final Object o : serverLocatorParams.keySet()) { final String key = (String) o; final String val = (String) serverLocatorParams.get(key); final String setterName = "set" + Character.toUpperCase(key.charAt(0)) + key.substring(1); final Method method = ServerLocator.class.getMethod(setterName); final Class<?> param1 = method.getParameterTypes()[0]; final Object[] args = new Object[1]; if (param1 == int.class) { args[0] = Integer.valueOf(val); } else if (param1 == String.class) { args[0] = val; } else if (param1 == boolean.class) { args[0] = Boolean.valueOf(val); } else if (param1 == long.class) { args[0] = Long.valueOf(val); } else if (param1 == double.class) { args[0] = Double.valueOf(val); } method.invoke(serverLocator, args); } } protected void close() { if (session != null) { try { session.close(); } catch (final HornetQException e) { SupportLogger.LOGGER.tracef(e, "Failed to close HornetQ client core session %s%n", session); } session = null; } if (sessionFactory != null && toCloseSessionFactory) { sessionFactory.close(); sessionFactory = null; } if (serverLocator != null && toCloseServerLocator) { serverLocator.close(); serverLocator = null; } } }