View | Details | Raw Unified | Return to bug 56728
Collapse All | Expand All

(-)/Users/schizophrenia/tmp/jmeter/src/components/org/apache/jmeter/control/CriticalSectionController.java (+141 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.control;
20
21
import java.io.Serializable;
22
import java.util.concurrent.ConcurrentHashMap;
23
import java.util.concurrent.atomic.AtomicBoolean;
24
import java.util.concurrent.locks.ReentrantLock;
25
26
import org.apache.jmeter.samplers.Sampler;
27
import org.apache.jmeter.testelement.TestElement;
28
import org.apache.jmeter.testelement.property.StringProperty;
29
import org.apache.jorphan.logging.LoggingManager;
30
import org.apache.log.Logger;
31
32
/**
33
 *
34
 *
35
 * This is a Critical Section Controller; it will execute the set of statements
36
 * (samplers/controllers, etc) under named lock.
37
 * <p>
38
 * In a programming world - this is equivalant of :
39
 * <pre>
40
 * try {
41
 *          named_lock.lock();
42
 *          statements ....
43
 * } finally {
44
 *          named_lock.unlock();
45
 * }
46
 * </pre>
47
 * In JMeter you may have :
48
 * <pre> 
49
 * Thread-Group (set to loop a number of times or indefinitely,
50
 *    ... Samplers ... (e.g. Counter )
51
 *    ... Other Controllers ....
52
 *    ... CriticalSectionController ( lock name like "foobar" )
53
 *       ... statements to perform when lock acquired
54
 *       ...
55
 *    ... Other Controllers /Samplers }
56
 * </pre>
57
 */
58
59
// TODO: write unit test
60
61
public class CriticalSectionController extends GenericController implements Serializable, TestElement {
62
63
    private static final Logger logger = LoggingManager.getLoggerForClass();
64
65
    private static final long serialVersionUID = 240L;
66
67
    private static final String LOCK_NAME = "CriticalSectionController.lockName"; //$NON-NLS-1$
68
69
    protected static final ConcurrentHashMap<String, ReentrantLock> lockMap =
70
    		new ConcurrentHashMap<String, ReentrantLock>();
71
    
72
    protected ReentrantLock currentLock;
73
    
74
    /**
75
     * constructor
76
     */
77
    public CriticalSectionController() {
78
        super();
79
    }
80
81
    /**
82
     * constructor
83
     */
84
    public CriticalSectionController(String name) {
85
        super();
86
        this.setName(name);
87
    }
88
89
    /**
90
     * Condition Accessor - this is gonna be any string value
91
     */
92
    public void setLockName(String name) {
93
        setProperty(new StringProperty(LOCK_NAME, name));
94
    }
95
    
96
    /**
97
     * Function for autocreate and get lock
98
     * @return named lock
99
     */
100
    public ReentrantLock getLock() {
101
    	ReentrantLock lock = lockMap.get(getLockName()), prev = null;
102
    	if(lock != null)	return lock;
103
    	lock = new ReentrantLock();
104
    	prev = lockMap.putIfAbsent(getLockName(), lock);
105
    	return prev == null ? lock : prev; 
106
    }
107
108
    /**
109
     * Lock name
110
     */
111
    public String getLockName() {
112
        return getPropertyAsString(LOCK_NAME);
113
    }
114
115
    /**
116
     * @see org.apache.jmeter.control.Controller#next()
117
     */
118
    @Override
119
    public Sampler next() {
120
    	if(getLockName() == null) return super.next();
121
    	if(getLockName().isEmpty()) return super.next();
122
    	long startTime = System.currentTimeMillis(), endTime;
123
    	if(this.currentLock == null) {
124
    		this.currentLock = getLock();
125
        }
126
    	this.currentLock.lock();
127
    	endTime = System.currentTimeMillis();
128
    	logger.debug("acquire time for named lock \"" + getLockName() +
129
    			"\" in Critical Section Controller is " + (endTime - startTime) + "ms");
130
    	return super.next();
131
    }
132
    
133
    @Override
134
    public void setDone(boolean done) {
135
    	if(done && this.currentLock != null) {
136
    		// TODO create policy for remove unused locks
137
    		if(this.currentLock.isLocked())	this.currentLock.unlock();
138
    	}
139
    	super.setDone(done);
140
    }
141
}
(-)/Users/schizophrenia/tmp/jmeter/src/components/org/apache/jmeter/control/gui/CriticalSectionControllerGui.java (+178 lines)
Line 0 Link Here
1
/*
2
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 * contributor license agreements.  See the NOTICE file distributed with
4
 * this work for additional information regarding copyright ownership.
5
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 * (the "License"); you may not use this file except in compliance with
7
 * the License.  You may obtain a copy of the License at
8
 *
9
 *   http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 */
18
19
package org.apache.jmeter.control.gui;
20
21
import java.awt.BorderLayout;
22
23
import javax.swing.Box;
24
import javax.swing.JCheckBox;
25
import javax.swing.JLabel;
26
import javax.swing.JPanel;
27
import javax.swing.JTextField;
28
29
import org.apache.jmeter.control.CriticalSectionController;
30
import org.apache.jmeter.control.IfController;
31
import org.apache.jmeter.testelement.TestElement;
32
import org.apache.jmeter.util.JMeterUtils;
33
34
/**
35
 * The user interface for a controller which specifies that its subcomponents
36
 * should be executed while a condition holds. This component can be used
37
 * standalone or embedded into some other component.
38
 *
39
 */
40
41
public class CriticalSectionControllerGui extends AbstractControllerGui {
42
43
    private static final long serialVersionUID = 240L;
44
45
    /**
46
     * A field allowing the user to specify the number of times the controller
47
     * should loop.
48
     */
49
    private JTextField tfLockName;
50
51
    /**
52
     * Boolean indicating whether or not this component should display its name.
53
     * If true, this is a standalone component. If false, this component is
54
     * intended to be used as a subpanel for another component.
55
     */
56
    private boolean displayName = true;
57
58
    /**
59
     * Create a new LoopControlPanel as a standalone component.
60
     */
61
    public CriticalSectionControllerGui() {
62
        this(true);
63
    }
64
65
    /**
66
     * Create a new IfControllerPanel as either a standalone or an embedded
67
     * component.
68
     *
69
     * @param displayName
70
     *            indicates whether or not this component should display its
71
     *            name. If true, this is a standalone component. If false, this
72
     *            component is intended to be used as a subpanel for another
73
     *            component.
74
     */
75
    public CriticalSectionControllerGui(boolean displayName) {
76
        this.displayName = displayName;
77
        init();
78
    }
79
80
    /**
81
     * A newly created component can be initialized with the contents of a Test
82
     * Element object by calling this method. The component is responsible for
83
     * querying the Test Element object for the relevant information to display
84
     * in its GUI.
85
     *
86
     * @param element
87
     *            the TestElement to configure
88
     */
89
    @Override
90
    public void configure(TestElement element) {
91
        super.configure(element);
92
        if (element instanceof CriticalSectionController) {
93
        	CriticalSectionController controller = (CriticalSectionController) element;
94
        	tfLockName.setText(controller.getLockName());
95
        }
96
97
    }
98
99
    /**
100
     * Implements JMeterGUIComponent.createTestElement()
101
     */
102
    @Override
103
    public TestElement createTestElement() {
104
    	CriticalSectionController controller = new CriticalSectionController();
105
        modifyTestElement(controller);
106
        return controller;
107
    }
108
109
    /**
110
     * Implements JMeterGUIComponent.modifyTestElement(TestElement)
111
     */
112
    @Override
113
    public void modifyTestElement(TestElement controller) {
114
        configureTestElement(controller);
115
        if (controller instanceof CriticalSectionController) {
116
        	CriticalSectionController csController = (CriticalSectionController) controller;
117
        	csController.setLockName(tfLockName.getText());
118
        }
119
    }
120
121
    /**
122
     * Implements JMeterGUIComponent.clearGui
123
     */
124
    @Override
125
    public void clearGui() {
126
        super.clearGui();
127
        tfLockName.setText("global_lock"); // $NON-NLS-1$
128
    }
129
130
    @Override
131
    public String getLabelResource() {
132
        return "critical_section_controller_title"; // $NON-NLS-1$
133
    }
134
135
    /**
136
     * Initialize the GUI components and layout for this component.
137
     */
138
    private void init() {
139
        // Standalone
140
        if (displayName) {
141
            setLayout(new BorderLayout(0, 5));
142
            setBorder(makeBorder());
143
            add(makeTitlePanel(), BorderLayout.NORTH);
144
145
            JPanel mainPanel = new JPanel(new BorderLayout());
146
            mainPanel.add(createConditionPanel(), BorderLayout.NORTH);
147
            add(mainPanel, BorderLayout.CENTER);
148
149
        } else {
150
            // Embedded
151
            setLayout(new BorderLayout());
152
            add(createConditionPanel(), BorderLayout.NORTH);
153
        }
154
    }
155
156
    /**
157
     * Create a GUI panel containing the condition.
158
     *
159
     * @return a GUI panel containing the condition components
160
     */
161
    private JPanel createConditionPanel() {
162
        JPanel conditionPanel = new JPanel(new BorderLayout(5, 0));
163
164
        // Condition LABEL
165
        JLabel conditionLabel = new JLabel(JMeterUtils.getResString("critical_section_controller_label")); // $NON-NLS-1$
166
        conditionPanel.add(conditionLabel, BorderLayout.WEST);
167
168
        // TEXT FIELD
169
        tfLockName = new JTextField(""); // $NON-NLS-1$
170
        conditionLabel.setLabelFor(tfLockName);
171
        conditionPanel.add(tfLockName, BorderLayout.CENTER);
172
       
173
        conditionPanel.add(Box.createHorizontalStrut(conditionLabel.getPreferredSize().width
174
                + tfLockName.getPreferredSize().width), BorderLayout.NORTH);
175
176
        return conditionPanel;
177
    }
178
}
(-)/Users/schizophrenia/tmp/jmeter/src/core/org/apache/jmeter/resources/messages.properties (+2 lines)
Lines 398-403 Link Here
398
if_controller_expression=Interpret Condition as Variable Expression?
398
if_controller_expression=Interpret Condition as Variable Expression?
399
if_controller_label=Condition (default Javascript)
399
if_controller_label=Condition (default Javascript)
400
if_controller_title=If Controller
400
if_controller_title=If Controller
401
critical_section_controller_label=Lock name
402
critical_section_controller_title=Critical Section Controller
401
ignore_subcontrollers=Ignore sub-controller blocks
403
ignore_subcontrollers=Ignore sub-controller blocks
402
include_controller=Include Controller
404
include_controller=Include Controller
403
include_equals=Include Equals?
405
include_equals=Include Equals?

Return to bug 56728