private void translateAppEngineWebXml()

in lib/tools_api/src/main/java/com/google/appengine/tools/admin/AppYamlTranslator.java [142:404]


  private void translateAppEngineWebXml(StringBuilder builder) {
    if (appEngineWebXml.getAppId() != null) {
      builder.append("application: '" + appEngineWebXml.getAppId() + "'\n");
    }
    builder.append("runtime: " + runtime + "\n");
    if (appEngineWebXml.getUseVm()) {
      builder.append("vm: True\n");
    }

    if (appEngineWebXml.isFlexible()) {
      builder.append("env: " + appEngineWebXml.getEnv() + "\n");
    }

    if (appEngineWebXml.getEntrypoint() != null) {
      builder.append("entrypoint: '" + appEngineWebXml.getEntrypoint() + "'\n");
    }

    if (appEngineWebXml.getRuntimeChannel() != null) {
      builder.append("runtime_channel: " + appEngineWebXml.getRuntimeChannel() + "\n");
    }
    if (appEngineWebXml.getMajorVersionId() != null) {
      builder.append("version: '" + appEngineWebXml.getMajorVersionId() + "'\n");
    }

    if (appEngineWebXml.getService() != null) {
      builder.append("service: '" + appEngineWebXml.getService() + "'\n");
    } else if (appEngineWebXml.getModule() != null) {
      builder.append("module: '" + appEngineWebXml.getModule() + "'\n");
    }

    if (appEngineWebXml.getInstanceClass() != null) {
      builder.append("instance_class: " + appEngineWebXml.getInstanceClass() + "\n");
    }

    if (!appEngineWebXml.getAutomaticScaling().isEmpty()) {
      builder.append("automatic_scaling:\n");
      AppEngineWebXml.AutomaticScaling settings = appEngineWebXml.getAutomaticScaling();
      appendIfNotNull(builder, "  min_pending_latency: ", settings.getMinPendingLatency());
      appendIfNotNull(builder, "  max_pending_latency: ", settings.getMaxPendingLatency());
      appendIfNotNull(builder, "  min_idle_instances: ", settings.getMinIdleInstances());
      appendIfNotNull(builder, "  max_idle_instances: ", settings.getMaxIdleInstances());
      appendIfNotNull(builder, "  max_concurrent_requests: ", settings.getMaxConcurrentRequests());
      appendIfNotNull(builder, "  min_num_instances: ", settings.getMinNumInstances());
      appendIfNotNull(builder, "  max_num_instances: ", settings.getMaxNumInstances());
      appendIfNotNull(builder, "  cool_down_period_sec: ", settings.getCoolDownPeriodSec());
      // GAE Standard new clone scheduler:
      // I know, having min_num_instances and min_instances is confusing. b/70626925.
      appendIfNotNull(builder, "  min_instances: ", settings.getMinInstances());
      appendIfNotNull(builder, "  max_instances: ", settings.getMaxInstances());
      appendIfNotNull(builder, "  target_cpu_utilization: ", settings.getTargetCpuUtilization());
      appendIfNotNull(
          builder, "  target_throughput_utilization: ", settings.getTargetThroughputUtilization());

      CpuUtilization cpuUtil = settings.getCpuUtilization();
      if (cpuUtil != null
          && (cpuUtil.getTargetUtilization() != null
              || cpuUtil.getAggregationWindowLengthSec() != null)) {
        builder.append("  cpu_utilization:\n");
        appendIfNotNull(builder, "    target_utilization: ", cpuUtil.getTargetUtilization());
        appendIfNotNull(
            builder, "    aggregation_window_length_sec: ",
            cpuUtil.getAggregationWindowLengthSec());
      }

      appendIfNotNull(
          builder, "  target_network_sent_bytes_per_sec: ",
          settings.getTargetNetworkSentBytesPerSec());
      appendIfNotNull(
          builder, "  target_network_sent_packets_per_sec: ",
          settings.getTargetNetworkSentPacketsPerSec());
      appendIfNotNull(
          builder, "  target_network_received_bytes_per_sec: ",
          settings.getTargetNetworkReceivedBytesPerSec());
      appendIfNotNull(
          builder, "  target_network_received_packets_per_sec: ",
          settings.getTargetNetworkReceivedPacketsPerSec());
      appendIfNotNull(
          builder, "  target_disk_write_bytes_per_sec: ",
          settings.getTargetDiskWriteBytesPerSec());
      appendIfNotNull(
          builder, "  target_disk_write_ops_per_sec: ",
          settings.getTargetDiskWriteOpsPerSec());
      appendIfNotNull(
          builder, "  target_disk_read_bytes_per_sec: ",
          settings.getTargetDiskReadBytesPerSec());
      appendIfNotNull(
          builder, "  target_disk_read_ops_per_sec: ",
          settings.getTargetDiskReadOpsPerSec());
      appendIfNotNull(
          builder, "  target_request_count_per_sec: ",
          settings.getTargetRequestCountPerSec());
      appendIfNotNull(
          builder, "  target_concurrent_requests: ",
          settings.getTargetConcurrentRequests());

      if (!settings.getCustomMetrics().isEmpty()) {
        if (!appEngineWebXml.isFlexible()) {
          throw new AppEngineConfigException("custom-metrics is only available in the AppEngine "
                                             + "Flexible environment.");
        }
        builder.append("  custom_metrics:\n");
        for (CustomMetricUtilization metric : settings.getCustomMetrics()) {
          builder.append("    - metric_name: '" + metric.getMetricName() + "'\n");
          builder.append("      target_type: '" + metric.getTargetType() + "'\n");
          appendIfNotNull(builder, "      target_utilization: ", metric.getTargetUtilization());
          appendIfNotNull(builder,
              "      single_instance_assignment: ",
              metric.getSingleInstanceAssignment());
          if (metric.getFilter() != null) {
            builder.append("      filter: '" + metric.getFilter() + "'\n");
          }
        }
      }
    }

    if (!appEngineWebXml.getManualScaling().isEmpty()) {
      builder.append("manual_scaling:\n");
      AppEngineWebXml.ManualScaling settings = appEngineWebXml.getManualScaling();
      builder.append("  instances: " + settings.getInstances() + "\n");
    }

    if (!appEngineWebXml.getBasicScaling().isEmpty()) {
      builder.append("basic_scaling:\n");
      AppEngineWebXml.BasicScaling settings = appEngineWebXml.getBasicScaling();
      builder.append("  max_instances: " + settings.getMaxInstances() + "\n");
      appendIfNotNull(builder, "  idle_timeout: ", settings.getIdleTimeout());
    }

    Collection<String> services = appEngineWebXml.getInboundServices();
    if (!services.isEmpty()) {
      builder.append("inbound_services:\n");
      for (String service : services) {
        builder.append("- " + service + "\n");
      }
    }

    // Precompilation is only for the Standard environment.
    if (appEngineWebXml.getPrecompilationEnabled()
        && !appEngineWebXml.getUseVm()
        && !appEngineWebXml.isFlexible()
        && !appEngineWebXml.isJava11OrAbove()) {
      builder.append("derived_file_type:\n");
      builder.append("- java_precompiled\n");

    }

    if (appEngineWebXml.getThreadsafe() && !appEngineWebXml.isJava11OrAbove()) {
      builder.append("threadsafe: True\n");
    }

    if (appEngineWebXml.getAppEngineApis() && appEngineWebXml.isJava11OrAbove()) {
      builder.append("app_engine_apis: True\n");
    }

    if (appEngineWebXml.getThreadsafeValueProvided() && appEngineWebXml.isJava11OrAbove()) {
      System.out.println(
          "Warning: The "
              + appEngineWebXml.getRuntime()
              + " runtime does not use the <threadsafe> element"
              + " in appengine-web.xml anymore");
      System.out.println(
          "Instead, you can use the <max-concurrent-requests> element in <automatic-scaling>.");
    }

    if (appEngineWebXml.getAutoIdPolicy() != null) {
      builder.append("auto_id_policy: " + appEngineWebXml.getAutoIdPolicy() + "\n");
    } else {
      // NOTE: The YAML parsing and validation done in the admin console must
      // set the value for unspecified auto_id_policy to 'legacy' in order to achieve
      // the desired behavior for previous SDK versions. But the desired value for
      // unspecified auto_id_policy in current and future SDK versions is 'default'.
      // Therefore in new SDK versions we intercept unspecified auto_id_policy here.
      builder.append("auto_id_policy: default\n");
    }

    if (appEngineWebXml.getCodeLock()) {
      builder.append("code_lock: True\n");
    }

    if (appEngineWebXml.getVpcAccessConnector() != null) {
      VpcAccessConnector connector = appEngineWebXml.getVpcAccessConnector();
      builder.append("vpc_access_connector:\n");
      builder.append("  name: " + connector.getName() + "\n");
      if (connector.getEgressSetting().isPresent()) {
        builder.append("  egress_setting: " + connector.getEgressSetting().get() + "\n");
      }
    }

    if (appEngineWebXml.getServiceAccount() != null) {
      builder.append("service_account: " + appEngineWebXml.getServiceAccount() + "\n");
    }

    List<AdminConsolePage> adminConsolePages = appEngineWebXml.getAdminConsolePages();
    if (!adminConsolePages.isEmpty()) {
      builder.append("admin_console:\n");
      builder.append("  pages:\n");
      for (AdminConsolePage page : adminConsolePages) {
        builder.append("  - name: " + page.getName() + "\n");
        builder.append("    url: " + page.getUrl() + "\n");
      }
    }

    List<ErrorHandler> errorHandlers = appEngineWebXml.getErrorHandlers();
    if (!errorHandlers.isEmpty()) {
      builder.append("error_handlers:\n");
      for (ErrorHandler handler : errorHandlers) {
        String fileName = handler.getFile();
        if (!fileName.startsWith("/")) {
          fileName = "/" + fileName;
        }
        // TODO: Consider whether we should be adding the
        // public root to this path.
        if (!staticFiles.contains("__static__" + fileName)) {
          throw new AppEngineConfigException("No static file found for error handler: "
              + fileName + ", out of " + staticFiles);
        }
        // error_handlers doesn't want a leading slash here.
        builder.append("- file: __static__" + fileName + "\n");
        if (handler.getErrorCode() != null) {
          builder.append("  error_code: " + handler.getErrorCode() + "\n");
        }
        String mimeType = webXml.getMimeTypeForPath(handler.getFile());
        if (mimeType != null) {
          builder.append("  mime_type: " + mimeType + "\n");
        }
      }
    }

    if (backendsXml != null) {
      builder.append(backendsXml.toYaml());
    }

    // Only one api config, it is a singleton, and multiple APIs are served
    // from subpaths within the namespace.
    // TODO: Verify script: is required.
    ApiConfig apiConfig = appEngineWebXml.getApiConfig();
    if (apiConfig != null) {
      builder.append("api_config:\n");
      builder.append("  url: " + apiConfig.getUrl() + "\n");
      builder.append("  script: unused\n");
    }

    // For beta-settings, we allow anything and defer to the later app.yaml processing
    // to detect invalid values.
    appendBetaSettings(appEngineWebXml.getBetaSettings(), builder);
    appendEnvVariables(appEngineWebXml.getEnvironmentVariables(), builder);
    appendBuildEnvVariables(appEngineWebXml.getBuildEnvironmentVariables(), builder);
    if (appEngineWebXml.getUseVm() || appEngineWebXml.isFlexible()) {

      if (appEngineWebXml.getHealthCheck() != null) {
        appendHealthCheck(appEngineWebXml.getHealthCheck(), builder);
      }
      if (appEngineWebXml.getLivenessCheck() != null) {
        appendLivenessCheck(appEngineWebXml.getLivenessCheck(), builder);
      }
      if (appEngineWebXml.getReadinessCheck() != null) {
        appendReadinessCheck(appEngineWebXml.getReadinessCheck(), builder);
      }

      appendResources(appEngineWebXml.getResources(), builder);
      appendNetwork(appEngineWebXml.getNetwork(), builder);
    }
  }