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

com.google.apphosting.utils.config.AppEngineWebXmlProcessor Maven / Gradle / Ivy

There is a newer version: 2.0.32
Show newest version
/*
 * Copyright 2021 Google LLC
 *
 * 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
 *
 *     https://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 com.google.apphosting.utils.config;

import com.google.apphosting.utils.config.AppEngineWebXml.AdminConsolePage;
import com.google.apphosting.utils.config.AppEngineWebXml.ApiConfig;
import com.google.apphosting.utils.config.AppEngineWebXml.AutomaticScaling;
import com.google.apphosting.utils.config.AppEngineWebXml.BasicScaling;
import com.google.apphosting.utils.config.AppEngineWebXml.ClassLoaderConfig;
import com.google.apphosting.utils.config.AppEngineWebXml.CpuUtilization;
import com.google.apphosting.utils.config.AppEngineWebXml.CustomMetricUtilization;
import com.google.apphosting.utils.config.AppEngineWebXml.ErrorHandler;
import com.google.apphosting.utils.config.AppEngineWebXml.HealthCheck;
import com.google.apphosting.utils.config.AppEngineWebXml.LivenessCheck;
import com.google.apphosting.utils.config.AppEngineWebXml.ManualScaling;
import com.google.apphosting.utils.config.AppEngineWebXml.Network;
import com.google.apphosting.utils.config.AppEngineWebXml.PrioritySpecifierEntry;
import com.google.apphosting.utils.config.AppEngineWebXml.ReadinessCheck;
import com.google.apphosting.utils.config.AppEngineWebXml.Resources;
import com.google.apphosting.utils.config.AppEngineWebXml.VpcAccessConnector;
import com.google.common.collect.ImmutableSortedSet;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.logging.Logger;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * Constructs an {@link AppEngineWebXml} from an xml document corresponding to appengine-web.xsd.
 *
 * 

TODO: Add a real link to the xsd once it exists and do schema validation. */ class AppEngineWebXmlProcessor { enum FileType { STATIC, RESOURCE } private static final Logger logger = Logger.getLogger(AppEngineWebXmlProcessor.class.getName()); // Error handling to disallow having both module and service entries. private boolean moduleNodeFound; private boolean serviceNodeFound; private boolean warmupNodeFound; /** * Construct an {@link AppEngineWebXml} from the xml document * identified by the provided {@link InputStream}. * * @param is The InputStream containing the xml we want to parse and process. * * @return Object representation of the xml document. * @throws AppEngineConfigException If the input stream cannot be parsed. */ public AppEngineWebXml processXml(InputStream is) { Element config = getTopLevelNode(is); AppEngineWebXml appEngineWebXml = new AppEngineWebXml(); NodeList nodes = config.getChildNodes(); for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); if (!(node instanceof Element)) { continue; } processSecondLevelNode((Element) node, appEngineWebXml); } checkScalingConstraints(appEngineWebXml); // Do not allow service and module to be defined in the same app.yaml. if (serviceNodeFound && moduleNodeFound) { throw new AppEngineConfigException( "The and elements are conflicting. " + "Please remove the deprecated element."); } // Warmup requests are on by default for Java Standard (not Flex) applications // configured via an appengine-web.xml. if (!appEngineWebXml.isFlexible() && !warmupNodeFound) { appEngineWebXml.setWarmupRequestsEnabled(true); } return appEngineWebXml; } /** * Given an AppEngineWebXml, ensure it has no more than one of the scaling options available. * * @throws AppEngineConfigException If there is more than one scaling option selected. */ private static void checkScalingConstraints(AppEngineWebXml appEngineWebXml) { int count = appEngineWebXml.getManualScaling().isEmpty() ? 0 : 1; count += appEngineWebXml.getBasicScaling().isEmpty() ? 0 : 1; count += appEngineWebXml.getAutomaticScaling().isEmpty() ? 0 : 1; if (count > 1) { throw new AppEngineConfigException( "There may be only one of 'automatic-scaling', 'manual-scaling' or " + "'basic-scaling' elements."); } } /** * Given an InputStream, create a Node corresponding to the top level xml * element. * * @throws AppEngineConfigException If the input stream cannot be parsed. */ Element getTopLevelNode(InputStream is) { return XmlUtils.parseXml(is).getDocumentElement(); } private void processSecondLevelNode(Element elt, AppEngineWebXml appEngineWebXml) { String elementName = elt.getTagName(); switch (elementName) { case "system-properties": processSystemPropertiesNode(elt, appEngineWebXml); break; case "vm-settings": case "beta-settings": processBetaSettingsNode(elt, appEngineWebXml); break; case "vm-health-check": case "health-check": processHealthCheckNode(elt, appEngineWebXml); break; case "liveness-check": processLivenessCheckNode(elt, appEngineWebXml); break; case "readiness-check": processReadinessCheckNode(elt, appEngineWebXml); break; case "resources": processResourcesNode(elt, appEngineWebXml); break; case "network": processNetworkNode(elt, appEngineWebXml); break; case "env-variables": processEnvironmentVariablesNode(elt, appEngineWebXml); break; case "build-env-variables": processBuildEnvironmentVariablesNode(elt, appEngineWebXml); break; case "application": processApplicationNode(elt, appEngineWebXml); break; case "entrypoint": processEntrypointNode(elt, appEngineWebXml); break; case "runtime-channel": processRuntimeChannelNode(elt, appEngineWebXml); break; case "runtime": processRuntimeNode(elt, appEngineWebXml); break; case "version": processVersionNode(elt, appEngineWebXml); break; case "source-language": logger.warning( "The element in appengine-web.xml file was ignored."); break; case "module": moduleNodeFound = true; processModuleNode(elt, appEngineWebXml); break; case "service": serviceNodeFound = true; processServiceNode(elt, appEngineWebXml); break; case "instance-class": processInstanceClassNode(elt, appEngineWebXml); break; case "automatic-scaling": processAutomaticScalingNode(elt, appEngineWebXml); break; case "manual-scaling": processManualScalingNode(elt, appEngineWebXml); break; case "basic-scaling": processBasicScalingNode(elt, appEngineWebXml); break; case "static-files": processFilesetNode(elt, appEngineWebXml, FileType.STATIC); break; case "resource-files": processFilesetNode(elt, appEngineWebXml, FileType.RESOURCE); break; case "ssl-enabled": processSslEnabledNode(elt, appEngineWebXml); break; case "sessions-enabled": processSessionsEnabledNode(elt, appEngineWebXml); break; case "async-session-persistence": processAsyncSessionPersistenceNode(elt, appEngineWebXml); break; case "user-permissions": processPermissionsNode(elt, appEngineWebXml); break; case "public-root": processPublicRootNode(elt, appEngineWebXml); break; case "inbound-services": processInboundServicesNode(elt, appEngineWebXml); break; case "precompilation-enabled": processPrecompilationEnabledNode(elt, appEngineWebXml); break; case "admin-console": processAdminConsoleNode(elt, appEngineWebXml); break; case "static-error-handlers": processErrorHandlerNode(elt, appEngineWebXml); break; case "warmup-requests-enabled": warmupNodeFound = true; processWarmupRequestsEnabledNode(elt, appEngineWebXml); break; case "threadsafe": processThreadsafeNode(elt, appEngineWebXml); break; case "app-engine-apis": appEngineWebXml.setAppEngineApis(getBooleanValue(elt)); break; case "auto-id-policy": processAutoIdPolicyNode(elt, appEngineWebXml); break; case "code-lock": processCodeLockNode(elt, appEngineWebXml); break; case "vm": processVmNode(elt, appEngineWebXml); break; case "env": processEnvNode(elt, appEngineWebXml); break; case "api-config": processApiConfigNode(elt, appEngineWebXml); break; case "class-loader-config": processClassLoaderConfig(elt, appEngineWebXml); break; case "url-stream-handler": processUrlStreamHandler(elt, appEngineWebXml); break; case "use-google-connector-j": processUseGoogleConnectorJNode(elt, appEngineWebXml); break; case "pagespeed": logger.warning( "app_id " + appEngineWebXml.getAppId() + " has in appengine-web.xml file, ignored."); break; case "staging": processStagingNode(elt, appEngineWebXml); break; case "vpc-access-connector": processVpcAccessConnector(elt, appEngineWebXml); break; case "service-account": processServiceAccountNode(elt, appEngineWebXml); break; default: throw new AppEngineConfigException("Unrecognized element <" + elementName + ">"); } } private void processApplicationNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setAppId(XmlUtils.getText(node)); } private void processEntrypointNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setEntrypoint(XmlUtils.getText(node)); } private void processRuntimeChannelNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setRuntimeChannel(XmlUtils.getText(node)); } private void processPublicRootNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setPublicRoot(XmlUtils.getText(node)); } private void processVersionNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setMajorVersionId(XmlUtils.getText(node)); } private void processRuntimeNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setRuntime(XmlUtils.getText(node)); } private void processModuleNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setModule(XmlUtils.getText(node)); } private void processServiceNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setService(XmlUtils.getText(node)); } private void processInstanceClassNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setInstanceClass(XmlUtils.getText(node)); } private void processServiceAccountNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setServiceAccount(XmlUtils.getText(node)); } private String getChildNodeText(Element parentNode, String childTag) { Element node = XmlUtils.getOptionalChildElement(parentNode, childTag); if (node == null) { return null; } String result = XmlUtils.getText(node); return result.isEmpty() ? null : result; } private Integer getChildNodePositiveInteger(Element parentNode, String childTag) { Integer result = getChildNodeNonNegativeInteger(parentNode, childTag); if (result != null && result == 0) { throw new AppEngineConfigException(childTag + " should only contain positive integers."); } return result; } private Integer getChildNodeNonNegativeInteger(Element parentNode, String childTag) { Integer result = null; Element node = XmlUtils.getOptionalChildElement(parentNode, childTag); if (node != null) { String trimmedText = XmlUtils.getText(node); if (!trimmedText.isEmpty()) { try { result = Integer.parseInt(trimmedText); } catch (NumberFormatException ex) { throw new AppEngineConfigException(childTag + " should only contain integers."); } if (result < 0) { throw new AppEngineConfigException( childTag + " should only contain non-negative integers."); } } } return result; } private Double getChildNodeDouble(Element parentNode, String childTag) { Double result = null; Element node = XmlUtils.getOptionalChildElement(parentNode, childTag); if (node != null) { String trimmedText = XmlUtils.getText(node); if (!trimmedText.isEmpty()) { try { result = Double.parseDouble(trimmedText); } catch (NumberFormatException ex) { throw new AppEngineConfigException(childTag + " should only contain doubles."); } catch (NullPointerException ex) { // This shouldn't happen because of the check above. However, Keep it here for // completeness of catching exceptions. throw new AppEngineConfigException(childTag + " should NOT be empty."); } } } return result; } private void processAutomaticScalingNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { AutomaticScaling automaticScaling = appEngineWebXml.getAutomaticScaling(); automaticScaling.setMinPendingLatency(getChildNodeText(settingsNode, "min-pending-latency")); automaticScaling.setMaxPendingLatency(getChildNodeText(settingsNode, "max-pending-latency")); automaticScaling.setMinIdleInstances(getChildNodeText(settingsNode, "min-idle-instances")); automaticScaling.setMaxIdleInstances(getChildNodeText(settingsNode, "max-idle-instances")); automaticScaling.setMaxInstances(getChildNodePositiveInteger(settingsNode, "max-instances")); automaticScaling.setMinInstances(getChildNodeNonNegativeInteger(settingsNode, "min-instances")); automaticScaling.setTargetCpuUtilization( getChildNodeDouble(settingsNode, "target-cpu-utilization")); automaticScaling.setTargetThroughputUtilization( getChildNodeDouble(settingsNode, "target-throughput-utilization")); automaticScaling.setMaxConcurrentRequests( getChildNodeText(settingsNode, "max-concurrent-requests")); automaticScaling.setMinNumInstances( getChildNodePositiveInteger(settingsNode, "min-num-instances")); automaticScaling.setMaxNumInstances( getChildNodePositiveInteger(settingsNode, "max-num-instances")); automaticScaling.setCoolDownPeriodSec( getChildNodePositiveInteger(settingsNode, "cool-down-period-sec")); processCpuUtilizationNode(settingsNode, automaticScaling); processCustomMetricsNode(settingsNode, automaticScaling); automaticScaling.setTargetNetworkSentBytesPerSec( getChildNodePositiveInteger(settingsNode, "target-network-sent-bytes-per-sec")); automaticScaling.setTargetNetworkSentPacketsPerSec( getChildNodePositiveInteger(settingsNode, "target-network-sent-packets-per-sec")); automaticScaling.setTargetNetworkReceivedBytesPerSec( getChildNodePositiveInteger(settingsNode, "target-network-received-bytes-per-sec")); automaticScaling.setTargetNetworkReceivedPacketsPerSec( getChildNodePositiveInteger(settingsNode, "target-network-received-packets-per-sec")); automaticScaling.setTargetDiskWriteBytesPerSec( getChildNodePositiveInteger(settingsNode, "target-disk-write-bytes-per-sec")); automaticScaling.setTargetDiskWriteOpsPerSec( getChildNodePositiveInteger(settingsNode, "target-disk-write-ops-per-sec")); automaticScaling.setTargetDiskReadBytesPerSec( getChildNodePositiveInteger(settingsNode, "target-disk-read-bytes-per-sec")); automaticScaling.setTargetDiskReadOpsPerSec( getChildNodePositiveInteger(settingsNode, "target-disk-read-ops-per-sec")); automaticScaling.setTargetRequestCountPerSec( getChildNodePositiveInteger(settingsNode, "target-request-count-per-sec")); automaticScaling.setTargetConcurrentRequests( getChildNodePositiveInteger(settingsNode, "target-concurrent-requests")); } private void processCpuUtilizationNode(Element settingsNode, AutomaticScaling automaticScaling) { Element childNode = XmlUtils.getOptionalChildElement(settingsNode, "cpu-utilization"); if (childNode != null) { CpuUtilization cpuUtilization = new CpuUtilization(); Double targetUtilization = getChildNodeDouble(childNode, "target-utilization"); if (targetUtilization != null) { if (targetUtilization <= 0 || targetUtilization > 1) { throw new AppEngineConfigException("target-utilization should be in range (0, 1]."); } cpuUtilization.setTargetUtilization(targetUtilization); } cpuUtilization.setAggregationWindowLengthSec( getChildNodePositiveInteger(childNode, "aggregation-window-length-sec")); if (!cpuUtilization.isEmpty()) { automaticScaling.setCpuUtilization(cpuUtilization); } } } private void processCustomMetricsNode(Element settingsNode, AutomaticScaling automaticScaling) { List customMetrics = new ArrayList<>(); Element node = XmlUtils.getOptionalChildElement(settingsNode, "custom-metrics"); if (node == null) { return; } for (Element metric : getNodeIterable(node, "custom-metric")) { CustomMetricUtilization customMetric = new CustomMetricUtilization(); final String metricName = getChildNodeText(metric, "metric-name"); if (metricName == null || metricName.isEmpty()) { throw new AppEngineConfigException("metric-name must be defined."); } customMetric.setMetricName(metricName); final String targetType = getChildNodeText(metric, "target-type"); if (targetType == null || targetType.isEmpty()) { throw new AppEngineConfigException("target-type must be defined."); } customMetric.setTargetType(targetType); final Double targetUtilization = getChildNodeDouble(metric, "target-utilization"); if (targetUtilization != null) { if (targetUtilization <= 0) { throw new AppEngineConfigException("target-utilization must be positive."); } customMetric.setTargetUtilization(targetUtilization); } final Double singleInstanceAssignment = getChildNodeDouble(metric, "single-instance-assignment"); if (singleInstanceAssignment != null) { if (singleInstanceAssignment <= 0) { throw new AppEngineConfigException("single-instance-assignment must be positive."); } customMetric.setSingleInstanceAssignment(singleInstanceAssignment); } String filter = getChildNodeText(metric, "filter"); if (filter != null && !filter.isEmpty()) { customMetric.setFilter(filter); } customMetrics.add(customMetric); } automaticScaling.setCustomMetrics(customMetrics); } private void processManualScalingNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { ManualScaling manualScaling = appEngineWebXml.getManualScaling(); manualScaling.setInstances(getChildNodeText(settingsNode, "instances")); } private void processBasicScalingNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { BasicScaling basicScaling = appEngineWebXml.getBasicScaling(); basicScaling.setMaxInstances(getChildNodeText(settingsNode, "max-instances")); basicScaling.setIdleTimeout(getChildNodeText(settingsNode, "idle-timeout")); } private void processSslEnabledNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setSslEnabled(getBooleanValue(node)); } private void processSessionsEnabledNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setSessionsEnabled(getBooleanValue(node)); } private void processAsyncSessionPersistenceNode(Element node, AppEngineWebXml appEngineWebXml) { boolean enabled = getBooleanAttributeValue(node, "enabled"); appEngineWebXml.setAsyncSessionPersistence(enabled); String queueName = trim(node.getAttribute("queue-name")); if (queueName.equals("")) { queueName = null; } appEngineWebXml.setAsyncSessionPersistenceQueueName(queueName); } private void processPrecompilationEnabledNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setPrecompilationEnabled(getBooleanValue(node)); } private void processWarmupRequestsEnabledNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setWarmupRequestsEnabled(getBooleanValue(node)); } private void processThreadsafeNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setThreadsafe(getBooleanValue(node)); } private void processAutoIdPolicyNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setAutoIdPolicy(XmlUtils.getText(node)); } private void processCodeLockNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setCodeLock(getBooleanValue(node)); } private void processVmNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setUseVm(getBooleanValue(node)); } private void processEnvNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setEnv(XmlUtils.getText(node)); } private void processFilesetNode(Element node, AppEngineWebXml appEngineWebXml, FileType type) { for (Element includeNode : getNodeIterable(node, "include")) { String path = trim(includeNode.getAttribute("path")); if (path.equals("")) { path = null; } if (type == FileType.STATIC) { String expiration = trim(includeNode.getAttribute("expiration")); if (expiration.equals("")) { expiration = null; } AppEngineWebXml.StaticFileInclude staticFileInclude = appEngineWebXml.includeStaticPattern(path, expiration); Map httpHeaders = staticFileInclude.getHttpHeaders(); for (Element httpHeaderNode : getNodeIterable(includeNode, "http-header")) { String name = httpHeaderNode.getAttribute("name"); String value = httpHeaderNode.getAttribute("value"); if (httpHeaders.containsKey(name)) { throw new AppEngineConfigException("Two http-header elements have the same name."); } httpHeaders.put(name, value); } } else { appEngineWebXml.includeResourcePattern(path); } } for (Element excludeNode : getNodeIterable(node, "exclude")) { String path = trim(excludeNode.getAttribute("path")); if (type == FileType.STATIC) { appEngineWebXml.excludeStaticPattern(path); } else { appEngineWebXml.excludeResourcePattern(path); } } } private Iterable getNodeIterable(Element node, String filter) { return XmlUtils.getChildren(node, filter); } private void processSystemPropertiesNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element propertyNode : getNodeIterable(node, "property")) { String propertyName = trim(propertyNode.getAttribute("name")); String propertyValue = trim(propertyNode.getAttribute("value")); appEngineWebXml.addSystemProperty(propertyName, propertyValue); } } private void processBetaSettingsNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "setting")) { String name = trim(subNode.getAttribute("name")); String value = trim(subNode.getAttribute("value")); appEngineWebXml.addBetaSetting(name, value); } } private void processHealthCheckNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { HealthCheck healthCheck = new HealthCheck(); String enableHealthCheck = trim(getChildNodeText(settingsNode, "enable-health-check")); if (enableHealthCheck != null && !enableHealthCheck.isEmpty()) { healthCheck.setEnableHealthCheck(toBoolean(enableHealthCheck)); } Integer checkIntervalSec = getChildNodePositiveInteger(settingsNode, "check-interval-sec"); if (checkIntervalSec != null) { healthCheck.setCheckIntervalSec(checkIntervalSec); } Integer timeoutSec = getChildNodePositiveInteger(settingsNode, "timeout-sec"); if (timeoutSec != null) { healthCheck.setTimeoutSec(timeoutSec); } Integer unhealthyThreshold = getChildNodePositiveInteger(settingsNode, "unhealthy-threshold"); if (unhealthyThreshold != null) { healthCheck.setUnhealthyThreshold(unhealthyThreshold); } Integer healthyThreshold = getChildNodePositiveInteger(settingsNode, "healthy-threshold"); if (healthyThreshold != null) { healthCheck.setHealthyThreshold(healthyThreshold); } Integer restartThreshold = getChildNodePositiveInteger(settingsNode, "restart-threshold"); if (restartThreshold != null) { healthCheck.setRestartThreshold(restartThreshold); } String host = getChildNodeText(settingsNode, "host"); if (host != null) { healthCheck.setHost(host); } appEngineWebXml.setHealthCheck(healthCheck); } private void processLivenessCheckNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { LivenessCheck livenessCheck = new LivenessCheck(); String path = getChildNodeText(settingsNode, "path"); if (path != null) { livenessCheck.setPath(path); } Integer checkIntervalSec = getChildNodePositiveInteger(settingsNode, "check-interval-sec"); if (checkIntervalSec != null) { livenessCheck.setCheckIntervalSec(checkIntervalSec); } Integer timeoutSec = getChildNodePositiveInteger(settingsNode, "timeout-sec"); if (timeoutSec != null) { livenessCheck.setTimeoutSec(timeoutSec); } Integer failureThreshold = getChildNodePositiveInteger(settingsNode, "failure-threshold"); if (failureThreshold != null) { livenessCheck.setFailureThreshold(failureThreshold); } Integer successThreshold = getChildNodePositiveInteger(settingsNode, "success-threshold"); if (successThreshold != null) { livenessCheck.setSuccessThreshold(successThreshold); } String host = getChildNodeText(settingsNode, "host"); if (host != null) { livenessCheck.setHost(host); } Integer initialDelaySec = getChildNodePositiveInteger(settingsNode, "initial-delay-sec"); if (initialDelaySec != null) { livenessCheck.setInitialDelaySec(initialDelaySec); } appEngineWebXml.setLivenessCheck(livenessCheck); } private void processReadinessCheckNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { ReadinessCheck readinessCheck = new ReadinessCheck(); String path = getChildNodeText(settingsNode, "path"); if (path != null) { readinessCheck.setPath(path); } Integer checkIntervalSec = getChildNodePositiveInteger(settingsNode, "check-interval-sec"); if (checkIntervalSec != null) { readinessCheck.setCheckIntervalSec(checkIntervalSec); } Integer timeoutSec = getChildNodePositiveInteger(settingsNode, "timeout-sec"); if (timeoutSec != null) { readinessCheck.setTimeoutSec(timeoutSec); } Integer failureThreshold = getChildNodePositiveInteger(settingsNode, "failure-threshold"); if (failureThreshold != null) { readinessCheck.setFailureThreshold(failureThreshold); } Integer successThreshold = getChildNodePositiveInteger(settingsNode, "success-threshold"); if (successThreshold != null) { readinessCheck.setSuccessThreshold(successThreshold); } String host = getChildNodeText(settingsNode, "host"); if (host != null) { readinessCheck.setHost(host); } Integer appStartTimeoutSec = getChildNodePositiveInteger(settingsNode, "app-start-timeout-sec"); if (appStartTimeoutSec != null) { readinessCheck.setAppStartTimeoutSec(appStartTimeoutSec); } appEngineWebXml.setReadinessCheck(readinessCheck); } private void processResourcesNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { Resources resources = appEngineWebXml.getResources(); Double cpu = getChildNodeDouble(settingsNode, "cpu"); if (cpu != null) { resources.setCpu(cpu); } Double memory_gb = getChildNodeDouble(settingsNode, "memory-gb"); if (memory_gb != null) { resources.setMemoryGb(memory_gb); } Integer disk_size_gb = getChildNodePositiveInteger(settingsNode, "disk-size-gb"); if (disk_size_gb != null) { resources.setDiskSizeGb(disk_size_gb); } } private void processNetworkNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { Network network = appEngineWebXml.getNetwork(); String instance_tag = trim(getChildNodeText(settingsNode, "instance-tag")); if (instance_tag != null && !instance_tag.isEmpty()) { network.setInstanceTag(instance_tag); } for (Element subNode : getNodeIterable(settingsNode, "forwarded-port")) { String forwardedPort = XmlUtils.getText(subNode); network.addForwardedPort(forwardedPort); } String name = trim(getChildNodeText(settingsNode, "name")); if (name != null && !name.isEmpty()) { network.setName(name); } String subnetworkName = trim(getChildNodeText(settingsNode, "subnetwork-name")); if (subnetworkName != null && !subnetworkName.isEmpty()) { network.setSubnetworkName(subnetworkName); } String sessionAffinity = trim(getChildNodeText(settingsNode, "session-affinity")); if (sessionAffinity != null && !sessionAffinity.isEmpty()) { network.setSessionAffinity(toBoolean(sessionAffinity)); } } private void processEnvironmentVariablesNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "env-var")) { String propertyName = trim(subNode.getAttribute("name")); String propertyValue = trim(subNode.getAttribute("value")); appEngineWebXml.addEnvironmentVariable(propertyName, propertyValue); } } private void processBuildEnvironmentVariablesNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "build-env-var")) { String propertyName = trim(subNode.getAttribute("name")); String propertyValue = trim(subNode.getAttribute("value")); appEngineWebXml.addBuildEnvironmentVariable(propertyName, propertyValue); } } private void processPermissionsNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "permission")) { String className = trim(subNode.getAttribute("class")); if (className.equals("")) { className = null; } String name = trim(subNode.getAttribute("name")); if (name.equals("")) { name = null; } String actions = trim(subNode.getAttribute("actions")); if (actions.equals("")) { actions = null; } appEngineWebXml.addUserPermission(className, name, actions); } } private void processInboundServicesNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "service")) { String service = XmlUtils.getText(subNode); appEngineWebXml.addInboundService(service); } } private void processAdminConsoleNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "page")) { String name = trim(subNode.getAttribute("name")); String url = trim(subNode.getAttribute("url")); appEngineWebXml.addAdminConsolePage(AdminConsolePage.of(name, url)); } } private void processErrorHandlerNode(Element node, AppEngineWebXml appEngineWebXml) { for (Element subNode : getNodeIterable(node, "handler")) { String file = trim(subNode.getAttribute("file")); if (file.equals("")) { file = null; } String errorCode = trim(subNode.getAttribute("error-code")); if (errorCode.equals("")) { errorCode = null; } appEngineWebXml.addErrorHandler(ErrorHandler.of(file, errorCode)); } } private void processApiConfigNode(Element node, AppEngineWebXml appEngineWebXml) { String servlet = trim(node.getAttribute("servlet-class")); String url = trim(node.getAttribute("url-pattern")); appEngineWebXml.setApiConfig(ApiConfig.of(servlet, url)); for (Element subNode : getNodeIterable(node, "endpoint-servlet-mapping-id")) { String id = XmlUtils.getText(subNode); if (!id.isEmpty()) { appEngineWebXml.addApiEndpoint(id); } } } private void processClassLoaderConfig(Element node, AppEngineWebXml appEngineWebXml) { ClassLoaderConfig config = new ClassLoaderConfig(); appEngineWebXml.setClassLoaderConfig(config); for (Element subNode : getNodeIterable(node, "priority-specifier")) { processClassPathPrioritySpecifier(subNode, config); } } private void processClassPathPrioritySpecifier(Element node, ClassLoaderConfig config) { PrioritySpecifierEntry entry = new PrioritySpecifierEntry(); entry.setFilename(XmlUtils.getAttributeOrNull(node, "filename")); entry.setPriority(XmlUtils.getAttributeOrNull(node, "priority")); entry.checkClassLoaderConfig(); config.add(entry); } private void processVpcAccessConnector(Element node, AppEngineWebXml appEngineWebXml) { String name = getChildNodeText(node, "name"); if (name == null) { throw new AppEngineConfigException( "The element should have a name sub element."); } VpcAccessConnector.Builder connectorBuilder = VpcAccessConnector.builderFor(name); String egressSetting = getChildNodeText(node, "egress-setting"); if (egressSetting != null) { connectorBuilder.setEgressSetting(egressSetting); } appEngineWebXml.setVpcAccessConnector(connectorBuilder.build()); } private void processStagingNode(Element settingsNode, AppEngineWebXml appEngineWebXml) { StagingOptions.Builder builder = StagingOptions.builder(); String enableJarSplitting = getChildNodeText(settingsNode, "enable-jar-splitting"); if (enableJarSplitting != null) { builder.setSplitJarFiles(Optional.of(toBoolean(enableJarSplitting))); } String jarSplittingExcludes = getChildNodeText(settingsNode, "jar-splitting-excludes"); if (jarSplittingExcludes != null) { ImmutableSortedSet jarSplittingExcludeSuffixes = ImmutableSortedSet.copyOf(jarSplittingExcludes.split(",")); builder.setSplitJarFilesExcludes(Optional.of(jarSplittingExcludeSuffixes)); } String disableJarJsps = getChildNodeText(settingsNode, "disable-jar-jsps"); if (disableJarJsps != null) { builder.setJarJsps(Optional.of(!toBoolean(disableJarJsps))); } String enableJarClasses = getChildNodeText(settingsNode, "enable-jar-classes"); if (enableJarClasses != null) { builder.setJarClasses(Optional.of(toBoolean(enableJarClasses))); } String deleteJsps = getChildNodeText(settingsNode, "delete-jsps"); if (deleteJsps != null) { builder.setDeleteJsps(Optional.of(toBoolean(deleteJsps))); } String compileEncoding = getChildNodeText(settingsNode, "compile-encoding"); if (compileEncoding != null) { builder.setCompileEncoding(Optional.of(compileEncoding)); } appEngineWebXml.setStagingOptions(builder.build()); } private void processUrlStreamHandler(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setUrlStreamHandlerType(XmlUtils.getText(node)); } private boolean getBooleanValue(Element node) { return toBoolean(XmlUtils.getText(node)); } private boolean getBooleanAttributeValue(Element node, String attribute) { return toBoolean(node.getAttribute(attribute)); } private boolean toBoolean(String value) { value = value.trim(); return (value.equalsIgnoreCase("true") || value.equals("1")); } private String trim(String attribute) { return attribute == null ? null : attribute.trim(); } private void processUseGoogleConnectorJNode(Element node, AppEngineWebXml appEngineWebXml) { appEngineWebXml.setUseGoogleConnectorJ(getBooleanValue(node)); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy