Skip to content

Commit

Permalink
BZ 64752 - Add GraphQL/HTTP Request Sampler (apache#627)
Browse files Browse the repository at this point in the history
* BZ-64752: adding GraphQL HTTP Sampler GUI components

* BZ-64752: javadocs

* BZ-64752: fixing tab selection problem; disable tab validation in graphql ui

* BZ-64752: (de)serializing test element with graphql query and vars

* BZ-64752: (de)serializing using gson

* BZ-64752: removing unnecessary GraphQLHTTPSampler

* BZ-64752: adding operationName input field

* BZ-64752: support GET method

* BZ-64752: init operationName from test elem

* BZ-64752: adding a simple graphql test plan demo

* BZ-64752: show advanced pane

* BZ-64752: add gson info to lib/aareadme.txt

* BZ-64752: screenshot and default constructor

* BZ-64752: documentation on GraphQLHTTPRequest

* BZ-64752: record in changes.xml

* BZ-64752: add gson.jar to expected_release_jars.csv

* BZ-64752: removing unnecessary, untranslated messages

* BZ-64752: utility for graphql param serialization and unit test

* BZ-64752: replace gson with jackson for graphql (de)serialization

* BZ-64752: remove gson jar from expected release jars

* BZ-64752: correcting French translation, thanks to pmouawad

* BZ-64752: graphql http recording support

* BZ-64752: checkbox option to switch on/off auto graphql req detection, true by default

* BZ-64752: precise json content type checking; encode in GET

* BZ-64752: French translation for graphql recording option, thanks to @ubikloadpack

Co-authored-by: Woonsan Ko <[email protected]>
  • Loading branch information
woonsan and woonsanko authored Oct 4, 2020
1 parent b17ac36 commit 82e56be
Show file tree
Hide file tree
Showing 27 changed files with 1,596 additions and 80 deletions.
1 change: 1 addition & 0 deletions bin/saveservice.properties
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ GaussianRandomTimerGui=org.apache.jmeter.timers.gui.GaussianRandomTimerGui
GenericController=org.apache.jmeter.control.GenericController
GraphAccumVisualizer=org.apache.jmeter.visualizers.GraphAccumVisualizer
GraphVisualizer=org.apache.jmeter.visualizers.GraphVisualizer
GraphQLHTTPSamplerGui=org.apache.jmeter.protocol.http.control.gui.GraphQLHTTPSamplerGui
Header=org.apache.jmeter.protocol.http.control.Header
HeaderManager=org.apache.jmeter.protocol.http.control.HeaderManager
HeaderPanel=org.apache.jmeter.protocol.http.gui.HeaderPanel
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public String serializedClass(@SuppressWarnings("rawtypes") // superclass does n
private static String fileVersion = ""; // computed from saveservice.properties file// $NON-NLS-1$
// Must match the sha1 checksum of the file saveservice.properties (without newline character),
// used to ensure saveservice.properties and SaveService are updated simultaneously
static final String FILEVERSION = "56ae8319b2b02d33eb1028c4460db770cf246b5c"; // Expected value $NON-NLS-1$
static final String FILEVERSION = "66ea47f7da884dff1c42ccede75113971c5c11f3"; // Expected value $NON-NLS-1$

private static String fileEncoding = ""; // read from properties file// $NON-NLS-1$

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jexl3 = text/java
jpython = text/python
js = text/javascript
jscript = text/javascript
json = text/json
judoscript = text/plain
jython = text/python
lisp = text/lisp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ deltest=Deletion test
deref=Dereference aliases
description=Description
detail=Detail
detect_graphql_request=Detect GraphQL Request
directory_field_title=Working directory:
disable=Disable
dn=DN
Expand Down Expand Up @@ -449,6 +450,11 @@ graph_results_ms=ms
graph_results_no_samples=No of Samples
graph_results_throughput=Throughput
graph_results_title=Graph Results
graphql_http_sampler_title=GraphQL HTTP Request
graphql_request_info=GraphQL Request
graphql_operation_name=Operation Name
graphql_query=Query
graphql_variables=Variables
groovy_function_expression=Expression to evaluate
grouping_add_separators=Add separators between groups
grouping_in_controllers=Put each group in a new controller
Expand Down Expand Up @@ -864,6 +870,7 @@ proxy_headers=Capture HTTP Headers
proxy_pause_http_sampler=Create new transaction after request (ms)\:
proxy_recorder_dialog=Recorder\: Transactions Control
proxy_regex=Regex matching
proxy_sampler_graphql_settings=GraphQL HTTP Sampler settings
proxy_sampler_settings=HTTP Sampler settings
proxy_sampler_type=Type\:
proxy_separators=Add Separators
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ deltest=Suppression
deref=Déréférencement des alias
description=Description
detail=Détail
detect_graphql_request=Détecter les requêtes GraphQL
directory_field_title=Répertoire d'exécution \:
disable=Désactiver
dn=Racine DN \:
Expand Down Expand Up @@ -443,6 +444,11 @@ graph_results_ms=ms
graph_results_no_samples=Nombre d'échantillons
graph_results_throughput=Débit
graph_results_title=Graphique de résultats
graphql_http_sampler_title=Requête HTTP GraphQL
graphql_request_info=Requête GraphQL
graphql_operation_name=Nom de l'opération
graphql_query=Requête
graphql_variables=Variables
groovy_function_expression=Expression à évaluer
grouping_add_separators=Ajouter des séparateurs entre les groupes
grouping_in_controllers=Mettre chaque groupe dans un nouveau contrôleur
Expand Down Expand Up @@ -853,6 +859,7 @@ proxy_headers=Capturer les entêtes HTTP
proxy_pause_http_sampler=Créer une nouvelle transaction après la requête (ms) \:
proxy_recorder_dialog=Enregistreur\: Contrôle des transactions
proxy_regex=Correspondance des variables par regex ?
proxy_sampler_graphql_settings=Configuration de la requête GraphQL
proxy_sampler_settings=Paramètres Echantillon HTTP
proxy_sampler_type=Type \:
proxy_separators=Ajouter des séparateurs
Expand Down
2 changes: 2 additions & 0 deletions src/protocol/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ project("http") {
implementation("org.apache.httpcomponents:httpcore")
implementation("org.brotli:dec")
implementation("com.miglayout:miglayout-swing")
implementation("com.fasterxml.jackson.core:jackson-core")
implementation("com.fasterxml.jackson.core:jackson-databind")
testImplementation(testFixtures(project(":src:testkit-wiremock")))
testImplementation("com.github.tomakehurst:wiremock-jre8")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.http.config;

import java.io.Serializable;

/**
* Represents GraphQL request parameter input data for Query, Variables and Operation Name.
*/
public class GraphQLRequestParams implements Serializable {

private static final long serialVersionUID = 1L;

private String operationName;

private String query;

private String variables;

public GraphQLRequestParams() {
}

public GraphQLRequestParams(final String operationName, final String query, final String variables) {
this.operationName = operationName;
this.query = query;
this.variables = variables;
}

public String getOperationName() {
return operationName;
}

public void setOperationName(String operationName) {
this.operationName = operationName;
}

public String getQuery() {
return query;
}

public void setQuery(String query) {
this.query = query;
}

public String getVariables() {
return variables;
}

public void setVariables(String variables) {
this.variables = variables;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* 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.http.config.gui;

import javax.swing.JTabbedPane;

/**
* Abstract {@link JTabbedPane} to allow validating the requested tab index, updating states and changing the tab index
* after the validation if necessary.
*/
abstract class AbstractValidationTabbedPane extends JTabbedPane {

private static final long serialVersionUID = 7014311238367882880L;

/**
* Flag whether the validation feature should be enabled or not, {@code true} by default.
*/
private boolean validationEnabled = true;

/**
* {@inheritDoc}
* <P>
* Overridden to delegate to {@link #setSelectedIndex(int, boolean)} in order to validate the requested tab index by default.
*/
@Override
public void setSelectedIndex(int index) {
setSelectedIndex(index, true);
}

/**
* Apply some check rules by invoking {@link #getValidatedTabIndex(int, int)}
* if {@link #isValidationEnabled()} returns true and the {@code check} input is true.
*
* @param index index to select
* @param check flag whether to perform checks before setting the selected index
*/
public void setSelectedIndex(int index, boolean check) {
final int curIndex = super.getSelectedIndex();

if (!isValidationEnabled() || !check || curIndex == -1) {
super.setSelectedIndex(index);
return;
}

super.setSelectedIndex(getValidatedTabIndex(curIndex, index));
}

/**
* Validate the requested tab index ({@code newTabIndex}) and return a validated tab index after applying some check rules.
* @param currentTabIndex current tab index
* @param newTabIndex new requested tab index to validate
* @return the validated tab index
*/
abstract protected int getValidatedTabIndex(final int currentTabIndex, final int newTabIndex);

/**
* Return true if the validation feature should be enabled, {@code true} by default.
* @return true if the validation feature should be enabled, {@code true} by default
*/
protected boolean isValidationEnabled() {
return validationEnabled;
}

/**
* Set the flag whether the validation feature should be enabled or not.
* @param validationEnabled flag whether the validation feature should be enabled or not
*/
protected void setValidationEnabled(boolean validationEnabled) {
this.validationEnabled = validationEnabled;
}
}
Loading

0 comments on commit 82e56be

Please sign in to comment.