/* * Copyright (c) 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.camel; import javax.batch.api.listener.StepListener; import javax.batch.runtime.StepExecution; import javax.batch.runtime.context.StepContext; import javax.inject.Inject; import javax.inject.Named; import static org.jberet.camel.EventType.AFTER_STEP; import static org.jberet.camel.EventType.BEFORE_STEP; /** * An implementation of {@code javax.batch.api.listener.StepListener} that sends * step execution events to a Camel endpoint. Two types of events are sent: * <ul> * <li>{@value org.jberet.camel.EventType#BEFORE_STEP}: sent before a step execution * <li>{@value org.jberet.camel.EventType#AFTER_STEP}: sent after a step execution * </ul> * The body of the message sent is the current {@code StepExecution}. * Each message also contains a header to indicate the event type: * its key is {@value org.jberet.camel.EventType#KEY}, and value is either * {@value org.jberet.camel.EventType#BEFORE_STEP} or * {@value org.jberet.camel.EventType#AFTER_STEP}. * <p> * The target Camel endpoint is configured through batch property * {@code endpoint} in job XML. For example, * <pre> * <job id="camelStepListenerTest" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0"> * <step id="camelStepListenerTest.step1"> * <listeners> * <listener ref="camelStepListener"> * <properties> * <property name="endpoint" value="#{jobParameters['endpoint']}"/> * </properties> * </listener> * </listeners> * ... ... * </step> * </job> * </pre> * * @see CamelJobListener * @see CamelChunkListener * @since 1.3.0 */ @Named public class CamelStepListener extends CamelListenerBase implements StepListener { /** * Injection of {@code javax.batch.runtime.context.StepContext} by batch * runtime. */ @Inject protected StepContext stepContext; /** * {@inheritDoc} * <p> * This method sends {@value org.jberet.camel.EventType#BEFORE_STEP} * event to the configured Camel endpoint. The message contains a header: * <pre> * {@value org.jberet.camel.EventType#KEY}={@value org.jberet.camel.EventType#BEFORE_STEP} * </pre> * , and the message body is the current {@code javax.batch.runtime.StepExecution}. * * @throws Exception */ @Override public void beforeStep() throws Exception { sendBodyAndHeader(BEFORE_STEP); } /** * {@inheritDoc} * <p> * This method sends {@value org.jberet.camel.EventType#AFTER_STEP} * event to the configured Camel endpoint. The message contains a header: * <pre> * {@value org.jberet.camel.EventType#KEY}={@value org.jberet.camel.EventType#AFTER_STEP} * </pre> * , and the message body is the current {@code javax.batch.runtime.StepExecution}. * * @throws Exception */ @Override public void afterStep() throws Exception { sendBodyAndHeader(AFTER_STEP); } /** * Sends the step execution event message to the configured Camel endpoint. * The message has the current {@code StepExecution} as the body, and * a header to indicate the event type. * * @param headerValue either {@value org.jberet.camel.EventType#BEFORE_STEP} * or {@value org.jberet.camel.EventType#AFTER_STEP} */ protected void sendBodyAndHeader(final String headerValue) { final long jobExecutionId = jobContext.getExecutionId(); final long stepExecutionId = stepContext.getStepExecutionId(); StepExecution stepExecution = null; for (final StepExecution e : jobOperator.getStepExecutions(jobExecutionId)) { if (stepExecutionId == e.getStepExecutionId()) { stepExecution = e; break; } } producerTemplate.sendBodyAndHeader(endpoint, stepExecution, EventType.KEY, headerValue); } }