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 }