All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.gematik.test.tiger.lib.TigerHttpClient Maven / Gradle / Ivy

/*
 * Copyright 2024 gematik GmbH
 *
 * Licensed 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 de.gematik.test.tiger.lib;

import de.gematik.rbellogger.data.RbelElement;
import de.gematik.rbellogger.writer.RbelContentType;
import de.gematik.rbellogger.writer.RbelSerializationResult;
import de.gematik.test.tiger.RbelLoggerWriter;
import de.gematik.test.tiger.common.config.TigerConfigurationKey;
import de.gematik.test.tiger.common.config.TigerGlobalConfiguration;
import de.gematik.test.tiger.common.config.TigerTypedConfigurationKey;
import de.gematik.test.tiger.common.jexl.TigerJexlContext;
import de.gematik.test.tiger.common.util.ResetableLazyInitializer;
import de.gematik.test.tiger.lib.exception.TigerHttpGlueCodeException;
import io.restassured.RestAssured;
import io.restassured.config.EncoderConfig;
import io.restassured.config.RedirectConfig;
import io.restassured.http.Method;
import io.restassured.internal.RequestSpecificationImpl;
import io.restassured.specification.QueryableRequestSpecification;
import io.restassured.specification.RequestSpecification;
import java.net.URI;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.api.SoftAssertionsProvider;

/**
 * This class provides methods to send requests with RestAssured. It also provides methods to
 * resolve placeholders in the request body and send the resolved body.
 */
public class TigerHttpClient {

  public static final String KEY_HTTP_CLIENT = "httpClient";
  public static final String KEY_TIGER = "tiger";
  public static final String KEY_DEFAULT_HEADER = "defaultHeader";

  private static final ResetableLazyInitializer RBEL_LOGGER_WRITER =
      new ResetableLazyInitializer<>(RbelLoggerWriter::new);

  private static final TigerTypedConfigurationKey executeBlocking =
      new TigerTypedConfigurationKey<>(
          new TigerConfigurationKey(KEY_TIGER, KEY_HTTP_CLIENT, "executeBlocking"),
          Boolean.class,
          true);
  private static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;

  private TigerHttpClient() {
    // do not instantiate
  }

  public static void reset() {
    // creating a new instance of the RbelLoggerWriter loads configuration from the
    // TigerGlobalConfiguration
    // If we use different configuration in different unit tests we need to reset this instance.
    RBEL_LOGGER_WRITER.reset();
  }

  /**
   * Create a configurable RequestSpecification with default Tiger headers. Example:
   *
   * 
   *  givenDefaultSpec()
   *    .formParams(resolveMap(dataAsMaps.get(0), true))
   *    .headers(Map.of("header", "value"))
   *    .contentType(ContentType.JSON)
   *    .request(method, address));
   * 
* * @return configurable RequestSpecification */ public static RequestSpecification givenDefaultSpec() { var encoderConfig = RestAssured.config() .getEncoderConfig() .appendDefaultContentCharsetToContentTypeIfUndefined(true); var requestSpecification = RestAssured.given() .urlEncodingEnabled(false) .config(RestAssured.config().encoderConfig(encoderConfig)); requestSpecification.headers( TigerGlobalConfiguration.readMap(KEY_TIGER, KEY_HTTP_CLIENT, KEY_DEFAULT_HEADER)); Optional.ofNullable(((QueryableRequestSpecification) requestSpecification).getContentType()) .ifPresent(ct -> setExactContentTypeHeader(requestSpecification, ct)); return requestSpecification; } /** * Execute a command in the background. This is useful for long-running tasks that should not * block the main thread. * * @param command the command to execute */ public static void executeCommandInBackground(SoftAssertionsProvider.ThrowingRunnable command) { TigerDirector.getTigerTestEnvMgr() .getCachedExecutor() .submit( () -> { try { command.run(); } catch (Exception e) { throw new TigerHttpGlueCodeException("Error during request execution", e); } }); } /** * Execute a command with a contingent wait. If the configuration value `executeBlocking` is set * to `true`, the command is executed immediately. Otherwise, the command is executed in the * background. * * @param command the command to execute */ public static void executeCommandWithContingentWait( SoftAssertionsProvider.ThrowingRunnable command) { if (Boolean.TRUE.equals(executeBlocking.getValueOrDefault())) { try { command.run(); } catch (Exception e) { throw new TigerHttpGlueCodeException("Error during request execution", e); } } else { executeCommandInBackground(command); } } /** * Apply a new RedirectConfig to the RestAssured configuration. * * @param newRedirectConfig the new RedirectConfig to apply */ public static void applyRedirectConfig(RedirectConfig newRedirectConfig) { RestAssured.config = RestAssured.config.redirect(newRedirectConfig); } /** Reset the RedirectConfig to the default configuration. */ public static void resetRedirectConfig() { applyRedirectConfig(new RedirectConfig()); } /** * Resolve placeholders in the given value and return the result as a string. * * @param value the value to resolve * @return the value, but resolved */ public static String resolveToString(String value) { return resolve(value).getContentAsString(); } /** * Resolve placeholders in the given value and return the result as a byte array. * * @param value the value to resolve * @return the value, but resolved as a byte array */ public static RbelSerializationResult resolve(String value) { final String resolvedInput = TigerGlobalConfiguration.resolvePlaceholders(value); if (TigerDirector.getLibConfig().getHttpClientConfig().isActivateRbelWriter()) { final RbelElement input = RBEL_LOGGER_WRITER.get().getRbelConverter().convertElement(resolvedInput, null); return RBEL_LOGGER_WRITER .get() .getRbelWriter() .serialize(input, new TigerJexlContext().withRootElement(input)); } else { return RbelSerializationResult.withUnknownType(resolvedInput.getBytes(DEFAULT_CHARSET)); } } /** * Send a request with the given method, address and body. The body is resolved before sending. * * @param method the HTTP method to use * @param address the URI to send the request to * @param body the body (which is to be resolved) of the request */ public static void sendResolvedBody(Method method, URI address, String body) { sendResolvedBody(method, address, null, body); } /** * Send a request with the given method, address and body. The body is resolved before sending. * * @param method the HTTP method to use * @param address the URI to send the request to * @param contentType the content type of the request * @param body the body (which is to be resolved) of the request */ public static void sendResolvedBody(Method method, URI address, String contentType, String body) { final RbelSerializationResult resolved = resolve(body); final RequestSpecification requestSpecification = givenDefaultSpec(); if (contentType != null) { setExactContentTypeHeader(requestSpecification, contentType); } resolved .getContentType() .map(RbelContentType::getContentTypeString) .filter( o -> StringUtils.isEmpty( ((RequestSpecificationImpl) requestSpecification).getContentType())) .ifPresent(requestSpecification::contentType); requestSpecification.body(resolved.getContent()).request(method, address); } private static void setExactContentTypeHeader( RequestSpecification requestSpecification, String contentType) { requestSpecification.config( RestAssured.config() .encoderConfig( EncoderConfig.encoderConfig() .appendDefaultContentCharsetToContentTypeIfUndefined(false))); requestSpecification.contentType(contentType); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy