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