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.jetty; 018 019import static org.apache.juneau.commons.utils.IoUtils.*; 020import static org.apache.juneau.commons.utils.Shorts.*; 021 022import java.io.*; 023import java.nio.file.*; 024import java.time.*; 025 026/** 027 * Programmatic settings for the Jetty server contributed by {@link JettyConfiguration}. 028 * 029 * <p> 030 * Users who need to override the defaults pulled from <c>Config</c> / <c>ManifestFile</c> should 031 * contribute a <c>@Bean JettySettings</c> from their own <c>@Configuration</c> class. Any value 032 * left {@code null} on this settings bean falls back to the corresponding <c>Config</c> / <c>ManifestFile</c> 033 * entry, then to a hard-coded default. 034 * 035 * <h5 class='section'>Example:</h5> 036 * <p class='bjava'> 037 * <ja>@Configuration</ja> 038 * <jk>public class</jk> MyAppConfig { 039 * <ja>@Bean</ja> 040 * <jk>public</jk> JettySettings jettySettings() { 041 * <jk>return</jk> JettySettings.<jsm>create</jsm>() 042 * .ports(8080, 0) 043 * .build(); 044 * } 045 * } 046 * </p> 047 * 048 * <h5 class='section'>See Also:</h5><ul> 049 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauMicroserviceJetty">juneau-microservice-jetty</a> 050 * </ul> 051 * 052 * @since 10.0.0 053 */ 054public class JettySettings { 055 056 /** 057 * Builder for {@link JettySettings}. 058 */ 059 public static class Builder { 060 061 int[] ports; 062 String jettyXml; 063 Boolean jettyXmlResolveVars; 064 Duration stopTimeout; 065 Duration shutdownSettleDelay; 066 067 Builder() {} 068 069 /** 070 * Builds a new {@link JettySettings} from this builder. 071 * 072 * @return A new settings instance. 073 */ 074 public JettySettings build() { 075 return new JettySettings(this); 076 } 077 078 /** 079 * Specifies the ports to try when binding the Jetty server. 080 * 081 * <p> 082 * The first available port is used. A value of <c>0</c> indicates "try a random port". When set, this 083 * value takes precedence over the <c>Jetty/port</c> config-file entry and the <c>Jetty-Port</c> 084 * manifest entry. 085 * 086 * @param value The candidate ports, in priority order. Can be <jk>null</jk> to defer to config / manifest. 087 * @return This object. 088 */ 089 public Builder ports(int...value) { 090 ports = cp(value); 091 return this; 092 } 093 094 /** 095 * Specifies the contents or location of the <c>jetty.xml</c> file used to build the Jetty server. 096 * 097 * <p> 098 * When set, this value takes precedence over the <c>Jetty/config</c> config-file entry and the 099 * <c>Jetty-Config</c> manifest entry. When not set, the component falls back to those values and 100 * finally to a <c>jetty.xml</c> file located on the file system or classpath. 101 * 102 * @param value The contents or location of the file. Can be any of: 103 * <ul> 104 * <li>{@link String} - Relative path to a file on the file system or classpath, or the raw XML content if it begins with <c><</c>. 105 * <li>{@link File} - File on the file system. 106 * <li>{@link Path} - Path on the file system. 107 * <li>{@link InputStream} - Raw contents as a <c>UTF-8</c> encoded stream. 108 * <li>{@link Reader} - Raw contents. 109 * </ul> 110 * <br>Can be <jk>null</jk> (defers to config / manifest / classpath resolution). 111 * @param resolveVars If <jk>true</jk>, SVL variables in the file will automatically be resolved. 112 * @return This object. 113 * @throws IOException Thrown by underlying stream. 114 */ 115 public Builder jettyXml(Object value, boolean resolveVars) throws IOException { 116 if (value == null) 117 jettyXml = null; 118 else if (value instanceof String value2) 119 jettyXml = value2.startsWith("<") ? value2 : read(new File(value2)); 120 else if (value instanceof File value2) 121 jettyXml = read(value2); 122 else if (value instanceof Path value2) 123 jettyXml = read(value2); 124 else if (value instanceof InputStream value2) 125 jettyXml = read(value2); 126 else if (value instanceof Reader value2) 127 jettyXml = read(value2); 128 else 129 throw rex("Invalid object type passed to jettyXml(Object): %s", cn(value)); 130 jettyXmlResolveVars = resolveVars; 131 return this; 132 } 133 134 /** 135 * Specifies the bounded graceful-shutdown drain timeout for the Jetty server. 136 * 137 * <p> 138 * On stop, the server stops accepting new connections and waits up to this duration for in-flight requests 139 * to complete before the connector closes (Jetty's <c>stopTimeout</c>). When set, this value takes 140 * precedence over the <c>Jetty/stopTimeout</c> config-file entry (in milliseconds). When neither is set, 141 * a default of {@code 30s} is applied. 142 * 143 * @param value The drain timeout. Can be <jk>null</jk> to defer to config, then to the default. 144 * @return This object. 145 */ 146 public Builder stopTimeout(Duration value) { 147 stopTimeout = value; 148 return this; 149 } 150 151 /** 152 * Specifies the settle delay applied between flipping the readiness probe out of service and stopping the 153 * connector. 154 * 155 * <p> 156 * On stop, the readiness probe ({@code /readyz}) flips to {@code 503} <i>before</i> the connector closes so a 157 * load balancer / Kubernetes stops routing new traffic. This brief delay gives the load balancer time to 158 * observe the {@code 503} before in-flight requests are drained. When set, this value takes precedence over 159 * the <c>Jetty/shutdownSettleDelay</c> config-file entry (in milliseconds). When neither is set, no settle 160 * delay is applied (defaults to {@code 0}) — the recommended Kubernetes pattern is a {@code preStop} 161 * hook sleep instead. 162 * 163 * @param value The settle delay. Can be <jk>null</jk> to defer to config, then to the default. 164 * @return This object. 165 */ 166 public Builder shutdownSettleDelay(Duration value) { 167 shutdownSettleDelay = value; 168 return this; 169 } 170 } 171 172 /** 173 * Creates a new builder for this object. 174 * 175 * @return A new builder. 176 */ 177 public static Builder create() { 178 return new Builder(); 179 } 180 181 private final int[] ports; 182 private final String jettyXml; 183 private final Boolean jettyXmlResolveVars; 184 private final Duration stopTimeout; 185 private final Duration shutdownSettleDelay; 186 187 JettySettings(Builder b) { 188 ports = b.ports; 189 jettyXml = b.jettyXml; 190 jettyXmlResolveVars = b.jettyXmlResolveVars; 191 stopTimeout = b.stopTimeout; 192 shutdownSettleDelay = b.shutdownSettleDelay; 193 } 194 195 /** 196 * Returns the candidate ports to try when binding the Jetty server, in priority order. 197 * 198 * @return The ports, or <jk>null</jk> if not set. 199 */ 200 public int[] getPorts() { 201 return cp(ports); 202 } 203 204 /** 205 * Returns the raw <c>jetty.xml</c> contents to use when building the server. 206 * 207 * @return The XML contents, or <jk>null</jk> if not set. 208 */ 209 public String getJettyXml() { 210 return jettyXml; 211 } 212 213 /** 214 * Returns whether SVL variables in the <c>jetty.xml</c> file should be resolved. 215 * 216 * @return The resolve-vars flag, or <jk>null</jk> if not set. 217 */ 218 public Boolean getJettyXmlResolveVars() { 219 return jettyXmlResolveVars; 220 } 221 222 /** 223 * Returns the bounded graceful-shutdown drain timeout for the Jetty server. 224 * 225 * @return The drain timeout, or <jk>null</jk> if not set. 226 */ 227 public Duration getStopTimeout() { 228 return stopTimeout; 229 } 230 231 /** 232 * Returns the settle delay applied between flipping the readiness probe out of service and stopping the connector. 233 * 234 * @return The settle delay, or <jk>null</jk> if not set. 235 */ 236 public Duration getShutdownSettleDelay() { 237 return shutdownSettleDelay; 238 } 239}