1
2
3
4
5
6
7
8
9
10
11 package org.mule.tck.functional;
12
13 import org.mule.api.MuleEventContext;
14 import org.mule.api.lifecycle.Callable;
15 import org.mule.transformer.types.DataTypeFactory;
16 import org.mule.util.ClassUtils;
17 import org.mule.util.StringMessageUtils;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.concurrent.atomic.AtomicInteger;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26
27
28
29
30
31
32
33
34
35
36
37
38 public class FunctionalStreamingTestComponent implements Callable
39 {
40 protected transient Log logger = LogFactory.getLog(getClass());
41
42 private static AtomicInteger count = new AtomicInteger(0);
43 private int number = count.incrementAndGet();
44
45 public static final int STREAM_SAMPLE_SIZE = 4;
46 public static final int STREAM_BUFFER_SIZE = 4096;
47 private EventCallback eventCallback;
48 private String summary = null;
49 private long targetSize = -1;
50
51 public FunctionalStreamingTestComponent()
52 {
53 logger.debug("creating " + toString());
54 }
55
56 public void setEventCallback(EventCallback eventCallback, long targetSize)
57 {
58 logger.debug("setting callback: " + eventCallback + " in " + toString());
59 this.eventCallback = eventCallback;
60 this.targetSize = targetSize;
61 }
62
63 public String getSummary()
64 {
65 return summary;
66 }
67
68 public int getNumber()
69 {
70 return number;
71 }
72
73 public Object onCall(MuleEventContext context) throws Exception
74 {
75 InputStream in = context.getMessage().getPayload(DataTypeFactory.create(InputStream.class));
76 try
77 {
78 logger.debug("arrived at " + toString());
79 byte[] startData = new byte[STREAM_SAMPLE_SIZE];
80 long startDataSize = 0;
81 byte[] endData = new byte[STREAM_SAMPLE_SIZE];
82 long endDataSize = 0;
83 long endRingPointer = 0;
84 long streamLength = 0;
85 byte[] buffer = new byte[STREAM_BUFFER_SIZE];
86
87
88 long bytesRead = 0;
89 while (bytesRead >= 0)
90 {
91 bytesRead = read(in, buffer);
92 if (bytesRead > 0)
93 {
94 if (logger.isDebugEnabled())
95 {
96 logger.debug("read " + bytesRead + " bytes");
97 }
98
99 streamLength += bytesRead;
100 long startOfEndBytes = 0;
101 for (long i = 0; startDataSize < STREAM_SAMPLE_SIZE && i < bytesRead; ++i)
102 {
103 startData[(int) startDataSize++] = buffer[(int) i];
104 ++startOfEndBytes;
105 }
106 startOfEndBytes = Math.max(startOfEndBytes, bytesRead - STREAM_SAMPLE_SIZE);
107 for (long i = startOfEndBytes; i < bytesRead; ++i)
108 {
109 ++endDataSize;
110 endData[(int) (endRingPointer++ % STREAM_SAMPLE_SIZE)] = buffer[(int) i];
111 }
112 if (streamLength >= targetSize)
113 {
114 doCallback(startData, startDataSize,
115 endData, endDataSize, endRingPointer,
116 streamLength, context);
117 }
118 }
119 }
120
121 in.close();
122 }
123 catch (Exception e)
124 {
125 in.close();
126
127 e.printStackTrace();
128 if (logger.isDebugEnabled())
129 {
130 logger.debug(e);
131 }
132 throw e;
133 }
134
135 return null;
136 }
137
138 protected int read(InputStream in, byte[] buffer) throws IOException
139 {
140 return in.read(buffer);
141 }
142
143 private void doCallback(byte[] startData, long startDataSize,
144 byte[] endData, long endDataSize, long endRingPointer,
145 long streamLength, MuleEventContext context) throws Exception
146 {
147
148 StringBuffer result = new StringBuffer("Received stream");
149 result.append("; length: ");
150 result.append(streamLength);
151 result.append("; '");
152
153 for (long i = 0; i < startDataSize; ++i)
154 {
155 result.append((char) startData[(int) i]);
156 }
157
158 long endSize = Math.min(endDataSize, STREAM_SAMPLE_SIZE);
159 if (endSize > 0)
160 {
161 result.append("...");
162 for (long i = 0; i < endSize; ++i)
163 {
164 result.append((char) endData[(int) ((endRingPointer + i) % STREAM_SAMPLE_SIZE)]);
165 }
166 }
167 result.append("'");
168
169 summary = result.toString();
170
171 String msg = StringMessageUtils.getBoilerPlate("Message Received in service: "
172 + context.getFlowConstruct().getName() + ". " + summary
173 + "\n callback: " + eventCallback,
174 '*', 80);
175
176 logger.info(msg);
177
178 if (eventCallback != null)
179 {
180 eventCallback.eventReceived(context, this);
181 }
182 }
183
184 @Override
185 public String toString()
186 {
187 return ClassUtils.getSimpleName(getClass()) + "/" + number;
188 }
189
190 }