mirror of https://github.com/apache/jmeter.git
				
				
				
			Bug 54584 - MongoDB plugin
Bugzilla Id: 54584
git-svn-id: https://svn.apache.org/repos/asf/jmeter/trunk@1451961 13f79535-47bb-0310-9956-ffa450edef68
Former-commit-id: f40c2e8e5d
			
			
This commit is contained in:
		
							parent
							
								
									5e8ba0f025
								
							
						
					
					
						commit
						b0365ef0a7
					
				|  | @ -213,6 +213,11 @@ logkit.jar                  = logkit-${logkit.version}.jar | |||
| logkit.loc                  = ${maven2.repo}/logkit/logkit/${logkit.version} | ||||
| logkit.md5                  = 8D82A3E91AAE216D0A2A40B837A232FF | ||||
| 
 | ||||
| mongo-java-driver.version				= 2.10.1 | ||||
| mongo-java-driver.jar					= mongo-java-driver-${mongo-java-driver.version}.jar | ||||
| mongo-java-driver.loc					= ${maven2.repo}/org/mongodb/mongo-java-driver/${mongo-java-driver.version} | ||||
| mongo-java-driver.md5					= e12feedcdd249b3973e24d03f6cb5131 | ||||
| 
 | ||||
| slf4j-api.version           = 1.7.2 | ||||
| slf4j-api.jar               = slf4j-api-${slf4j-api.version}.jar | ||||
| slf4j-api.loc               = ${maven2.repo}/org/slf4j/slf4j-api/${slf4j-api.version} | ||||
|  |  | |||
							
								
								
									
										34
									
								
								build.xml
								
								
								
								
							
							
						
						
									
										34
									
								
								build.xml
								
								
								
								
							|  | @ -141,6 +141,7 @@ | |||
|       <class location="${dest.jar}/ApacheJMeter_mail.jar"/> | ||||
|       <class location="${dest.jar}/ApacheJMeter_monitors.jar"/> | ||||
|       <class location="${dest.jar}/ApacheJMeter_native.jar"/> | ||||
|       <class location="${dest.jar}/ApacheJMeter_mongodb.jar"/> | ||||
|       <class location="${dest.jar}/ApacheJMeter_report.jar"/> | ||||
|       <class location="${dest.jar}/ApacheJMeter_tcp.jar"/> | ||||
|       <class location="${dest.jar.jmeter}/ApacheJMeter.jar" /> | ||||
|  | @ -148,6 +149,7 @@ | |||
|       <sourcePath path="${src.tcp}" /> | ||||
|       <sourcePath path="${src.jms}" /> | ||||
|       <sourcePath path="${src.native}" /> | ||||
|       <sourcePath path="${src.mongodb}" /> | ||||
|       <sourcePath path="${src.report}" /> | ||||
|       		 | ||||
|       <auxClasspath> | ||||
|  | @ -211,6 +213,7 @@ | |||
|   <property name="src.monitor.model" value="src/monitor/model"/> | ||||
|   <property name="src.jms" value="src/protocol/jms"/> | ||||
|   <property name="src.native" value="src/protocol/native"/> | ||||
|   <property name="src.mongodb" value="src/protocol/mongodb"/> | ||||
|   <property name="src.report" value="src/reports"/> | ||||
| 
 | ||||
|   <!-- Where the documentation sources live --> | ||||
|  | @ -260,6 +263,7 @@ | |||
|   <property name="build.monitor.model" value="build/monitor/model"/> | ||||
|   <property name="build.jms" value="build/protocol/jms"/> | ||||
|   <property name="build.native" value="build/protocol/native"/> | ||||
|   <property name="build.mongodb" value="build/protocol/mongodb"/> | ||||
|   <property name="build.report" value="build/reports"/> | ||||
|   <property name="build.test" value="build/test"/> | ||||
|   <property name="build.res" value="build/res"/> | ||||
|  | @ -448,6 +452,7 @@ | |||
|     <pathelement location="${lib.dir}/${jsoup.jar}"/> | ||||
|     <pathelement location="${lib.dir}/${junit.jar}"/> | ||||
|     <pathelement location="${lib.dir}/${logkit.jar}"/> | ||||
|     <pathelement location="${lib.dir}/${mongo-java-driver.jar}"/> | ||||
|     <pathelement location="${lib.dir}/${serializer.jar}"/> | ||||
|     <pathelement location="${lib.dir}/${slf4j-api.jar}"/> | ||||
|     <pathelement location="${lib.dir}/${soap.jar}"/> | ||||
|  | @ -839,9 +844,23 @@ | |||
|       </classpath> | ||||
|     </javac> | ||||
|   </target> | ||||
| 	 | ||||
|   <target name="compile-mongodb" depends="compile-jorphan,compile-core,compile-components" | ||||
|         description="Compile components specific to MongoDB sampling."> | ||||
|     <mkdir dir="${build.mongodb}"/> | ||||
|     <javac srcdir="${src.mongodb}" destdir="${build.mongodb}" source="${src.java.version}" optimize="${optimize}" debug="on" target="${target.java.version}" | ||||
|            includeAntRuntime="${includeAntRuntime}" deprecation="${deprecation}" encoding="${encoding}"> | ||||
|       <include name="**/*.java"/> | ||||
|       <classpath> | ||||
|         <pathelement location="${build.jorphan}"/> | ||||
|         <pathelement location="${build.core}"/> | ||||
|         <path refid="classpath"/> | ||||
|       </classpath> | ||||
|     </javac> | ||||
|   </target> | ||||
| 
 | ||||
|   <target name="compile" | ||||
|   depends="_message_3rdParty,compile-core,compile-components,compile-functions,compile-protocols,compile-rmi,compile-monitor,compile-junit,compile-jms,compile-native, compile-report" | ||||
|   depends="_message_3rdParty,compile-core,compile-components,compile-functions,compile-protocols,compile-rmi,compile-monitor,compile-junit,compile-jms,compile-native, compile-mongodb, compile-report" | ||||
|   description="Compile everything."/> | ||||
| 
 | ||||
|   <target name="run_gui" depends="package" description="Run the JMeter GUI off the jar files"> | ||||
|  | @ -1117,6 +1136,18 @@ run JMeter unless all the JMeter jars are added. | |||
|       <fileset dir="${src.native}" includes="**/*.properties" /> | ||||
|     </jar> | ||||
| 
 | ||||
|     <!-- mongodb --> | ||||
|     <!-- Ensure that build dir exists, even if MongoDB has not been built --> | ||||
|     <mkdir dir="${build.mongodb}"/> | ||||
|     <jar jarfile="${dest.jar}/ApacheJMeter_mongodb.jar" manifest="${build.dir}/MANIFEST_BIN.MF"> | ||||
|       <zipfileset file="${resources.meta-inf}/default.notice" | ||||
|         fullpath="META-INF/NOTICE" /> | ||||
|       <zipfileset file="${resources.meta-inf}/default.license" | ||||
|         fullpath="META-INF/LICENSE" /> | ||||
|       <fileset dir="${build.mongodb}" includes="**/*.class" /> | ||||
|       <fileset dir="${src.mongodb}" includes="**/*.properties" /> | ||||
|     </jar> | ||||
|       	 | ||||
|     <jar jarfile="${lib.dir}/jorphan.jar" manifest="${build.dir}/MANIFEST_BIN.MF"> | ||||
|         <zipfileset file="${resources.meta-inf}/default.notice" | ||||
|           fullpath="META-INF/NOTICE" /> | ||||
|  | @ -2728,6 +2759,7 @@ run JMeter unless all the JMeter jars are added. | |||
|         <process_jarfile jarname="jsoup"/> | ||||
|         <process_jarfile jarname="junit"/> | ||||
|         <process_jarfile jarname="logkit"/> | ||||
|         <process_jarfile jarname="mongo-java-driver"/> | ||||
|         <process_jarfile jarname="serializer"/> | ||||
|     	<process_jarfile jarname="slf4j-api"/> | ||||
|         <process_jarfile jarname="soap"/> | ||||
|  |  | |||
|  | @ -0,0 +1,49 @@ | |||
| <!-- | ||||
| Licensed to the Apache Software Foundation (ASF) under one | ||||
| or more contributor license agreements.  See the NOTICE file | ||||
| distributed with this work for additional information | ||||
| regarding copyright ownership.  The ASF licenses this file | ||||
| to you under the Apache License, Version 2.0 (the | ||||
| "License"); you may not use this file except in compliance | ||||
| with the License.  You may obtain a copy of the License at | ||||
| 
 | ||||
|   http://www.apache.org/licenses/LICENSE-2.0 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, | ||||
| software distributed under the License is distributed on an | ||||
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||||
| KIND, either express or implied.  See the License for the | ||||
| specific language governing permissions and limitations | ||||
| under the License. | ||||
| --> | ||||
| 
 | ||||
| <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <parent> | ||||
|       <groupId>org.apache.jmeter</groupId> | ||||
|       <artifactId>ApacheJMeter_parent</artifactId> | ||||
|       <version>@MAVEN.DEPLOY.VERSION@</version> | ||||
|       <relativePath>.</relativePath> | ||||
|     </parent> | ||||
|     <artifactId>ApacheJMeter_mongodb</artifactId> | ||||
|     <name>Apache JMeter MongoDB</name> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.jmeter</groupId> | ||||
|             <artifactId>jorphan</artifactId> | ||||
|             <version>@MAVEN.DEPLOY.VERSION@</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.jmeter</groupId> | ||||
|             <artifactId>ApacheJMeter_core</artifactId> | ||||
|             <version>@MAVEN.DEPLOY.VERSION@</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.jmeter</groupId> | ||||
|             <artifactId>ApacheJMeter_components</artifactId> | ||||
|             <version>@MAVEN.DEPLOY.VERSION@</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
| </project> | ||||
|  | @ -82,6 +82,7 @@ under the License. | |||
|       <js_rhino.version>1.7R4</js_rhino.version> | ||||
|       <junit.version>4.10</junit.version> | ||||
|       <logkit.version>2.0</logkit.version> | ||||
|       <mongo-java-driver.version>2.10.1</mongo-java-driver.version> | ||||
|       <slf4j.version>1.7.2</slf4j.version> | ||||
|       <soap.version>2.3.1</soap.version> | ||||
|       <tidy.version>r938</tidy.version> | ||||
|  | @ -344,6 +345,11 @@ under the License. | |||
|         <artifactId>jodd-lagarto</artifactId> | ||||
|         <version>${jodd.version}</version> | ||||
|       </dependency> | ||||
|       <dependency> | ||||
|         <groupId>org.mongodb</groupId> | ||||
|         <artifactId>mongo-java-driver</artifactId> | ||||
|         <version>${mongo-java-driver.version}</version> | ||||
|       </dependency> | ||||
|       <dependency> | ||||
|         <groupId>org.slf4j</groupId> | ||||
|         <artifactId>slf4j-api</artifactId> | ||||
|  |  | |||
|  | @ -0,0 +1,264 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.config; | ||||
| 
 | ||||
