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 org.apache.juneau.commons.inject.*; 020import org.apache.juneau.microservice.*; 021 022import jakarta.servlet.*; 023 024/** 025 * Zero-config convenience launcher for an embedded-Tomcat-backed Juneau microservice. 026 * 027 * <p> 028 * Wraps the {@link Microservice} + {@link TomcatConfiguration} bootstrap in a single static call so 029 * a consumer can stand up a Tomcat microservice with one Maven dependency and one line of code: 030 * 031 * <p class='bjava'> 032 * <jc>// Boot Tomcat + Juneau on the default port (8000) with the interactive console enabled.</jc> 033 * <jk>public static void</jk> main(String[] args) <jk>throws</jk> Exception { 034 * TomcatMicroservice.<jsm>run</jsm>(args, <jk>new</jk> RootResources()); 035 * } 036 * </p> 037 * 038 * <p> 039 * Bundled defaults (all overridable): 040 * <ul> 041 * <li>Port <c>8000</c> (surfaced as <c>Tomcat/port</c> in a consumer-supplied <c>juneau.cfg</c>). 042 * <li>Interactive console enabled (use {@link #run(String[], Servlet, boolean)} with 043 * {@code startConsole=false} to suppress). 044 * <li>An auto-created, auto-deleted temp Catalina base directory — a consumer-supplied 045 * {@code @Bean TomcatSettings} with {@link TomcatSettings.Builder#baseDir(String)} wins via the 046 * existing {@link TomcatServerComponent} resolution chain. 047 * </ul> 048 * 049 * <p> 050 * The supplied root servlet is registered as a {@code @Bean Servlet} in an external bean store and 051 * auto-mounted by {@link TomcatServerComponent TomcatServerComponent} 052 * at the path declared by its {@link org.apache.juneau.rest.server.Rest @Rest} annotation. Consumers 053 * who want full control over the bean store / configuration classes / listener wiring should call 054 * {@link Microservice#create()} directly — this facade is a thin convenience over that builder. 055 * 056 * @since 10.0.0 057 */ 058@SuppressWarnings({ 059 "java:S112", // throws Exception intentional - mirrors Microservice.start() lifecycle contract. 060 "resource" // beanStore lifetime is managed by the returned Microservice; not an independent resource. 061}) 062public final class TomcatMicroservice { 063 064 private TomcatMicroservice() {} 065 066 /** 067 * Boots a Tomcat microservice with the supplied root servlet and the bundled defaults, 068 * with the interactive console enabled. 069 * 070 * <p> 071 * Equivalent to calling {@link #run(String[], Servlet, boolean) run(args, rootServlet, true)}. 072 * 073 * @param args The {@code main(String[])} arguments. Forwarded to {@link org.apache.juneau.microservice.Microservice.Builder#args(String...) Microservice.Builder#args(String...)}. 074 * @param rootServlet The root REST servlet (typically annotated with 075 * {@link org.apache.juneau.rest.server.Rest @Rest}). 076 * @return The started {@link Microservice} instance. Callers typically chain {@link Microservice#join()}. 077 * @throws Exception Error occurred during bootstrap. 078 */ 079 public static Microservice run(String[] args, Servlet rootServlet) throws Exception { 080 return run(args, rootServlet, true); 081 } 082 083 /** 084 * Boots a Tomcat microservice with the supplied root servlet and the bundled defaults. 085 * 086 * <p> 087 * Constructs the {@link Microservice}, registers the supplied servlet as a {@code @Bean Servlet} so 088 * {@link TomcatServerComponent TomcatServerComponent} auto-mounts 089 * it, applies {@link TomcatConfiguration} so embedded Tomcat itself is wired, and starts the lifecycle. The 090 * returned microservice has not yet been {@link Microservice#join() joined}; callers wanting the 091 * standard "start and block forever" loop should chain {@code .join()}. 092 * 093 * @param args The {@code main(String[])} arguments. Forwarded to {@link org.apache.juneau.microservice.Microservice.Builder#args(String...) Microservice.Builder#args(String...)}. 094 * @param rootServlet The root REST servlet (typically annotated with 095 * {@link org.apache.juneau.rest.server.Rest @Rest}). 096 * @param startConsole If <jk>true</jk>, also starts the interactive console thread via 097 * {@link Microservice#startConsole()}. 098 * @return The started {@link Microservice} instance. 099 * @throws Exception Error occurred during bootstrap. 100 */ 101 public static Microservice run(String[] args, Servlet rootServlet, boolean startConsole) throws Exception { 102 var beanStore = new BasicBeanStore(); 103 beanStore.addBean(Servlet.class, rootServlet); 104 return run(args, beanStore, startConsole, TomcatConfiguration.class); 105 } 106 107 /** 108 * Power-user form: boots a Tomcat microservice with a caller-supplied bean store and configuration 109 * class list. 110 * 111 * <p> 112 * Equivalent to writing the {@link Microservice} builder chain by hand, but with the boilerplate 113 * collapsed. Use this when the simpler {@link #run(String[], Servlet)} overloads are too 114 * restrictive — e.g. multiple {@code @Bean Servlet} contributions, custom 115 * {@code MicroserviceListener}s, or a parent bean store. 116 * 117 * @param args The {@code main(String[])} arguments. Forwarded to {@link org.apache.juneau.microservice.Microservice.Builder#args(String...) Microservice.Builder#args(String...)}. 118 * @param beanStore The bean store to use for dependency injection. Pre-populated bean entries 119 * ({@code @Bean Servlet}, {@code MicroserviceListener}, etc.) are picked up by 120 * {@link TomcatConfiguration} and the microservice runtime. 121 * @param startConsole If <jk>true</jk>, also starts the interactive console thread. 122 * @param configurations The {@code @Configuration}-annotated classes to register. Always includes 123 * {@link TomcatConfiguration}; pass an empty list to use only that. 124 * @return The started {@link Microservice} instance. 125 * @throws Exception Error occurred during bootstrap. 126 */ 127 public static Microservice run(String[] args, WritableBeanStore beanStore, boolean startConsole, Class<?>... configurations) throws Exception { 128 var ms = Microservice 129 .create() 130 .args(args) 131 .beanStore(beanStore) 132 .configurations(configurations) 133 .build() 134 .start(); 135 if (startConsole) 136 ms.startConsole(); 137 return ms; 138 } 139}