content: /*
   * 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.camel.quarkus.main;
  
  import java.net.HttpURLConnection;
  import java.util.Map;
  
  import io.quarkus.test.junit.QuarkusTest;
  import io.restassured.RestAssured;
  import io.restassured.http.ContentType;
  import io.restassured.path.json.JsonPath;
  import io.restassured.response.Response;
  import jakarta.ws.rs.core.MediaType;
  import org.apache.camel.ServiceStatus;
  import org.apache.camel.quarkus.core.DisabledModelToXMLDumper;
  import org.apache.camel.quarkus.core.RegistryRoutesLoaders;
  import org.apache.camel.quarkus.test.DisabledOnQuarkusPlatform;
  import org.apache.camel.reactive.vertx.VertXReactiveExecutor;
  import org.apache.camel.reactive.vertx.VertXThreadPoolFactory;
  import org.apache.camel.support.DefaultLRUCacheFactory;
  import org.junit.jupiter.api.Test;
  
  import static org.apache.camel.quarkus.test.Conditions.doesNotStartWith;
  import static org.apache.camel.quarkus.test.Conditions.entry;
  import static org.apache.camel.quarkus.test.Conditions.startsWith;
  import static org.apache.camel.util.CollectionHelper.mapOf;
  import static org.assertj.core.api.Assertions.assertThat;
  import static org.hamcrest.Matchers.containsString;
  import static org.hamcrest.Matchers.is;
  import static org.junit.jupiter.api.Assertions.assertEquals;
  import static org.junit.jupiter.api.Assertions.assertNotEquals;
  
  @QuarkusTest
  public class CoreMainTest {
  
      @Test
      public void testProperties() {
          RestAssured.when().get("/test/property/camel.context.name").then().body(is("quarkus-camel-example"));
          RestAssured.when().get("/test/property/the.message").then().body(is("test"));
      }
  
      @Test
      public void testSetCamelContextName() {
          Response response = RestAssured.get("/test/context/name").andReturn();
  
          assertEquals(HttpURLConnection.HTTP_OK, response.getStatusCode());
          assertNotEquals("my-ctx-name", response.body().asString());
  
          RestAssured.given()
                  .contentType(ContentType.TEXT).body("my-ctx-name")
                  .post("/test/context/name")
                  .then().body(is("my-ctx-name"));
      }
  
      @Test
      public void testMainInstance() {
          JsonPath p = RestAssured.given()
                  .accept(MediaType.APPLICATION_JSON)
                  .get("/test/main/describe")
                  .then()
                  .statusCode(200)
                  .extract()
                  .body()
                  .jsonPath();
  
          assertThat(p.getString("xml-model-dumper")).isEqualTo(DisabledModelToXMLDumper.class.getName());
  
          assertThat(p.getString("routes-collector.type")).isEqualTo(CamelMainRoutesCollector.class.getName());
          assertThat(p.getString("routes-collector.type-registry")).isEqualTo(RegistryRoutesLoaders.Default.class.getName());
  
          assertThat(p.getList("routeBuilders", String.class))
                  .contains(CamelRoute.class.getName())
                  .doesNotContain(CamelRouteFiltered.class.getName());
          assertThat(p.getList("routes", String.class))
                  .contains("keep-alive", "produced", "endpointdsl", "lambdaEndpointRoute")
                  .doesNotContain("filtered");
  
          assertThat(p.getString("lru-cache-factory")).isEqualTo(DefaultLRUCacheFactory.class.getName());
          assertThat(p.getBoolean("autoConfigurationLogSummary")).isFalse();
  
          assertThat(p.getMap("registry.components", String.class, String.class)).isNotEmpty();
          assertThat(p.getMap("registry.dataformats", String.class, String.class)).isEmpty();
          assertThat(p.getMap("registry.languages", String.class, String.class)).containsExactlyInAnyOrderEntriesOf(mapOf(
                  "constant", "org.apache.camel.language.constant.ConstantLanguage",
                  "file", "org.apache.camel.language.simple.FileLanguage",
                  "header", "org.apache.camel.language.header.HeaderLanguage",
                  "simple", "org.apache.camel.language.simple.SimpleLanguage",
                  "ref", "org.apache.camel.language.ref.RefLanguage"));
  
          Map<String, String> factoryFinderMap = p.getMap("factory-finder.class-map", String.class, String.class);
  
          // dataformats
          assertThat(factoryFinderMap)
                  .hasKeySatisfying(startsWith("META-INF/services/org/apache/camel/dataformat/"))
                  .hasEntrySatisfying(entry(
                          "META-INF/services/org/apache/camel/dataformat/my-dataformat",
                          "org.apache.camel.quarkus.it.support.dataformat.MyDataformat"));
  
          // languages
          assertThat(factoryFinderMap)
                  .hasKeySatisfying(startsWith("META-INF/services/org/apache/camel/language/"))
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/constant"))
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/file"))
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/header"))
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/ref"))
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/language/simple"));
  
          // components
          assertThat(factoryFinderMap)
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/component/"));
  
          // misc
          assertThat(factoryFinderMap)
                  .hasKeySatisfying(startsWith("META-INF/services/org/apache/camel/configurer/"));
  
          // core
          assertThat(factoryFinderMap)
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/properties-component-factory"))
                  .hasKeySatisfying(doesNotStartWith("META-INF/services/org/apache/camel/reactive-executor"));
  
          // rest properties are configured through CamelContext, this test is to spot changes
          // done to underlying camel-main implementation that would prevent to configure it
          // consistently across runtimes using camel-main properties.
          assertThat(p.getString("config.rest-port")).isEqualTo("9876");
  
          // resilience4j properties are configured through ModelCamelContext, this test is
          // to ensure that FastCamelContext won't change in a way it cannot be configured
          // consistently across runtimes using camel-main properties.
          assertThat(p.getString("config.resilience4j-sliding-window-size")).isEqualTo("1234");
  
          // ensure reflection is not used
          assertThat(p.getLong("bean-introspection-invocations")).isEqualTo(0);
  
      }
  
      @Test
      public void testReactiveExecutor() {
          JsonPath executor = RestAssured.when().get("/test/context/reactive-executor")
                  .then()
                  .statusCode(200)
                  .extract()
                  .body()
                  .jsonPath();
  
          assertThat(executor.getString("class")).isEqualTo(VertXReactiveExecutor.class.getName());
          assertThat(executor.getBoolean("configured")).isTrue();
      }
  
      @Test
      public void testThreadPoolFactory() {
          JsonPath executor = RestAssured.when().get("/test/context/thread-pool-factory")
                  .then()
                  .statusCode(200)
                  .extract()
                  .body()
                  .jsonPath();
  
          assertThat(executor.getString("class")).isEqualTo(VertXThreadPoolFactory.class.getName());
          assertThat(executor.getBoolean("configured")).isTrue();
      }
  
      @Test
      public void testCustomTypeConverter() {
          RestAssured.given()
                  .contentType(ContentType.TEXT).body("a:b")
                  .accept(MediaType.APPLICATION_JSON)
                  .post("/test/converter/my-pair")
                  .then().body(
                          "key", is("a"),
                          "val", is("b"));
      }
  
      @Test
      public void testCustomComponent() {
          RestAssured.given()
                  .accept(MediaType.APPLICATION_JSON)
                  .get("/test/registry/component/direct")
                  .then()
                  .statusCode(200)
                  .body(
                          "timeout", is("1234"),
                          "registry", is("repository"),
                          "registry-type", is("org.apache.camel.quarkus.core.RuntimeBeanRepository"));
      }
  
      @Test
      public void testGetStringFromRegistry() {
          RestAssured.given()
                  .accept(MediaType.TEXT_PLAIN)
                  .get("/test/registry/string/stringFromRegistry")
                  .then()
                  .statusCode(200)
                  .body(is("String From Registry"));
      }
  
      @Test
      public void testJmxConnectorService() {
          RestAssured.given()
                  .accept(MediaType.TEXT_PLAIN)
                  .get("/test/service/jmx-connector/status")
                  .then()
                  .statusCode(200)
                  .body(is(ServiceStatus.Started.name().toUpperCase()));
  
          RestAssured.given()
                  .accept(MediaType.TEXT_PLAIN)
                  .get("/test/service/jmx-connector/expected/connect/state")
                  .then()
                  .statusCode(200)
                  .body(is("true"));
      }
  
      // Avoid running in the Quarkus Platform where there are no .java source files
      @DisabledOnQuarkusPlatform
      @Test
      public void routeSourceResource() {
          RestAssured.given()
                  .get("/test/context/route/source/resource")
                  .then()
                  .statusCode(200)
                  .body(containsString("public class " + CamelCdiBeanRoute.class.getSimpleName()));
      }
  
  }
  