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