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 * Endpoint for DataSet. 037 * 038 * @version $Revision: 1279 $ 039 */ 040 public class DataSetEndpoint extends MockEndpoint implements Service { 041 private static final transient Log LOG = LogFactory.getLog(DataSetEndpoint.class); 042 private DataSet dataSet; 043 private AtomicInteger receivedCounter = new AtomicInteger(); 044 private long produceDelay = -1; 045 private long consumeDelay = -1; 046 private long startTime; 047 private long preloadSize; 048 049 public DataSetEndpoint(String endpointUri, Component component, DataSet dataSet) { 050 super(endpointUri, component); 051 this.dataSet = dataSet; 052 } 053 054 public DataSetEndpoint(String endpointUri, DataSet dataSet) { 055 super(endpointUri); 056 this.dataSet = dataSet; 057 } 058 059 public static void assertEquals(String description, Object expected, Object actual, Exchange exchange) { 060 if (!ObjectHelper.equal(expected, actual)) { 061 throw new AssertionError(description + " does not match. Expected: " + expected + " but was: " + actual + " on " + exchange + " with headers: " + exchange.getIn().getHeaders()); 062 } 063 } 064 065 @Override 066 public PollingConsumer<Exchange> createPollingConsumer() throws Exception { 067 return new EventDrivenPollingConsumer<Exchange>(this); 068 } 069 070 @Override 071 public Consumer<Exchange> createConsumer(Processor processor) throws Exception { 072 return new DataSetConsumer(this, processor); 073 } 074 075 @Override 076 public void reset() { 077 super.reset(); 078 receivedCounter.set(0); 079 } 080 081 @Override 082 public int getReceivedCounter() { 083 return receivedCounter.get(); 084 } 085 086 /** 087 * Creates a message exchange for the given index in the {@link DataSet} 088 */ 089 public Exchange createExchange(long messageIndex) throws Exception { 090 Exchange exchange = createExchange(); 091 getDataSet().populateMessage(exchange, messageIndex); 092 093 Message in = exchange.getIn(); 094 in.setHeader(DataSet.INDEX_HEADER, messageIndex); 095 096 return exchange; 097 } 098 099 @Override 100 protected void waitForCompleteLatch() throws InterruptedException { 101 // TODO lets do a much better version of this! 102 long size = getDataSet().getSize(); 103 size *= 4000; 104 setResultWaitTime(size); 105 super.waitForCompleteLatch(); 106 } 107 108 // Properties 109 //------------------------------------------------------------------------- 110 111 public DataSet getDataSet() { 112 return dataSet; 113 } 114 115 public void setDataSet(DataSet dataSet) { 116 this.dataSet = dataSet; 117 } 118 119 public long getPreloadSize() { 120 return preloadSize; 121 } 122 123 /** 124 * Sets how many messages should be preloaded (sent) before the route completes its initialisation 125 */ 126 public void setPreloadSize(long preloadSize) { 127 this.preloadSize = preloadSize; 128 } 129 130 public long getConsumeDelay() { 131 return consumeDelay; 132 } 133 134 /** 135 * Allows a delay to be specified which causes consumers to pause - to simulate slow consumers 136 */ 137 public void setConsumeDelay(long consumeDelay) { 138 this.consumeDelay = consumeDelay; 139 } 140 141 public long getProduceDelay() { 142 return produceDelay; 143 } 144 145 /** 146 * Allows a delay to be specified which causes producers to pause - to simulate slow producers 147 */ 148 public void setProduceDelay(long produceDelay) { 149 this.produceDelay = produceDelay; 150 } 151 152 // Implementation methods 153 //------------------------------------------------------------------------- 154 155 @Override 156 protected void performAssertions(Exchange actual) throws Exception { 157 if (startTime == 0) { 158 startTime = System.currentTimeMillis(); 159 } 160 int receivedCount = receivedCounter.incrementAndGet(); 161 long index = receivedCount - 1; 162 Exchange expected = createExchange(index); 163 164 // now lets assert that they are the same 165 if (LOG.isDebugEnabled()) { 166 LOG.debug("Received message: " + index + " = " + actual); 167 } 168 169 assertMessageExpected(index, expected, actual); 170 171 if (consumeDelay > 0) { 172 Thread.sleep(consumeDelay); 173 } 174 175 long group = getDataSet().getReportCount(); 176 if (receivedCount % group == 0) { 177 reportProgress(actual, receivedCount); 178 } 179 } 180 181 protected void reportProgress(Exchange actual, int receivedCount) { 182 long time = System.currentTimeMillis(); 183 long elapsed = time - startTime; 184 startTime = time; 185 186 LOG.info("Received: " + receivedCount + " messages so far. Last group took: " + elapsed + " millis"); 187 } 188 189 protected void assertMessageExpected(long index, Exchange expected, Exchange actual) throws Exception { 190 long actualCounter = ExchangeHelper.getMandatoryHeader(actual, DataSet.INDEX_HEADER, Long.class); 191 assertEquals("Header: " + DataSet.INDEX_HEADER, index, actualCounter, actual); 192 193 getDataSet().assertMessageExpected(this, expected, actual, index); 194 } 195 196 public void start() throws Exception { 197 long size = getDataSet().getSize(); 198 expectedMessageCount((int) size); 199 } 200 201 public void stop() throws Exception { 202 } 203 }