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

(-)a/src/components/src/main/java/org/apache/jmeter/extractor/json/jsonpath/JSONManager.java (-1 / +1 lines)
Lines 95-101 public class JSONManager { Link Here
95
        if (obj instanceof JSONArray) {
95
        if (obj instanceof JSONArray) {
96
            return ((JSONArray)obj).toJSONString();
96
            return ((JSONArray)obj).toJSONString();
97
        }
97
        }
98
        return obj == null ? "" : obj.toString(); //$NON-NLS-1$
98
        return obj == null ? null : obj.toString();
99
    }
99
    }
100
100
101
}
101
}
(-)a/src/components/src/main/java/org/apache/jmeter/extractor/json/jsonpath/JSONPostProcessor.java (-26 / +25 lines)
Lines 81-90 public class JSONPostProcessor Link Here
81
            clearOldRefVars(vars, currentRefName);
81
            clearOldRefVars(vars, currentRefName);
82
            try {
82
            try {
83
                if (jsonResponses.isEmpty()) {
83
                if (jsonResponses.isEmpty()) {
84
                    handleEmptyResponse(vars, defaultValues, i, currentRefName);
84
                    handleEmptyResponse(vars, defaultValues[i], currentRefName);
85
                } else {
85
                } else {
86
                    List<Object> extractedValues = extractValues(jsonResponses, currentJsonPath);
86
                    List<Object> extractedValues = extractValues(jsonResponses, currentJsonPath);
87
                    handleResult(vars, defaultValues, i, matchNumber, currentRefName, extractedValues);
87
                    handleResult(vars, defaultValues[i], matchNumber, currentRefName, extractedValues);
88
                }
88
                }
89
            } catch (Exception e) {
89
            } catch (Exception e) {
90
                if (log.isDebugEnabled()) {
90
                if (log.isDebugEnabled()) {
Lines 98-110 public class JSONPostProcessor Link Here
98
        }
98
        }
99
    }
99
    }
100
100
101
    private void handleResult(JMeterVariables vars, String[] defaultValues, int i, int matchNumber,
101
    private void handleResult(JMeterVariables vars, String defaultValue, int matchNumber, String currentRefName,
102
            String currentRefName, List<Object> extractedValues) {
102
            List<Object> extractedValues) {
103
        // if no values extracted, default value added
103
        // if no values extracted, default value added
104
        if (extractedValues.isEmpty()) {
104
        if (extractedValues.isEmpty()) {
105
            handleEmptyResult(vars, defaultValues, i, matchNumber, currentRefName);
105
            handleEmptyResult(vars, defaultValue, matchNumber, currentRefName);
106
        } else {
106
        } else {
107
            handleNonEmptyResult(vars, defaultValues, i, matchNumber, currentRefName, extractedValues);
107
            handleNonEmptyResult(vars, defaultValue, matchNumber, currentRefName, extractedValues);
108
        }
108
        }
109
    }
109
    }
110
110
Lines 116-129 public class JSONPostProcessor Link Here
116
        return extractedValues;
116
        return extractedValues;
117
    }
117
    }
118
118
119
    private void handleNonEmptyResult(JMeterVariables vars, String[] defaultValues, int i, int matchNumber,
119
    private void handleNonEmptyResult(JMeterVariables vars, String defaultValue, int matchNumber, String currentRefName,
120
            String currentRefName, List<Object> extractedValues) {
120
            List<Object> extractedValues) {
121
        // if more than one value extracted, suffix with "_index"
121
        // if more than one value extracted, suffix with "_index"
122
        if (extractedValues.size() > 1) {
122
        if (extractedValues.size() > 1) {
123
            handleListResult(vars, defaultValues, i, matchNumber, currentRefName, extractedValues);
123
            handleListResult(vars, defaultValue, matchNumber, currentRefName, extractedValues);
124
        } else {
124
        } else {
125
            // else just one value extracted
125
            // else just one value extracted
126
            handleSingleResult(vars, matchNumber, currentRefName, extractedValues);
126
            handleSingleResult(vars, defaultValue, matchNumber, currentRefName, extractedValues);
127
        }
127
        }
128
        if (matchNumber != 0) {
128
        if (matchNumber != 0) {
129
            vars.put(currentRefName + REF_MATCH_NR, Integer.toString(extractedValues.size()));
129
            vars.put(currentRefName + REF_MATCH_NR, Integer.toString(extractedValues.size()));
Lines 142-158 public class JSONPostProcessor Link Here
142
        }
142
        }
143
    }
143
    }
144
144
145
    private void handleSingleResult(JMeterVariables vars, final int matchNumber, String currentRefName,
145
    private void handleSingleResult(JMeterVariables vars, String defaultValue,  final int matchNumber, String currentRefName,
146
            List<Object> extractedValues) {
146
            List<Object> extractedValues) {
147
        String suffix = (matchNumber < 0) ? "_1" : "";
147
        String suffix = (matchNumber < 0) ? "_1" : "";
148
        placeObjectIntoVars(vars, currentRefName + suffix, extractedValues, 0);
148
        placeObjectIntoVars(vars, currentRefName + suffix, extractedValues, 0, defaultValue);
149
        if (matchNumber < 0 && getComputeConcatenation()) {
149
        if (matchNumber < 0 && getComputeConcatenation()) {
150
            vars.put(currentRefName + ALL_SUFFIX, vars.get(currentRefName + suffix));
150
            vars.put(currentRefName + ALL_SUFFIX, vars.get(currentRefName + suffix));
151
        }
151
        }
152
    }
152
    }
153
153
154
    private void handleListResult(JMeterVariables vars, String[] defaultValues, final int i, final int matchNumber,
154
    private void handleListResult(JMeterVariables vars, String defaultValue, final int matchNumber, String currentRefName,
155
            String currentRefName, List<Object> extractedValues) {
155
            List<Object> extractedValues) {
156
        if (matchNumber < 0) {
156
        if (matchNumber < 0) {
157
            // Extract all
157
            // Extract all
158
            int index = 1;
158
            int index = 1;
Lines 161-167 public class JSONPostProcessor Link Here
161
                            ? extractedValues.size() * 20
161
                            ? extractedValues.size() * 20
162
                            : 1);
162
                            : 1);
163
            for (Object extractedObject : extractedValues) {
163
            for (Object extractedObject : extractedValues) {
164
                String extractedString = stringify(extractedObject);
164
                String extractedString = StringUtils.defaultString(stringify(extractedObject), defaultValue);
165
                vars.put(currentRefName + "_" + index,
165
                vars.put(currentRefName + "_" + index,
166
                        extractedString); //$NON-NLS-1$
166
                        extractedString); //$NON-NLS-1$
167
                if (getComputeConcatenation()) {
167
                if (getComputeConcatenation()) {
Lines 181-187 public class JSONPostProcessor Link Here
181
            int matchSize = extractedValues.size();
181
            int matchSize = extractedValues.size();
182
            int matchNr = JMeterUtils.getRandomInt(matchSize);
182
            int matchNr = JMeterUtils.getRandomInt(matchSize);
183
            placeObjectIntoVars(vars, currentRefName,
183
            placeObjectIntoVars(vars, currentRefName,
184
                    extractedValues, matchNr);
184
                    extractedValues, matchNr, defaultValue);
185
            return;
185
            return;
186
        }
186
        }
187
        // extract at position
187
        // extract at position
Lines 191-205 public class JSONPostProcessor Link Here
191
                    "matchNumber({}) exceeds number of items found({}), default value will be used",
191
                    "matchNumber({}) exceeds number of items found({}), default value will be used",
192
                        matchNumber, extractedValues.size());
192
                        matchNumber, extractedValues.size());
193
            }
193
            }
194
            vars.put(currentRefName, defaultValues[i]);
194
            vars.put(currentRefName, defaultValue);
195
        } else {
195
        } else {
196
            placeObjectIntoVars(vars, currentRefName, extractedValues, matchNumber - 1);
196
            placeObjectIntoVars(vars, currentRefName, extractedValues, matchNumber - 1, defaultValue);
197
        }
197
        }
198
    }
198
    }
199
199
200
    private void handleEmptyResult(JMeterVariables vars, String[] defaultValues, int i, int matchNumber,
200
    private void handleEmptyResult(JMeterVariables vars, String defaultValue, int matchNumber, String currentRefName) {
201
            String currentRefName) {
201
        vars.put(currentRefName, defaultValue);
202
        vars.put(currentRefName, defaultValues[i]);
203
        vars.put(currentRefName + REF_MATCH_NR, "0"); //$NON-NLS-1$
202
        vars.put(currentRefName + REF_MATCH_NR, "0"); //$NON-NLS-1$
204
        if (matchNumber < 0 && getComputeConcatenation()) {
203
        if (matchNumber < 0 && getComputeConcatenation()) {
205
            log.debug("No value extracted, storing empty in: {}{}", currentRefName, ALL_SUFFIX);
204
            log.debug("No value extracted, storing empty in: {}{}", currentRefName, ALL_SUFFIX);
Lines 207-217 public class JSONPostProcessor Link Here
207
        }
206
        }
208
    }
207
    }
209
208
210
    private void handleEmptyResponse(JMeterVariables vars, String[] defaultValues, int i, String currentRefName) {
209
    private void handleEmptyResponse(JMeterVariables vars, String defaultValue, String currentRefName) {
211
        if(log.isDebugEnabled()) {
210
        if(log.isDebugEnabled()) {
212
            log.debug("Response or source variable is null or empty for {}", getName());
211
            log.debug("Response or source variable is null or empty for {}", getName());
213
        }
212
        }
214
        vars.put(currentRefName, defaultValues[i]);
213
        vars.put(currentRefName, defaultValue);
215
    }
214
    }
216
215
217
    private List<String> extractJsonResponse(JMeterContext context, JMeterVariables vars) {
216
    private List<String> extractJsonResponse(JMeterContext context, JMeterVariables vars) {
Lines 245-257 public class JSONPostProcessor Link Here
245
    }
244
    }
246
245
247
    private void placeObjectIntoVars(JMeterVariables vars, String currentRefName,
246
    private void placeObjectIntoVars(JMeterVariables vars, String currentRefName,
248
            List<Object> extractedValues, int matchNr) {
247
            List<Object> extractedValues, int matchNr, String defaultValue) {
249
        vars.put(currentRefName,
248
        vars.put(currentRefName,
250
                stringify(extractedValues.get(matchNr)));
249
                StringUtils.defaultString(stringify(extractedValues.get(matchNr)), defaultValue));
251
    }
250
    }
252
251
253
    private String stringify(Object obj) {
252
    private String stringify(Object obj) {
254
        return obj == null ? "" : obj.toString(); //$NON-NLS-1$
253
        return obj == null ? null : obj.toString();
255
    }
254
    }
256
255
257
    public String getJsonPathExpressions() {
256
    public String getJsonPathExpressions() {
(-)a/src/components/src/test/java/org/apache/jmeter/extractor/TestJSONPostProcessor.java (-8 / +18 lines)
Lines 212-236 class TestJSONPostProcessor { Link Here
212
        assertThat(vars.get("varname_2"), CoreMatchers.is(CoreMatchers.nullValue()));
212
        assertThat(vars.get("varname_2"), CoreMatchers.is(CoreMatchers.nullValue()));
213
    }
213
    }
214
214
215
    @Test
215
    private static Stream<Arguments> provideEmptyOrNullResultArgs() {
216
    void testEmptyInput() throws ParseException {
216
        return Stream.of(
217
                Arguments.of("{\"context\": null}", "$.context", "0", null, "NONE"), // bug 65681
218
                Arguments.of("[{\"context\": null}, {\"context\": \"\"}]", "$[*].context", "1", "2", "NONE"),
219
                Arguments.of("[{\"context\": null}, {\"context\": \"\"}]", "$[*].context", "2", "2", ""),
220
                Arguments.of("{\"context\": \"\"}", "$.context", "0", null, ""),
221
                Arguments.of("", "$.context", "0", null, "NONE"));
222
    }
223
224
    @ParameterizedTest
225
    @MethodSource("provideEmptyOrNullResultArgs")
226
    void testEmptyOrNullResult(String contextValue, String jsonPath, String matchNumber, String expectedMatchNumber,
227
            String expectedResult) throws ParseException {
217
        JMeterContext context = JMeterContextService.getContext();
228
        JMeterContext context = JMeterContextService.getContext();
218
        JSONPostProcessor processor = setupProcessor(context, "0", false);
229
        JSONPostProcessor processor = setupProcessor(context, matchNumber, false);
219
230
220
        SampleResult result = new SampleResult();
231
        SampleResult result = new SampleResult();
221
        result.setResponseData("".getBytes(StandardCharsets.UTF_8));
232
        result.setResponseData(contextValue.getBytes(StandardCharsets.UTF_8));
222
233
223
        JMeterVariables vars = new JMeterVariables();
234
        JMeterVariables vars = new JMeterVariables();
224
        context.setVariables(vars);
235
        context.setVariables(vars);
225
        context.setPreviousResult(result);
236
        context.setPreviousResult(result);
226
237
227
        processor.setJsonPathExpressions("$.context");
238
        processor.setJsonPathExpressions(jsonPath);
228
        processor.setDefaultValues("NONE");
239
        processor.setDefaultValues("NONE");
229
        processor.setScopeAll();
240
        processor.setScopeAll();
230
        processor.process();
241
        processor.process();
231
242
232
        assertThat(vars.get(VAR_NAME), CoreMatchers.is("NONE"));
243
        assertThat(vars.get(VAR_NAME), CoreMatchers.is(expectedResult));
233
        assertThat(vars.get(VAR_NAME + "_matchNr"), CoreMatchers.nullValue());
244
        assertThat(vars.get(VAR_NAME + "_matchNr"), CoreMatchers.is(expectedMatchNumber));
234
        assertThat(vars.get(VAR_NAME + "_1"), CoreMatchers.is(CoreMatchers.nullValue()));
245
        assertThat(vars.get(VAR_NAME + "_1"), CoreMatchers.is(CoreMatchers.nullValue()));
235
    }
246
    }
236
247
237
- 

Return to bug 65681