001
014
015 package com.liferay.portal.resiliency.spi.agent;
016
017 import com.liferay.portal.kernel.io.BigEndianCodec;
018 import com.liferay.portal.kernel.io.Deserializer;
019 import com.liferay.portal.kernel.io.Serializer;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.nio.intraband.RegistrationReference;
023 import com.liferay.portal.kernel.nio.intraband.mailbox.MailboxException;
024 import com.liferay.portal.kernel.nio.intraband.mailbox.MailboxUtil;
025 import com.liferay.portal.kernel.resiliency.spi.agent.annotation.Direction;
026 import com.liferay.portal.kernel.resiliency.spi.agent.annotation.DistributedRegistry;
027 import com.liferay.portal.kernel.servlet.HttpHeaders;
028 import com.liferay.portal.kernel.util.StringUtil;
029 import com.liferay.portal.kernel.util.ThreadLocalDistributor;
030 import com.liferay.portal.kernel.util.ThreadLocalDistributorRegistry;
031
032 import java.io.EOFException;
033 import java.io.IOException;
034 import java.io.InputStream;
035 import java.io.OutputStream;
036 import java.io.Serializable;
037
038 import java.nio.ByteBuffer;
039
040 import java.util.ArrayList;
041 import java.util.Collections;
042 import java.util.Enumeration;
043 import java.util.HashMap;
044 import java.util.List;
045 import java.util.Map;
046
047 import javax.servlet.http.HttpServletRequest;
048 import javax.servlet.http.HttpSession;
049
050
053 public class SPIAgentSerializable implements Serializable {
054
055 public static Map<String, Serializable> extractDistributedRequestAttributes(
056 HttpServletRequest request, Direction direction) {
057
058 Map<String, Serializable> distributedRequestAttributes =
059 new HashMap<String, Serializable>();
060
061 Enumeration<String> enumeration = request.getAttributeNames();
062
063 while (enumeration.hasMoreElements()) {
064 String name = enumeration.nextElement();
065
066 if (DistributedRegistry.isDistributed(name, direction)) {
067 Object value = request.getAttribute(name);
068
069 if (value instanceof Serializable) {
070 distributedRequestAttributes.put(name, (Serializable)value);
071 }
072 else if (_log.isWarnEnabled()) {
073 _log.warn(
074 "Nonserializable distributed request attribute name " +
075 name + " with value " + value);
076 }
077 }
078 else if (_log.isDebugEnabled()) {
079 _log.debug(
080 "Nondistributed request attribute name " + name +
081 " with direction " + direction + " and value " +
082 request.getAttribute(name));
083 }
084 }
085
086 return distributedRequestAttributes;
087 }
088
089 public static Map<String, List<String>> extractRequestHeaders(
090 HttpServletRequest request) {
091
092 Map<String, List<String>> headers = new HashMap<String, List<String>>();
093
094 Enumeration<String> nameEnumeration = request.getHeaderNames();
095
096 while (nameEnumeration.hasMoreElements()) {
097 String headerName = nameEnumeration.nextElement();
098
099
100
101 if (StringUtil.equalsIgnoreCase(
102 HttpHeaders.ACCEPT_ENCODING, headerName)) {
103
104 continue;
105 }
106
107
108
109 if (StringUtil.equalsIgnoreCase(HttpHeaders.COOKIE, headerName)) {
110 continue;
111 }
112
113 Enumeration<String> valueEnumeration = request.getHeaders(
114 headerName);
115
116 if (valueEnumeration != null) {
117 List<String> values = new ArrayList<String>();
118
119 while (valueEnumeration.hasMoreElements()) {
120 values.add(valueEnumeration.nextElement());
121 }
122
123 if (values.isEmpty()) {
124 values = Collections.emptyList();
125 }
126
127 headers.put(StringUtil.toLowerCase(headerName), values);
128 }
129 }
130
131 if (headers.isEmpty()) {
132 headers = Collections.emptyMap();
133 }
134
135 return headers;
136 }
137
138 public static Map<String, Serializable> extractSessionAttributes(
139 HttpSession session) {
140
141 Map<String, Serializable> sessionAttributes =
142 new HashMap<String, Serializable>();
143
144 Enumeration<String> enumeration = session.getAttributeNames();
145
146 while (enumeration.hasMoreElements()) {
147 String name = enumeration.nextElement();
148 Object value = session.getAttribute(name);
149
150 if (value instanceof Serializable) {
151 sessionAttributes.put(name, (Serializable)value);
152 }
153 else if (_log.isWarnEnabled()) {
154 _log.warn(
155 "Nonserializable session attribute name " + name +
156 " with value " + value);
157 }
158 }
159
160 return sessionAttributes;
161 }
162
163 public static <T extends SPIAgentSerializable> T readFrom(
164 InputStream inputStream)
165 throws IOException {
166
167 byte[] data = new byte[8];
168 int length = 0;
169
170 while (length < 8) {
171 int count = inputStream.read(data, length, 8 - length);
172
173 if (count < 0) {
174 throw new EOFException();
175 }
176
177 length += count;
178 }
179
180 long receipt = BigEndianCodec.getLong(data, 0);
181
182 ByteBuffer byteBuffer = MailboxUtil.receiveMail(receipt);
183
184 if (byteBuffer == null) {
185 throw new IllegalArgumentException(
186 "No mail with receipt " + receipt);
187 }
188
189 Deserializer deserializer = new Deserializer(byteBuffer);
190
191 try {
192 return deserializer.readObject();
193 }
194 catch (ClassNotFoundException cnfe) {
195 throw new IOException(cnfe);
196 }
197 }
198
199 public void writeTo(
200 RegistrationReference registrationReference,
201 OutputStream outputStream)
202 throws IOException {
203
204 Serializer serializer = new Serializer();
205
206 serializer.writeObject(this);
207
208 try {
209 byte[] data = new byte[8];
210
211 ByteBuffer byteBuffer = serializer.toByteBuffer();
212
213 long receipt = MailboxUtil.sendMail(
214 registrationReference, byteBuffer);
215
216 BigEndianCodec.putLong(data, 0, receipt);
217
218 outputStream.write(data);
219
220 outputStream.flush();
221 }
222 catch (MailboxException me) {
223 throw new IOException(me);
224 }
225 }
226
227 protected void captureThreadLocals() {
228 threadLocalDistributors =
229 ThreadLocalDistributorRegistry.getThreadLocalDistributors();
230
231 for (ThreadLocalDistributor threadLocalDistributor :
232 threadLocalDistributors) {
233
234 threadLocalDistributor.capture();
235 }
236 }
237
238 protected void restoreThreadLocals() {
239 for (ThreadLocalDistributor threadLocalDistributor :
240 threadLocalDistributors) {
241
242 threadLocalDistributor.restore();
243 }
244 }
245
246 protected ThreadLocalDistributor[] threadLocalDistributors;
247
248 private static Log _log = LogFactoryUtil.getLog(SPIAgentSerializable.class);
249
250 }