001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.dataset;
018
019 import java.util.concurrent.atomic.AtomicInteger;
020
021 import org.apache.camel.Component;
022 import org.apache.camel.Consumer;
023 import org.apache.camel.Exchange;
024 import org.apache.camel.Message;
025 import org.apache.camel.PollingConsumer;
026 import org.apache.camel.Processor;
027 import org.apache.camel.Service;
028 import org.apache.camel.component.mock.MockEndpoint;
029 import org.apache.camel.impl.EventDrivenPollingConsumer;
030 import org.apache.camel.util.ExchangeHelper;
031 import org.apache.camel.util.ObjectHelper;
032 import org.apache.commons.logging.Log;
033 import org.apache.commons.logging.LogFactory;
034
035 /**
036 * @version $Revision: 37863 $
037 */
038 public class DataSetEndpoint extends MockEndpoint implements Service {
039 private static final transient Log LOG = LogFactory.getLog(DataSetEndpoint.class);
040 private DataSet dataSet;
041 private AtomicInteger receivedCounter = new AtomicInteger();
042 private long produceDelay = -1;
043 private long consumeDelay = -1;
044 private long startTime;
045 private long preloadSize;
046
047 public DataSetEndpoint(String endpointUri, Component component, DataSet dataSet) {
048 super(endpointUri, component);
049 this.dataSet = dataSet;
050 }
051
052 public static void assertEquals(String description, Object expected, Object actual, Exchange exchange) {
053 if (!ObjectHelper.equal(expected, actual)) {
054 throw new AssertionError(description + " does not match. Expected: " + expected + " but was: " + actual + " on " + exchange + " with headers: " + exchange.getIn().getHeaders());
055 }
056 }
057
058 @Override
059 public PollingConsumer<Exchange> createPollingConsumer() throws Exception {
060 return new EventDrivenPollingConsumer<Exchange>(this);
061 }
062
063 @Override
064 public Consumer<Exchange> createConsumer(Processor processor) throws Exception {
065 return new DataSetConsumer(this, processor);
066 }
067
068 @Override
069 public void reset() {
070 super.reset();
071 receivedCounter.set(0);
072 }
073
074 @Override
075 public int getReceivedCounter() {
076 return receivedCounter.get();
077 }
078
079 /**
080 * Creates a message exchange for the given index in the {@link DataSet}
081 */
082 public Exchange createExchange(long messageIndex) throws Exception {
083 Exchange exchange = createExchange();
084 getDataSet().populateMessage(exchange, messageIndex);
085
086 Message in = exchange.getIn();
087 in.setHeader(DataSet.INDEX_HEADER, messageIndex);
088
089 return exchange;
090 }
091
092 @Override
093 protected void waitForCompleteLatch() throws InterruptedException {
094 // TODO lets do a much better version of this!
095 long size = getDataSet().getSize();
096 size *= 4000;
097 setResultWaitTime(size);
098 super.waitForCompleteLatch();
099 }
100
101 // Properties
102 //-------------------------------------------------------------------------
103
104 public DataSet getDataSet() {
105 return dataSet;
106 }
107
108 public void setDataSet(DataSet dataSet) {
109 this.dataSet = dataSet;
110 }
111
112 public long getPreloadSize() {
113 return preloadSize;
114 }
115
116 /**
117 * Sets how many messages should be preloaded (sent) before the route completes its initialisation
118 */
119 public void setPreloadSize(long preloadSize) {
120 this.preloadSize = preloadSize;
121 }
122
123 public long getConsumeDelay() {
124 return consumeDelay;
125 }
126
127 /**
128 * Allows a delay to be specified which causes consumers to pause - to simulate slow consumers
129 */
130 public void setConsumeDelay(long consumeDelay) {
131 this.consumeDelay = consumeDelay;
132 }
133
134 public long getProduceDelay() {
135 return produceDelay;
136 }
137
138 /**
139 * Allows a delay to be specified which causes producers to pause - to simpulate slow producers
140 */
141 public void setProduceDelay(long produceDelay) {
142 this.produceDelay = produceDelay;
143 }
144
145 // Implementation methods
146 //-------------------------------------------------------------------------
147
148 @Override
149 protected void performAssertions(Exchange actual) throws Exception {
150 if (startTime == 0) {
151 startTime = System.currentTimeMillis();
152 }
153 int receivedCount = receivedCounter.incrementAndGet();
154 long index = receivedCount - 1;
155 Exchange expected = createExchange(index);
156
157 // now lets assert that they are the same
158 if (LOG.isDebugEnabled()) {
159 LOG.debug("Received message: " + index + " = " + actual);
160 }
161
162 assertMessageExpected(index, expected, actual);
163
164 if (consumeDelay > 0) {
165 Thread.sleep(consumeDelay);
166 }
167
168 long group = getDataSet().getReportCount();
169 if (receivedCount % group == 0) {
170 reportProgress(actual, receivedCount);
171 }
172 }
173
174 protected void reportProgress(Exchange actual, int receivedCount) {
175 long time = System.currentTimeMillis();
176 long elapsed = time - startTime;
177 startTime = time;
178
179 LOG.info("Received: " + receivedCount + " messages so far. Last group took: " + elapsed + " millis");
180 }
181
182 protected void assertMessageExpected(long index, Exchange expected, Exchange actual) throws Exception {
183 long actualCounter = ExchangeHelper.getMandatoryHeader(actual, DataSet.INDEX_HEADER, Long.class);
184 assertEquals("Header: " + DataSet.INDEX_HEADER, index, actualCounter, actual);
185
186 getDataSet().assertMessageExpected(this, expected, actual, index);
187 }
188
189 public void start() throws Exception {
190 long size = getDataSet().getSize();
191 expectedMessageCount((int) size);
192 }
193
194 public void stop() throws Exception {
195 }
196 }