001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.microservice.tomcat; 018 019import static org.apache.juneau.commons.utils.Shorts.*; 020 021import java.time.*; 022 023/** 024 * Programmatic settings for the embedded Tomcat server contributed by {@link TomcatConfiguration}. 025 * 026 * <p> 027 * Users who need to override the defaults pulled from <c>Config</c> / <c>ManifestFile</c> should 028 * contribute a <c>@Bean TomcatSettings</c> from their own <c>@Configuration</c> class. Any value 029 * left {@code null} on this settings bean falls back to the corresponding <c>Config</c> / <c>ManifestFile</c> 030 * entry, then to a hard-coded default. 031 * 032 * <h5 class='section'>Example:</h5> 033 * <p class='bjava'> 034 * <ja>@Configuration</ja> 035 * <jk>public class</jk> MyAppConfig { 036 * <ja>@Bean</ja> 037 * <jk>public</jk> TomcatSettings tomcatSettings() { 038 * <jk>return</jk> TomcatSettings.<jsm>create</jsm>() 039 * .ports(8080, 0) 040 * .build(); 041 * } 042 * } 043 * </p> 044 * 045 * <h5 class='section'>See Also:</h5><ul> 046 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauMicroserviceTomcat">juneau-microservice-tomcat</a> 047 * </ul> 048 * 049 * @since 10.0.0 050 */ 051public class TomcatSettings { 052 053 /** 054 * Builder for {@link TomcatSettings}. 055 */ 056 public static class Builder { 057 058 int[] ports; 059 String baseDir; 060 Duration stopTimeout; 061 Duration shutdownSettleDelay; 062 063 Builder() {} 064 065 /** 066 * Builds a new {@link TomcatSettings} from this builder. 067 * 068 * @return A new settings instance. 069 */ 070 public TomcatSettings build() { 071 return new TomcatSettings(this); 072 } 073 074 /** 075 * Specifies the ports to try when binding the Tomcat server. 076 * 077 * <p> 078 * The first available port is used. A value of <c>0</c> indicates "try a random port". When set, this 079 * value takes precedence over the <c>Tomcat/port</c> config-file entry and the <c>Tomcat-Port</c> 080 * manifest entry. 081 * 082 * @param value The candidate ports, in priority order. Can be <jk>null</jk> to defer to config / manifest. 083 * @return This object. 084 */ 085 public Builder ports(int...value) { 086 ports = cp(value); 087 return this; 088 } 089 090 /** 091 * Specifies the Catalina base directory used by the embedded Tomcat server for its work files. 092 * 093 * <p> 094 * When set, the {@link TomcatServerFactory} uses this directory as both the Catalina base and the root 095 * context doc-base, and the directory is left in place after the server stops. When not set, the 096 * {@link TomcatServerComponent} creates a fresh temp directory on start-up and deletes it on stop. 097 * 098 * @param value The absolute or relative path to the base directory. Can be <jk>null</jk> to use an 099 * auto-created temp directory. 100 * @return This object. 101 */ 102 public Builder baseDir(String value) { 103 baseDir = value; 104 return this; 105 } 106 107 /** 108 * Specifies the bounded graceful-shutdown drain timeout for the Tomcat server. 109 * 110 * <p> 111 * On stop, the connector is paused (stops accepting new requests) and the component waits up to this 112 * duration for in-flight requests to complete before the server stops. When set, this value takes 113 * precedence over the <c>Tomcat/stopTimeout</c> config-file entry (in milliseconds). When neither is set, 114 * a default of {@code 30s} is applied. 115 * 116 * @param value The drain timeout. Can be <jk>null</jk> to defer to config, then to the default. 117 * @return This object. 118 */ 119 public Builder stopTimeout(Duration value) { 120 stopTimeout = value; 121 return this; 122 } 123 124 /** 125 * Specifies the settle delay applied between flipping the readiness probe out of service and stopping the 126 * connector. 127 * 128 * <p> 129 * On stop, the readiness probe ({@code /readyz}) flips to {@code 503} <i>before</i> the connector is paused 130 * so a load balancer / Kubernetes stops routing new traffic. This brief delay gives the load balancer time 131 * to observe the {@code 503} before in-flight requests are drained. When set, this value takes precedence 132 * over the <c>Tomcat/shutdownSettleDelay</c> config-file entry (in milliseconds). When neither is set, no 133 * settle delay is applied (defaults to {@code 0}) — the recommended Kubernetes pattern is a 134 * {@code preStop} hook sleep instead. 135 * 136 * @param value The settle delay. Can be <jk>null</jk> to defer to config, then to the default. 137 * @return This object. 138 */ 139 public Builder shutdownSettleDelay(Duration value) { 140 shutdownSettleDelay = value; 141 return this; 142 } 143 } 144 145 /** 146 * Creates a new builder for this object. 147 * 148 * @return A new builder. 149 */ 150 public static Builder create() { 151 return new Builder(); 152 } 153 154 private final int[] ports; 155 private final String baseDir; 156 private final Duration stopTimeout; 157 private final Duration shutdownSettleDelay; 158 159 TomcatSettings(Builder b) { 160 ports = b.ports; 161 baseDir = b.baseDir; 162 stopTimeout = b.stopTimeout; 163 shutdownSettleDelay = b.shutdownSettleDelay; 164 } 165 166 /** 167 * Returns the candidate ports to try when binding the Tomcat server, in priority order. 168 * 169 * @return The ports, or <jk>null</jk> if not set. 170 */ 171 public int[] getPorts() { 172 return cp(ports); 173 } 174 175 /** 176 * Returns the Catalina base directory to use when building the Tomcat server. 177 * 178 * @return The base directory path, or <jk>null</jk> if not set (an auto-created temp directory is used). 179 */ 180 public String getBaseDir() { 181 return baseDir; 182 } 183 184 /** 185 * Returns the bounded graceful-shutdown drain timeout for the Tomcat server. 186 * 187 * @return The drain timeout, or <jk>null</jk> if not set. 188 */ 189 public Duration getStopTimeout() { 190 return stopTimeout; 191 } 192 193 /** 194 * Returns the settle delay applied between flipping the readiness probe out of service and stopping the connector. 195 * 196 * @return The settle delay, or <jk>null</jk> if not set. 197 */ 198 public Duration getShutdownSettleDelay() { 199 return shutdownSettleDelay; 200 } 201}