001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
013: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
014: * License for the specific language governing permissions and limitations
015: * under the License.
016: *
017: */
018:
019: /*
020: * Created on May 21, 2004
021: */
022: package org.apache.jmeter.protocol.http.util.accesslog;
023:
024: import java.io.Serializable;
025: import java.util.Collections;
026: import java.util.HashMap;
027: import java.util.HashSet;
028: import java.util.Map;
029: import java.util.Set;
030:
031: import org.apache.jmeter.protocol.http.control.CookieManager;
032: import org.apache.jmeter.protocol.http.sampler.HTTPSampler;
033: import org.apache.jmeter.testelement.TestCloneable;
034: import org.apache.jmeter.testelement.TestElement;
035: import org.apache.jmeter.testelement.ThreadListener;
036: import org.apache.jmeter.util.JMeterUtils;
037: import org.apache.jorphan.logging.LoggingManager;
038: import org.apache.log.Logger;
039: import org.apache.oro.text.regex.Pattern;
040: import org.apache.oro.text.regex.Perl5Compiler;
041: import org.apache.oro.text.regex.Perl5Matcher;
042:
043: /**
044: * @author mstover
045: *
046: */
047: public class SessionFilter implements Filter, Serializable,
048: TestCloneable, ThreadListener {
049: private static final long serialVersionUID = 1;
050: static Logger log = LoggingManager.getLoggerForClass();
051:
052: /**
053: * These objects are static across multiple threads in a test, via clone()
054: * method.
055: */
056: protected Map cookieManagers;
057: protected Set managersInUse;
058:
059: protected CookieManager lastUsed;
060:
061: /*
062: * (non-Javadoc)
063: *
064: * @see org.apache.jmeter.protocol.http.util.accesslog.LogFilter#excPattern(java.lang.String)
065: */
066: protected boolean hasExcPattern(String text) {
067: return false;
068: }
069:
070: protected String getIpAddress(String logLine) {
071: Pattern incIp = JMeterUtils.getPatternCache().getPattern(
072: "\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}",
073: Perl5Compiler.READ_ONLY_MASK
074: | Perl5Compiler.SINGLELINE_MASK);
075: Perl5Matcher matcher = JMeterUtils.getMatcher();
076: matcher.contains(logLine, incIp);
077: return matcher.getMatch().group(0);
078: }
079:
080: /*
081: * (non-Javadoc)
082: *
083: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#reset()
084: */
085: public void reset() {
086: cookieManagers.clear();
087: }
088:
089: public Object clone() {
090: if (cookieManagers == null) {
091: cookieManagers = Collections.synchronizedMap(new HashMap());
092: }
093: if (managersInUse == null) {
094: managersInUse = Collections.synchronizedSet(new HashSet());
095: }
096: SessionFilter f = new SessionFilter();
097: f.cookieManagers = cookieManagers;
098: f.managersInUse = managersInUse;
099: return f;
100: }
101:
102: /**
103: *
104: */
105: public SessionFilter() {
106: }
107:
108: /*
109: * (non-Javadoc)
110: *
111: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#excludeFiles(java.lang.String[])
112: */
113: public void excludeFiles(String[] filenames) {
114: }
115:
116: /*
117: * (non-Javadoc)
118: *
119: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#excludePattern(java.lang.String[])
120: */
121: public void excludePattern(String[] regexp) {
122: }
123:
124: /*
125: * (non-Javadoc)
126: *
127: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#filter(java.lang.String)
128: */
129: public String filter(String text) {
130: return text;
131: }
132:
133: /*
134: * (non-Javadoc)
135: *
136: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#includeFiles(java.lang.String[])
137: */
138: public void includeFiles(String[] filenames) {
139: }
140:
141: /*
142: * (non-Javadoc)
143: *
144: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#includePattern(java.lang.String[])
145: */
146: public void includePattern(String[] regexp) {
147: }
148:
149: /*
150: * (non-Javadoc)
151: *
152: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#isFiltered(java.lang.String)
153: */
154: public boolean isFiltered(String path, TestElement sampler) {
155: String ipAddr = getIpAddress(path);
156: CookieManager cm = getCookieManager(ipAddr);
157: ((HTTPSampler) sampler).setCookieManager(cm);
158: return false;
159: }
160:
161: protected CookieManager getCookieManager(String ipAddr) {
162: CookieManager cm = null;
163: // First have to release the cookie we were using so other
164: // threads stuck in wait can move on
165: synchronized (managersInUse) {
166: if (lastUsed != null) {
167: managersInUse.remove(lastUsed);
168: managersInUse.notify();
169: }
170: }
171: // let notified threads move on and get lock on managersInUse
172: if (lastUsed != null) {
173: Thread.yield();
174: }
175: // here is the core routine to find appropriate cookie manager and
176: // check it's not being used. If used, wait until whoever's using it gives
177: // it up
178: synchronized (managersInUse) {
179: cm = (CookieManager) cookieManagers.get(ipAddr);
180: if (cm == null) {
181: cm = new CookieManager();
182: cookieManagers.put(ipAddr, cm);
183: }
184: while (managersInUse.contains(cm)) {
185: try {
186: managersInUse.wait();
187: } catch (InterruptedException e) {
188: log.info("SessionFilter wait interrupted");
189: }
190: }
191: managersInUse.add(cm);
192: lastUsed = cm;
193: }
194: return cm;
195: }
196:
197: /*
198: * (non-Javadoc)
199: *
200: * @see org.apache.jmeter.protocol.http.util.accesslog.Filter#setReplaceExtension(java.lang.String,
201: * java.lang.String)
202: */
203: public void setReplaceExtension(String oldextension,
204: String newextension) {
205: }
206:
207: /* (non-Javadoc)
208: * @see org.apache.jmeter.testelement.ThreadListener#threadFinished()
209: */
210: public void threadFinished() {
211: synchronized (managersInUse) {
212: managersInUse.remove(lastUsed);
213: managersInUse.notify();
214: }
215: }
216:
217: /* (non-Javadoc)
218: * @see org.apache.jmeter.testelement.ThreadListener#threadStarted()
219: */
220: public void threadStarted() {
221: // TODO Auto-generated method stub
222:
223: }
224: }
|