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