| import org.apache.jmeter.config.ConfigElement; | ||||
| import org.apache.jmeter.protocol.mongodb.mongo.MongoDB; | ||||
| import org.apache.jmeter.protocol.mongodb.mongo.MongoUtils; | ||||
| import org.apache.jmeter.testbeans.TestBean; | ||||
| import org.apache.jmeter.testelement.AbstractTestElement; | ||||
| import org.apache.jmeter.testelement.TestStateListener; | ||||
| import org.apache.jmeter.threads.JMeterContextService; | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| import com.mongodb.MongoOptions; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
| public class MongoSourceElement | ||||
|     extends AbstractTestElement | ||||
|         implements ConfigElement, TestStateListener, TestBean { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     public final static String CONNECTION = "MongoSourceElement.connection"; //$NON-NLS-1$ | ||||
|     public final static String SOURCE = "MongoSourceElement.source"; //$NON-NLS-1$ | ||||
| 
 | ||||
|     public final static String AUTO_CONNECT_RETRY = "MongoSourceElement.autoConnectRetry"; //$NON-NLS-1$ | ||||
|     public final static String CONNECTIONS_PER_HOST = "MongoSourceElement.connectionsPerHost"; //$NON-NLS-1$ | ||||
|     public final static String CONNECT_TIMEOUT = "MongoSourceElement.connectTimeout"; //$NON-NLS-1$ | ||||
|     public final static String MAX_AUTO_CONNECT_RETRY_TIME = "MongoSourceElement.maxAutoConnectRetryTime"; //$NON-NLS-1$ | ||||
|     public final static String MAX_WAIT_TIME = "MongoSourceElement.maxWaitTime"; //$NON-NLS-1$ | ||||
|     public final static String SOCKET_TIMEOUT = "MongoSourceElement.socketTimeout"; //$NON-NLS-1$ | ||||
|     public final static String SOCKET_KEEP_ALIVE = "MongoSourceElement.socketKeepAlive"; //$NON-NLS-1$ | ||||
|     public final static String THREADS_ALLOWED_TO_BLOCK_MULTIPLIER = "MongoSourceElement.threadsAllowedToBlockForConnectionMultiplier"; //$NON-NLS-1$ | ||||
| 
 | ||||
|     public final static String FSYNC = "MongoSourceElement.fsync"; //$NON-NLS-1$ | ||||
|     public final static String SAFE = "MongoSourceElement.safe"; //$NON-NLS-1$ | ||||
|     public final static String WAIT_FOR_JOURNALING = "MongoSourceElement.waitForJournaling"; //$NON-NLS-1$ | ||||
|     public final static String WRITE_OPERATION_NUMBER_OF_SERVERS = "MongoSourceElement.writeOperationNumberOfServers"; //$NON-NLS-1$ | ||||
|     public final static String WRITE_OPERATION_TIMEOUT = "MongoSourceElement.writeOperationTimeout"; //$NON-NLS-1$ | ||||
| 
 | ||||
|     public String getTitle() { | ||||
|         return this.getName(); | ||||
|     } | ||||
| 
 | ||||
|     public String getConnection() { | ||||
|         return getPropertyAsString(CONNECTION); | ||||
|     } | ||||
| 
 | ||||
|     public void setConnection(String connection) { | ||||
|         setProperty(CONNECTION, connection); | ||||
|     } | ||||
| 
 | ||||
|     public String getSource() { | ||||
|         return getPropertyAsString(SOURCE); | ||||
|     } | ||||
| 
 | ||||
|     public void setSource(String source) { | ||||
|         setProperty(SOURCE, source); | ||||
|     } | ||||
| 
 | ||||
|     public String getAutoConnectRetry() { | ||||
|         return getPropertyAsString(AUTO_CONNECT_RETRY); | ||||
|     } | ||||
| 
 | ||||
|     public void setAutoConnectRetry(String autoConnectRetry) { | ||||
|         setProperty(AUTO_CONNECT_RETRY, autoConnectRetry); | ||||
|     } | ||||
| 
 | ||||
|     public String getConnectionsPerHost() { | ||||
|         return getPropertyAsString(CONNECTIONS_PER_HOST); | ||||
|     } | ||||
| 
 | ||||
|     public void setConnectionsPerHost(String connectionsPerHost) { | ||||
|         setProperty(CONNECTIONS_PER_HOST, connectionsPerHost); | ||||
|     } | ||||
| 
 | ||||
|     public String getConnectTimeout() { | ||||
|         return getPropertyAsString(CONNECT_TIMEOUT); | ||||
|     } | ||||
| 
 | ||||
|     public void setConnectTimeout(String connectTimeout) { | ||||
|         setProperty(CONNECT_TIMEOUT, connectTimeout); | ||||
|     } | ||||
| 
 | ||||
|     public String getMaxAutoConnectRetryTime() { | ||||
|         return getPropertyAsString(MAX_AUTO_CONNECT_RETRY_TIME); | ||||
|     } | ||||
| 
 | ||||
|     public void setMaxAutoConnectRetryTime(String maxAutoConnectRetryTime) { | ||||
|         setProperty(MAX_AUTO_CONNECT_RETRY_TIME, maxAutoConnectRetryTime); | ||||
|     } | ||||
| 
 | ||||
|     public String getMaxWaitTime() { | ||||
|         return getPropertyAsString(MAX_WAIT_TIME); | ||||
|     } | ||||
| 
 | ||||
|     public void setMaxWaitTime(String maxWaitTime) { | ||||
|         setProperty(MAX_WAIT_TIME, maxWaitTime); | ||||
|     } | ||||
| 
 | ||||
|     public String getSocketTimeout() { | ||||
|         return getPropertyAsString(SOCKET_TIMEOUT); | ||||
|     } | ||||
| 
 | ||||
|     public void setSocketTimeout(String socketTimeout) { | ||||
|         setProperty(SOCKET_TIMEOUT, socketTimeout); | ||||
|     } | ||||
| 
 | ||||
|     public String getSocketKeepAlive() { | ||||
|         return getPropertyAsString(SOCKET_KEEP_ALIVE); | ||||
|     } | ||||
| 
 | ||||
|     public void setSocketKeepAlive(String socketKeepAlive) { | ||||
|         setProperty(SOCKET_KEEP_ALIVE, socketKeepAlive); | ||||
|     } | ||||
| 
 | ||||
|     public String getThreadsAllowedToBlockForConnectionMultiplier() { | ||||
|         return getPropertyAsString(THREADS_ALLOWED_TO_BLOCK_MULTIPLIER); | ||||
|     } | ||||
| 
 | ||||
|     public void setThreadsAllowedToBlockForConnectionMultiplier(String threadsAllowed) { | ||||
|         setProperty(THREADS_ALLOWED_TO_BLOCK_MULTIPLIER, threadsAllowed); | ||||
|     } | ||||
| 
 | ||||
|     public String getFsync() { | ||||
|         return getPropertyAsString(FSYNC); | ||||
|     } | ||||
| 
 | ||||
|     public void setFsync(String fsync) { | ||||
|         setProperty(FSYNC, fsync); | ||||
|     } | ||||
| 
 | ||||
|     public String getSafe() { | ||||
|         return getPropertyAsString(SAFE); | ||||
|     } | ||||
| 
 | ||||
|     public void setSafe(String safe) { | ||||
|         setProperty(SAFE, safe); | ||||
|     } | ||||
| 
 | ||||
|     public String getWaitForJournaling() { | ||||
|         return getPropertyAsString(WAIT_FOR_JOURNALING); | ||||
|     } | ||||
| 
 | ||||
|     public void setWaitForJournaling(String waitForJournaling) { | ||||
|         setProperty(WAIT_FOR_JOURNALING, waitForJournaling); | ||||
|     } | ||||
| 
 | ||||
|     public String getWriteOperationNumberOfServers() { | ||||
|         return getPropertyAsString(WRITE_OPERATION_NUMBER_OF_SERVERS); | ||||
|     } | ||||
| 
 | ||||
|     public void setWriteOperationNumberOfServers(String writeOperationNumberOfServers) { | ||||
|         setProperty(WRITE_OPERATION_NUMBER_OF_SERVERS, writeOperationNumberOfServers); | ||||
|     } | ||||
| 
 | ||||
|     public String getWriteOperationTimeout() { | ||||
|         return getPropertyAsString(WRITE_OPERATION_TIMEOUT); | ||||
|     } | ||||
| 
 | ||||
|     public void setWriteOperationTimeout(String writeOperationTimeout) { | ||||
|         setProperty(WRITE_OPERATION_TIMEOUT, writeOperationTimeout); | ||||
|     } | ||||
| 
 | ||||
|     public static MongoDB getMongoDB(String source) { | ||||
| 
 | ||||
|         Object mongoSource = JMeterContextService.getContext().getVariables().getObject(source); | ||||
| 
 | ||||
|         if(mongoSource == null) { | ||||
|             throw new IllegalStateException("mongoSource is null"); | ||||
|         } | ||||
|         else { | ||||
|             if(mongoSource instanceof MongoDB) { | ||||
|                 return (MongoDB)mongoSource; | ||||
|             } | ||||
|             else { | ||||
|                 throw new IllegalStateException("Variable:"+ source +" is not a MongoDB instance, class:"+(mongoSource != null ? mongoSource.getClass():"null")); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void addConfigElement(ConfigElement configElement) { | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean expectsModification() { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void testStarted() { | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug(getTitle() + " testStarted"); | ||||
|         } | ||||
| 
 | ||||
|         MongoOptions mongoOptions = new MongoOptions(); | ||||
|         mongoOptions.autoConnectRetry = Boolean.parseBoolean(getAutoConnectRetry()); | ||||
|         mongoOptions.connectTimeout = Integer.parseInt(getConnectTimeout()); | ||||
|         mongoOptions.connectionsPerHost = Integer.parseInt(getConnectionsPerHost()); | ||||
|         mongoOptions.fsync = Boolean.parseBoolean(getFsync()); | ||||
|         mongoOptions.j = Boolean.parseBoolean(getWaitForJournaling()); | ||||
|         mongoOptions.maxAutoConnectRetryTime = Integer.parseInt(getMaxAutoConnectRetryTime()); | ||||
|         mongoOptions.maxWaitTime = Integer.parseInt(getMaxWaitTime()); | ||||
|         mongoOptions.safe = Boolean.parseBoolean(getSafe()); | ||||
|         mongoOptions.socketKeepAlive = Boolean.parseBoolean(getSocketKeepAlive()); | ||||
|         mongoOptions.socketTimeout = Integer.parseInt(getSocketTimeout()); | ||||
|         mongoOptions.threadsAllowedToBlockForConnectionMultiplier = Integer.parseInt(getThreadsAllowedToBlockForConnectionMultiplier()); | ||||
|         mongoOptions.w = Integer.parseInt(getWriteOperationNumberOfServers()); | ||||
|         mongoOptions.wtimeout = Integer.parseInt(getWriteOperationTimeout()); | ||||
| 
 | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug("options : " + mongoOptions.toString()); | ||||
|         } | ||||
| 
 | ||||
|         if(getThreadContext().getVariables().getObject(getSource()) != null) { | ||||
|             if(log.isWarnEnabled()) { | ||||
|                 log.warn(getSource() + " has already been defined."); | ||||
|             } | ||||
|         } | ||||
|         else { | ||||
|             if(log.isDebugEnabled()) { | ||||
|                 log.debug(getSource() + "  is being defined."); | ||||
|             } | ||||
|             getThreadContext().getVariables().putObject(getSource(), new MongoDB(MongoUtils.toServerAddresses(getConnection()), mongoOptions)); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void testStarted(String s) { | ||||
|         testStarted(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void testEnded() { | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug(getTitle() + " testEnded"); | ||||
|         } | ||||
|         ((MongoDB)getThreadContext().getVariables().getObject(getSource())).clear(); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void testEnded(String s) { | ||||
|         testEnded(); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,116 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.config; | ||||
| 
 | ||||
| import java.beans.PropertyDescriptor; | ||||
| 
 | ||||
| import org.apache.jmeter.testbeans.BeanInfoSupport; | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| /** | ||||
|   */ | ||||
| public class MongoSourceElementBeanInfo | ||||
|         extends BeanInfoSupport { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     public MongoSourceElementBeanInfo() { | ||||
|         super(MongoSourceElement.class); | ||||
| 
 | ||||
|         //http://api.mongodb.org/java/2.7.2/com/mongodb/Mongo.html | ||||
|         createPropertyGroup("mongodb", new String[] { | ||||
|                 "connection", | ||||
|                 "source"}); | ||||
| 
 | ||||
|         //http://api.mongodb.org/java/2.7.2/com/mongodb/MongoOptions.html/ | ||||
|         createPropertyGroup("options", new String[]{ | ||||
|                 "autoConnectRetry", | ||||
|                 "connectionsPerHost", | ||||
|                 "connectTimeout", | ||||
|                 "maxAutoConnectRetryTime", | ||||
|                 "maxWaitTime", | ||||
|                 "socketTimeout", | ||||
|                 "socketKeepAlive", | ||||
|                 "threadsAllowedToBlockForConnectionMultiplier"}); | ||||
| 
 | ||||
|         //http://api.mongodb.org/java/2.7.2/com/mongodb/MongoOptions.html/ | ||||
|         createPropertyGroup("writeConcern", new String[] { | ||||
|                 "fsync", | ||||
|                 "safe", | ||||
|                 "waitForJournaling", | ||||
|                 "writeOperationNumberOfServers", | ||||
|                 "writeOperationTimeout" }); | ||||
| 
 | ||||
|         PropertyDescriptor p = property("connection"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
|         p = property("source"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
| 
 | ||||
|         p = property("autoConnectRetry"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, Boolean.FALSE); | ||||
|         p = property("connectionsPerHost"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "10"); | ||||
|         p = property("connectTimeout"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "0"); | ||||
|         p = property("threadsAllowedToBlockForConnectionMultiplier"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "5"); | ||||
|         p = property("maxAutoConnectRetryTime"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "0"); | ||||
|         p = property("maxWaitTime"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "120000"); | ||||
|         p = property("socketTimeout"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "0"); | ||||
|         p = property("socketKeepAlive"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, Boolean.FALSE); | ||||
| 
 | ||||
|         p = property("fsync"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, Boolean.FALSE); | ||||
|         p = property("safe"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, Boolean.FALSE); | ||||
|         p = property("waitForJournaling"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, Boolean.FALSE); | ||||
|         p = property("writeOperationNumberOfServers"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "0"); | ||||
|         p = property("writeOperationTimeout"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, "0"); | ||||
| 
 | ||||
|         if(log.isDebugEnabled()) { | ||||
|             for (PropertyDescriptor pd : getPropertyDescriptors()) { | ||||
|                 log.debug(pd.getName()); | ||||
|                 log.debug(pd.getDisplayName()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,46 @@ | |||
| displayName=MongoDB Source Config | ||||
| 
 | ||||
| mongodb.displayName=MongoDB Connection | ||||
| mongodb.shortDescription=Configure the connection | ||||
| 
 | ||||
| connection.displayName=Server Address List | ||||
| connection.shortDescription=Server Address List | ||||
| 
 | ||||
| source.displayName=MongoDB Source | ||||
| source.shortDescription=Configure the Source | ||||
| 
 | ||||
| options.displayName=MongoDB Options | ||||
| options.shortDescription=Various settings for the driver | ||||
| 
 | ||||
| autoConnectRetry.displayName=Keep trying | ||||
| connectionsPerHost.displayName=Maximum connections Per Host | ||||
| connectTimeout.displayName=Connection timeout | ||||
| maxAutoConnectRetryTime.displayName=Maximum retry time | ||||
| maxWaitTime.displayName=Maximum wait time | ||||
| socketKeepAlive.displayName=Socket keep alive | ||||
| socketTimeout.displayName=Socket timeout | ||||
| threadsAllowedToBlockForConnectionMultiplier.displayName=Block Multiplier | ||||
| 
 | ||||
| autoConnectRetry.shortDescription=If true, the driver will keep trying to connect to the same server in case that the socket cannot be established.<br><br>There is maximum amount of time to keep retrying, which is 15s by default.<br><br>This can be useful to avoid some exceptions being thrown when a server is down temporarily by blocking the operations.<br><br>It also can be useful to smooth the transition to a new master (so that a new master is elected within the retry time).<br><br>Note that when using this flag:<br>- for a replica set, the driver will trying to connect to the old master for that time, instead of failing over to the new one right away -<br> this does not prevent exception from being thrown in read/write operations on the socket, which must be handled by application.<br><br>Even if this flag is false, the driver already has mechanisms to automatically recreate broken connections and retry the read operations. <br><br>Default is false. | ||||
| connectionsPerHost.shortDescription=The maximum number of connections allowed per host for this Mongo instance.<br><br>Those connections will be kept in a pool when idle.<br><br>Once the pool is exhausted, any operation requiring a connection will block waiting for an available connection.<br><br>Default is 10. | ||||
| connectTimeout.shortDescription=The connection timeout in milliseconds.<br><br>It is used solely when establishing a new connection Socket.connect(java.net.SocketAddress, int)<br><br>Default is 0 and means no timeout. | ||||
| maxAutoConnectRetryTime.shortDescription=The maximum amount of time in MS to spend retrying to open connection to the same server.<br><br>Default is 0, which means to use the default 15s if autoConnectRetry is on. | ||||
| maxWaitTime.shortDescription=The maximum wait time in ms that a thread may wait for a connection to become available.<br><br>Default is 120,000. | ||||
| socketKeepAlive.shortDescription=This flag controls the socket keep alive feature that keeps a connection alive through firewalls Socket.setKeepAlive(boolean)<br><br>Default is false. | ||||
| socketTimeout.shortDescription=The socket timeout in milliseconds It is used for I/O socket read and write operations Socket.setSoTimeout(int)<br><br>Default is 0 and means no timeout. | ||||
| threadsAllowedToBlockForConnectionMultiplier.shortDescription=This multiplier, multiplied with the connectionsPerHost setting, gives the maximum number of threads that may be waiting for a connection to become available from the pool.<br><br>All further threads will get an exception right away.<br><br>For example if connectionsPerHost is 10 and threadsAllowedToBlockForConnectionMultiplier is 5, then up to 50 threads can wait for a connection.<br><br>Default is 5. | ||||
| 
 | ||||
| writeConcern.displayName=Write Concern Options | ||||
| writeConcern.shortDescription=Various settings for the driver | ||||
| 
 | ||||
| fsync.displayName=Fsync | ||||
| safe.displayName=Safe | ||||
| waitForJournaling.displayName=Wait for Journal | ||||
| writeOperationNumberOfServers.displayName=Wait for Servers | ||||
| writeOperationTimeout.displayName=Wait Timeout | ||||
| 
 | ||||
| fsync.shortDescription=The fsync value of the global WriteConcern.<br><br>Default is false. | ||||
| safe.shortDescription=If true the driver will use a WriteConcern of WriteConcern.SAFE for all operations.<br><br>If w, wtimeout, fsync or j are specified, this setting is ignored.<br><br>Default is false. | ||||
| waitForJournaling.shortDescription=The j value of the global WriteConcern.<br><br>Default is false. | ||||
| writeOperationNumberOfServers.shortDescription=The w value of the global WriteConcern.<br><br>Default is 0. | ||||
| writeOperationTimeout.shortDescription=The wtimeout value of the global WriteConcern.<br><br>Default is 0. | ||||
|  | @ -0,0 +1,46 @@ | |||
| displayName=MongoDB Source Config | ||||
| 
 | ||||
| mongodb.displayName=MongoDB Connection | ||||
| mongodb.shortDescription=Configure the connection | ||||
| 
 | ||||
| connection.displayName=Server Address List | ||||
| connection.shortDescription=Server Address List | ||||
| 
 | ||||
| source.displayName=MongoDB Source | ||||
| source.shortDescription=Configure the Source | ||||
| 
 | ||||
| options.displayName=MongoDB Options | ||||
| options.shortDescription=Various settings for the driver | ||||
| 
 | ||||
| autoConnectRetry.displayName=Keep trying | ||||
| connectionsPerHost.displayName=Maximum connections Per Host | ||||
| connectTimeout.displayName=Connection timeout | ||||
| maxAutoConnectRetryTime.displayName=Maximum retry time | ||||
| maxWaitTime.displayName=Maximum wait time | ||||
| socketKeepAlive.displayName=Socket keep alive | ||||
| socketTimeout.displayName=Socket timeout | ||||
| threadsAllowedToBlockForConnectionMultiplier.displayName=Block Multiplier | ||||
| 
 | ||||
| autoConnectRetry.shortDescription=If true, the driver will keep trying to connect to the same server in case that the socket cannot be established.<br><br>There is maximum amount of time to keep retrying, which is 15s by default.<br><br>This can be useful to avoid some exceptions being thrown when a server is down temporarily by blocking the operations.<br><br>It also can be useful to smooth the transition to a new master (so that a new master is elected within the retry time).<br><br>Note that when using this flag:<br>- for a replica set, the driver will trying to connect to the old master for that time, instead of failing over to the new one right away -<br> this does not prevent exception from being thrown in read/write operations on the socket, which must be handled by application.<br><br>Even if this flag is false, the driver already has mechanisms to automatically recreate broken connections and retry the read operations. <br><br>Default is false. | ||||
| connectionsPerHost.shortDescription=The maximum number of connections allowed per host for this Mongo instance.<br><br>Those connections will be kept in a pool when idle.<br><br>Once the pool is exhausted, any operation requiring a connection will block waiting for an available connection.<br><br>Default is 10. | ||||
| connectTimeout.shortDescription=The connection timeout in milliseconds.<br><br>It is used solely when establishing a new connection Socket.connect(java.net.SocketAddress, int)<br><br>Default is 0 and means no timeout. | ||||
| maxAutoConnectRetryTime.shortDescription=The maximum amount of time in MS to spend retrying to open connection to the same server.<br><br>Default is 0, which means to use the default 15s if autoConnectRetry is on. | ||||
| maxWaitTime.shortDescription=The maximum wait time in ms that a thread may wait for a connection to become available.<br><br>Default is 120,000. | ||||
| socketKeepAlive.shortDescription=This flag controls the socket keep alive feature that keeps a connection alive through firewalls Socket.setKeepAlive(boolean)<br><br>Default is false. | ||||
| socketTimeout.shortDescription=The socket timeout in milliseconds It is used for I/O socket read and write operations Socket.setSoTimeout(int)<br><br>Default is 0 and means no timeout. | ||||
| threadsAllowedToBlockForConnectionMultiplier.shortDescription=This multiplier, multiplied with the connectionsPerHost setting, gives the maximum number of threads that may be waiting for a connection to become available from the pool.<br><br>All further threads will get an exception right away.<br><br>For example if connectionsPerHost is 10 and threadsAllowedToBlockForConnectionMultiplier is 5, then up to 50 threads can wait for a connection.<br><br>Default is 5. | ||||
| 
 | ||||
| writeConcern.displayName=Write Concern Options | ||||
| writeConcern.shortDescription=Various settings for the driver | ||||
| 
 | ||||
| fsync.displayName=Fsync | ||||
| safe.displayName=Safe | ||||
| waitForJournaling.displayName=Wait for Journal | ||||
| writeOperationNumberOfServers.displayName=Wait for Servers | ||||
| writeOperationTimeout.displayName=Wait Timeout | ||||
| 
 | ||||
| fsync.shortDescription=The fsync value of the global WriteConcern.<br><br>Default is false. | ||||
| safe.shortDescription=If true the driver will use a WriteConcern of WriteConcern.SAFE for all operations.<br><br>If w, wtimeout, fsync or j are specified, this setting is ignored.<br><br>Default is false. | ||||
| waitForJournaling.shortDescription=The j value of the global WriteConcern.<br><br>Default is false. | ||||
| writeOperationNumberOfServers.shortDescription=The w value of the global WriteConcern.<br><br>Default is 0. | ||||
| writeOperationTimeout.shortDescription=The wtimeout value of the global WriteConcern.<br><br>Default is 0. | ||||
|  | @ -0,0 +1,67 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.mongo; | ||||
| 
 | ||||
| import com.mongodb.DBObject; | ||||
| import com.mongodb.util.JSON; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
| public class EvalResultHandler { | ||||
| 
 | ||||
|     //This can lead to code smell, meh! Do we care | ||||
|     public String handle(Object o) { | ||||
|         if(o == null) { | ||||
|             return "ok"; | ||||
|         } | ||||
| 
 | ||||
|         if(o instanceof Double) { | ||||
|             return this.handle((Double)o); | ||||
|         } | ||||
|         else if(o instanceof Integer) { | ||||
|             return this.handle((Integer)o); | ||||
|         } | ||||
|         else if(o instanceof String) { | ||||
|             return this.handle((String)o); | ||||
|         } | ||||
|         else if(o instanceof DBObject) { | ||||
|             return this.handle((DBObject)o); | ||||
|         } | ||||
|         else { | ||||
|             return "return type not handled"; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public String handle(Integer o) { | ||||
|         return o.toString(); | ||||
|     } | ||||
| 
 | ||||
|     public String handle(String o) { | ||||
|         return o; | ||||
|     } | ||||
| 
 | ||||
|     public String handle(Double o) { | ||||
|         return o.toString(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public String handle(DBObject o) { | ||||
|         return JSON.serialize(o); | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,74 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.mongo; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| import com.mongodb.DB; | ||||
| import com.mongodb.Mongo; | ||||
| import com.mongodb.MongoOptions; | ||||
| import com.mongodb.ServerAddress; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
| public class MongoDB { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     // Mongo is Thread Safe | ||||
|     private Mongo mongo = null; | ||||
| 
 | ||||
|     public MongoDB( | ||||
|             List<ServerAddress> serverAddresses, | ||||
|             MongoOptions mongoOptions) { | ||||
|         mongo = new Mongo(serverAddresses, mongoOptions);    | ||||
|     } | ||||
| 
 | ||||
|     public DB getDB(String database, String username, String password) { | ||||
| 
 | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug("username: " + username+", password: " + password+", database: " + database); | ||||
|         } | ||||
|         DB db = mongo.getDB(database); | ||||
|         boolean authenticated = db.isAuthenticated(); | ||||
| 
 | ||||
|         if(!authenticated) { | ||||
|             if(username != null && password != null && username.length() > 0 && password.length() > 0) { | ||||
|                 authenticated = db.authenticate(username, password.toCharArray()); | ||||
|             } | ||||
|         } | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug("authenticated: " + authenticated); | ||||
|         } | ||||
|         return db; | ||||
|     } | ||||
| 
 | ||||
|     public void clear() { | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug("clearing"); | ||||
|         } | ||||
| 
 | ||||
|         mongo.close(); | ||||
|         //there is no harm in trying to clear up | ||||
|         mongo = null; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,56 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.mongo; | ||||
| 
 | ||||
| import java.net.UnknownHostException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| 
 | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| import com.mongodb.ServerAddress; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
| public class MongoUtils { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     public static ArrayList<ServerAddress> toServerAddresses(String connections) { | ||||
| 
 | ||||
|         ArrayList<ServerAddress> addresses = new ArrayList<ServerAddress>(); | ||||
|         try { | ||||
|             for(String connection : Arrays.asList(connections.split(","))) { | ||||
|                 int port = 27017; | ||||
|                 String[] hostPort = connection.split(":"); | ||||
|                 if(hostPort.length > 1 && hostPort[1] != null) { | ||||
|                     port = Integer.parseInt(hostPort[1].trim()); | ||||
|                 } | ||||
|                 addresses.add(new ServerAddress(hostPort[0], port)); | ||||
|             } | ||||
|         } | ||||
|         catch(UnknownHostException uhe) { | ||||
|             if(log.isWarnEnabled()) { | ||||
|                 log.warn("", uhe); | ||||
|             } | ||||
|         } | ||||
|         return addresses; | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,64 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.sampler; | ||||
| 
 | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| import com.mongodb.DB; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
| public class MongoScriptRunner { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     public MongoScriptRunner() { | ||||
|         super(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      *  | ||||
|      * @param db | ||||
|      * @param script | ||||
|      * @return | ||||
|      * @throws Exception | ||||
|      */ | ||||
|     public Object evaluate(DB db, String script) | ||||
|         throws Exception { | ||||
| 
 | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug("database: " + db.getName()+", script: " + script); | ||||
|         } | ||||
| 
 | ||||
|         db.requestStart(); | ||||
|         try { | ||||
|             db.requestEnsureConnection(); | ||||
|      | ||||
|             Object result = db.eval(script); | ||||
|      | ||||
|             if(log.isDebugEnabled()) { | ||||
|                 log.debug("Result : " + result); | ||||
|             } | ||||
|             return result; | ||||
|         } finally { | ||||
|             db.requestDone(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,150 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.sampler; | ||||
| 
 | ||||
| import org.apache.jmeter.protocol.mongodb.config.MongoSourceElement; | ||||
| import org.apache.jmeter.protocol.mongodb.mongo.EvalResultHandler; | ||||
| import org.apache.jmeter.protocol.mongodb.mongo.MongoDB; | ||||
| import org.apache.jmeter.samplers.AbstractSampler; | ||||
| import org.apache.jmeter.samplers.Entry; | ||||
| import org.apache.jmeter.samplers.SampleResult; | ||||
| import org.apache.jmeter.testbeans.TestBean; | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| import com.mongodb.DB; | ||||
| 
 | ||||
| /** | ||||
|  */ | ||||
| public class MongoScriptSampler | ||||
|     extends AbstractSampler | ||||
|         implements TestBean { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     public final static String SOURCE = "MongoScriptSampler.source"; //$NON-NLS-1$ | ||||
| 
 | ||||
|     public final static String DATABASE = "MongoScriptSampler.database"; //$NON-NLS-1$ | ||||
|     public final static String USERNAME = "MongoScriptSampler.username"; //$NON-NLS-1$ | ||||
|     public final static String PASSWORD = "MongoScriptSampler.password"; //$NON-NLS-1$ | ||||
| 
 | ||||
|     public final static String SCRIPT = "MongoScriptSampler.script"; //$NON-NLS-1$ | ||||
| 
 | ||||
|     private static final long serialVersionUID = -7789012234636439896L; | ||||
| 
 | ||||
|     public MongoScriptSampler() { | ||||
|         trace("MongoScriptSampler()"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SampleResult sample(Entry e) { | ||||
|         trace("sample()"); | ||||
| 
 | ||||
|         SampleResult res = new SampleResult(); | ||||
|         String data = getScript(); | ||||
| 
 | ||||
|         res.setSampleLabel(getTitle()); | ||||
|         res.setResponseCodeOK(); | ||||
|         res.setResponseCode("200"); | ||||
|         res.setSuccessful(true); | ||||
|         res.setResponseMessageOK(); | ||||
|         res.setSamplerData(data); | ||||
|         res.setDataType(SampleResult.TEXT); | ||||
|         res.setContentType("text/plain"); // $NON-NLS-1$ | ||||
|         res.sampleStart(); | ||||
| 
 | ||||
|         try { | ||||
|             MongoDB mongoDB = MongoSourceElement.getMongoDB(getSource()); | ||||
|             MongoScriptRunner runner = new MongoScriptRunner(); | ||||
|             DB db = mongoDB.getDB(getDatabase(), getUsername(), getPassword()); | ||||
|             res.latencyEnd(); | ||||
|             Object result = runner.evaluate(db, data); | ||||
|             res.sampleEnd(); | ||||
|             EvalResultHandler handler = new EvalResultHandler(); | ||||
|             String resultAsString = handler.handle(result); | ||||
|             res.setResponseData(resultAsString.getBytes()); | ||||
|         } | ||||
|         catch (Exception ex) { | ||||
|             res.sampleEnd(); | ||||
|             log.warn("", ex); | ||||
|             res.setResponseCode("500");// $NON-NLS-1$ | ||||
|             res.setSuccessful(false); | ||||
|             res.setResponseMessage(ex.toString()); | ||||
|             res.setResponseData(ex.getMessage().getBytes()); | ||||
|         } | ||||
|         finally { | ||||
|             res.sampleEnd(); | ||||
|         } | ||||
| 
 | ||||
|         return res; | ||||
|     } | ||||
| 
 | ||||
|     public String getTitle() { | ||||
|         return this.getName(); | ||||
|     } | ||||
| 
 | ||||
|     public String getScript() { | ||||
|         return getPropertyAsString(SCRIPT); | ||||
|     } | ||||
| 
 | ||||
|     public void setScript(String script) { | ||||
|         setProperty(SCRIPT, script); | ||||
|     } | ||||
| 
 | ||||
|     public String getDatabase() { | ||||
|         return getPropertyAsString(DATABASE); | ||||
|     } | ||||
| 
 | ||||
|     public void setDatabase(String database) { | ||||
|         setProperty(DATABASE, database); | ||||
|     } | ||||
| 
 | ||||
|     public String getUsername() { | ||||
|         return getPropertyAsString(USERNAME); | ||||
|     } | ||||
| 
 | ||||
|     public void setUsername(String username) { | ||||
|         setProperty(USERNAME, username); | ||||
|     } | ||||
| 
 | ||||
|     public String getPassword() { | ||||
|         return getPropertyAsString(PASSWORD); | ||||
|     } | ||||
| 
 | ||||
|     public void setPassword(String password) { | ||||
|         setProperty(PASSWORD, password); | ||||
|     } | ||||
| 
 | ||||
|     public String getSource() { | ||||
|         return getPropertyAsString(SOURCE); | ||||
|     } | ||||
| 
 | ||||
|     public void setSource(String source) { | ||||
|         setProperty(SOURCE, source); | ||||
|     } | ||||
| 
 | ||||
|     /* | ||||
|     * Helper | ||||
|     */ | ||||
|     private void trace(String s) { | ||||
|         if(log.isDebugEnabled()) { | ||||
|             log.debug(Thread.currentThread().getName() + " (" + getTitle() + " " + s + " " + this.toString()); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| /* | ||||
|  * Licensed to the Apache Software Foundation (ASF) under one or more | ||||
|  * contributor license agreements.  See the NOTICE file distributed with | ||||
|  * this work for additional information regarding copyright ownership. | ||||
|  * The ASF licenses this file to You under the Apache License, Version 2.0 | ||||
|  * (the "License"); you may not use this file except in compliance with | ||||
|  * the License.  You may obtain a copy of the License at | ||||
|  * | ||||
|  *   http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| package org.apache.jmeter.protocol.mongodb.sampler; | ||||
| 
 | ||||
| import java.beans.PropertyDescriptor; | ||||
| 
 | ||||
| import org.apache.jmeter.testbeans.BeanInfoSupport; | ||||
| import org.apache.jmeter.testbeans.gui.TextAreaEditor; | ||||
| import org.apache.jmeter.testbeans.gui.TypeEditor; | ||||
| import org.apache.jorphan.logging.LoggingManager; | ||||
| import org.apache.log.Logger; | ||||
| 
 | ||||
| /** | ||||
|   */ | ||||
| public class MongoScriptSamplerBeanInfo | ||||
|     extends BeanInfoSupport { | ||||
| 
 | ||||
|     private static final Logger log = LoggingManager.getLoggerForClass(); | ||||
| 
 | ||||
|     public MongoScriptSamplerBeanInfo() { | ||||
|         super(MongoScriptSampler.class); | ||||
| 
 | ||||
|         //http://api.mongodb.org/java/2.7.2/com/mongodb/Mongo.html | ||||
|         createPropertyGroup("mongodb", new String[] { | ||||
|                 "source", | ||||
|                 "database", | ||||
|                 "username", | ||||
|                 "password" }); | ||||
| 
 | ||||
|         createPropertyGroup("sampler", new String[]{ | ||||
|                 "script"}); | ||||
| 
 | ||||
|         PropertyDescriptor p = property("database"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
|         p = property("username"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
|         p = property("password", TypeEditor.PasswordEditor); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
|         p = property("source"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.TRUE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
| 
 | ||||
|         p = property("script"); | ||||
|         p.setValue(NOT_UNDEFINED, Boolean.FALSE); | ||||
|         p.setValue(DEFAULT, ""); | ||||
|         p.setValue(NOT_EXPRESSION, Boolean.TRUE); | ||||
|         p.setPropertyEditorClass(TextAreaEditor.class); | ||||
| 
 | ||||
|         if(log.isDebugEnabled()) { | ||||
|             for (PropertyDescriptor pd : getPropertyDescriptors()) { | ||||
|                 log.debug(pd.getName()); | ||||
|                 log.debug(pd.getDisplayName()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -0,0 +1,14 @@ | |||
| displayName=MongoDB Script | ||||
| mongodb.displayName=MongoDB Connection | ||||
| mongodb.shortDescription=Configure the connection | ||||
| 
 | ||||
| source.displayName=MongoDB Source | ||||
| source.shortDescription=Configure the Source | ||||
| 
 | ||||
| database.displayName=Database Name | ||||
| username.displayName=Username | ||||
| password.displayName=Password | ||||
| 
 | ||||
| sampler.displayName=Script | ||||
| script.displayName=The script to run | ||||
| script.shortDescription=Add your mongo shell script as you would via the mongo shell. | ||||
|  | @ -0,0 +1,14 @@ | |||
| displayName=MongoDB Script | ||||
| mongodb.displayName=MongoDB Connection | ||||
| mongodb.shortDescription=Configure the connection | ||||
| 
 | ||||
| source.displayName=MongoDB Source | ||||
| source.shortDescription=Configure the Source | ||||
| 
 | ||||
| database.displayName=Database Name | ||||
| username.displayName=Username | ||||
| password.displayName=Password | ||||
| 
 | ||||
| sampler.displayName=Script | ||||
| script.displayName=The script to run | ||||
| script.shortDescription=Add your mongo shell script as you would via the mongo shell. | ||||
|  | @ -167,6 +167,7 @@ This does not affect JMeter operation. | |||
| 
 | ||||
| <h3>General</h3> | ||||
| <ul> | ||||
| <li><bugzilla>54584</bugzilla> - MongoDB plugin</li> | ||||
| </ul> | ||||
| 
 | ||||
| <h2>Non-functional changes</h2> | ||||
|  |  | |||
|  | @ -1862,6 +1862,17 @@ If omitted, output is captured and returned as the response data.</property> | |||
| <property name="Expected Return Code" required="No">Expected return code for System Call, required if "Check Return Code" is checked.</property> | ||||
| </component> | ||||
| 
 | ||||
| <component name="MongoDB Script" index="§-num;.1.21" width="519" height="289" screenshot="mongodb-sampler.png"> | ||||
| <description> | ||||
| TODO</description> | ||||
| <properties> | ||||
|          | ||||
| </properties> | ||||
| <links> | ||||
| </links> | ||||
| 
 | ||||
| </component> | ||||
| 
 | ||||
| <a href="#">^</a> | ||||
| 
 | ||||
| </section> | ||||
|  | @ -3921,6 +3932,16 @@ GUI that they can use while developing new JMeter components.</p> | |||
| 
 | ||||
| </component> | ||||
| 
 | ||||
| <component name="MongoDB Source Config" index="§-num;.4.18" width="519" height="289" screenshot="mongodb-config.png"> | ||||
| <description> | ||||
| TODO</description> | ||||
| <properties> | ||||
|          | ||||
| </properties> | ||||
| <links> | ||||
| </links> | ||||
| 
 | ||||
| </component> | ||||
| 
 | ||||
| <a href="#">^</a> | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue