/* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch 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.elasticsearch.test.rest; import com.google.common.collect.Maps; import org.elasticsearch.Version; import org.elasticsearch.common.logging.ESLogger; import org.elasticsearch.common.logging.Loggers; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.xcontent.XContentFactory; import org.elasticsearch.test.rest.client.RestClient; import org.elasticsearch.test.rest.client.RestException; import org.elasticsearch.test.rest.client.RestResponse; import org.elasticsearch.test.rest.spec.RestSpec; import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Execution context passed across the REST tests. * Holds the REST client used to communicate with elasticsearch. * Caches the last obtained test response and allows to stash part of it within variables * that can be used as input values in following requests. */ public class RestTestExecutionContext implements Closeable { private static final ESLogger logger = Loggers.getLogger(RestTestExecutionContext.class); private final Stash stash = new Stash(); private final RestSpec restSpec; private RestClient restClient; private RestResponse response; public RestTestExecutionContext(RestSpec restSpec) { this.restSpec = restSpec; } /** * Calls an elasticsearch api with the parameters and request body provided as arguments. * Saves the obtained response in the execution context. * @throws RestException if the returned status code is non ok */ public RestResponse callApi(String apiName, Map<String, String> params, List<Map<String, Object>> bodies, Map<String, String> headers) throws IOException, RestException { //makes a copy of the parameters before modifying them for this specific request HashMap<String, String> requestParams = Maps.newHashMap(params); for (Map.Entry<String, String> entry : requestParams.entrySet()) { if (stash.isStashedValue(entry.getValue())) { entry.setValue(stash.unstashValue(entry.getValue()).toString()); } } String body = actualBody(bodies); try { response = callApiInternal(apiName, requestParams, body, headers); //we always stash the last response body stash.stashValue("body", response.getBody()); return response; } catch(RestException e) { response = e.restResponse(); throw e; } } private String actualBody(List<Map<String, Object>> bodies) throws IOException { if (bodies.isEmpty()) { return ""; } if (bodies.size() == 1) { return bodyAsString(stash.unstashMap(bodies.get(0))); } StringBuilder bodyBuilder = new StringBuilder(); for (Map<String, Object> body : bodies) { bodyBuilder.append(bodyAsString(stash.unstashMap(body))).append("\n"); } return bodyBuilder.toString(); } private String bodyAsString(Map<String, Object> body) throws IOException { return XContentFactory.jsonBuilder().map(body).string(); } private RestResponse callApiInternal(String apiName, Map<String, String> params, String body, Map<String, String> headers) throws IOException, RestException { return restClient.callApi(apiName, params, body, headers); } /** * Extracts a specific value from the last saved response */ public Object response(String path) throws IOException { return response.evaluate(path, stash); } /** * Creates the embedded REST client when needed. Needs to be called before each test. */ public void initClient(InetSocketAddress[] addresses, Settings settings) throws IOException, RestException { if (restClient == null) { restClient = new RestClient(restSpec, settings, addresses); } } /** * Clears the last obtained response and the stashed fields */ public void clear() { logger.debug("resetting client, response and stash"); response = null; stash.clear(); } public Stash stash() { return stash; } /** * Returns the current es version as a string */ public Version esVersion() { return restClient.getEsVersion(); } /** * Closes the execution context and releases the underlying resources */ @Override public void close() { if (restClient != null) { restClient.close(); } } }