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