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

de.gematik.test.tiger.zion.controller.CatchAllController Maven / Gradle / Ivy

The newest version!
/*
 * 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.zion.controller;

import static org.springframework.web.bind.annotation.RequestMethod.*;

import com.fasterxml.jackson.databind.ObjectMapper;
import de.gematik.rbellogger.RbelLogger;
import de.gematik.rbellogger.data.RbelElement;
import de.gematik.rbellogger.data.RbelHostname;
import de.gematik.rbellogger.writer.RbelWriter;
import de.gematik.test.tiger.zion.config.TigerMockResponse;
import de.gematik.test.tiger.zion.config.ZionConfiguration;
import de.gematik.test.tiger.zion.services.BackendRequestExecutor;
import de.gematik.test.tiger.zion.services.ZionRequestExecutor;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.nio.file.Path;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

@RestController
@RequestMapping("/")
@RequiredArgsConstructor
@Slf4j
public class CatchAllController implements WebMvcConfigurer {

  private final RbelLogger rbelLogger;
  private final RbelWriter rbelWriter;
  private final ZionConfiguration configuration;
  private final ObjectMapper objectMapper;
  private final ServletWebServerApplicationContext webServerAppCtxt;
  private final BackendRequestExecutor backendRequestExecutor;

  @SneakyThrows
  @PostConstruct
  public void loadMockReponsesFromFile() {
    if (configuration.getMockResponseFiles() == null
        || configuration.getMockResponseFiles().isEmpty()) {
      log.info("Skipping initialization for mock-responses from files, none specified");
      return;
    }
    for (Entry entry : configuration.getMockResponseFiles().entrySet()) {
      final File file = Path.of(entry.getValue()).toFile();
      try (final FileInputStream fileInputStream = new FileInputStream(file)) {
        final TigerMockResponse mockResponse =
            new Yaml(new Constructor(TigerMockResponse.class, new LoaderOptions()))
                .load(fileInputStream);
        configuration.getMockResponses().put(entry.getKey(), mockResponse);
        log.info(
            "Successfully added mock-response from file {} with criteria {}",
            file.getAbsolutePath(),
            String.join(", ", mockResponse.getRequestCriterions()));
      }
    }
  }

  @RequestMapping(
      value = "**",
      consumes = {"*/*", "application/*"},
      produces = "*/*",
      method = {GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE}) // NOSONAR
  public ResponseEntity masterResponder(
      RequestEntity request, HttpServletRequest servletRequest) {
    final LocalDateTime responseStartTime = LocalDateTime.now();
    log.info("Got new request {} {}", request.getMethod(), request.getUrl());

    byte[] rawMessage = buildRawMessageApproximate(request);
    final RbelHostname client =
        RbelHostname.builder()
            .hostname(servletRequest.getRemoteHost())
            .port(servletRequest.getRemotePort())
            .build();
    final RbelHostname server =
        RbelHostname.builder()
            .hostname(servletRequest.getLocalAddr())
            .port(servletRequest.getLocalPort())
            .build();
    final RbelElement requestRbelMessage =
        rbelLogger
            .getRbelConverter()
            .parseMessage(rawMessage, client, server, Optional.of(ZonedDateTime.now()));

    final ResponseEntity response =
        ZionRequestExecutor.builder()
            .clientHostname(client)
            .serverHostname(server)
            .requestRbelMessage(requestRbelMessage)
            .rbelLogger(rbelLogger)
            .rbelWriter(rbelWriter)
            .objectMapper(objectMapper)
            .localServerPort(webServerAppCtxt.getWebServer().getPort())
            .configuration(configuration)
            .backendRequestExecutor(backendRequestExecutor)
            .request(request)
            .responseStartTime(responseStartTime)
            .build()
            .execute();

    log.info("Returning response {}", response);
    return response;
  }

  private byte[] buildRawMessageApproximate(RequestEntity request) {
    final String header =
        request.getMethod()
            + " "
            + request.getUrl()
            + " HTTP/1.1\r\n"
            + // NOSONAR
            request.getHeaders().entrySet().stream()
                .flatMap(entry -> entry.getValue().stream().map(v -> entry.getKey() + ": " + v))
                .collect(Collectors.joining("\r\n"))
            + "\r\n\r\n";
    if (request.hasBody()) {
      return ArrayUtils.addAll(header.getBytes(), request.getBody());
    } else {
      return header.getBytes();
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy