This is an automated email from the ASF dual-hosted git repository. jamesbognar pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/juneau.git
The following commit(s) were added to refs/heads/master by this push: new c59f01acc Fix bug with RestObject objects. c59f01acc is described below commit c59f01accec64b58b8441415dfd4a81a3e43d28d Author: JamesBognar <james.bog...@salesforce.com> AuthorDate: Thu Jun 16 11:11:33 2022 -0400 Fix bug with RestObject objects. --- .../java/org/apache/juneau/reflect/ClassInfo.java | 2 +- .../logs/.gitignore | 1 + .../juneau/examples/rest/RootContentTest.java | 2 +- .../juneau-examples-rest-jetty/logs/.gitignore | 1 + .../juneau-examples-rest-jetty/logs/empty.txt | 0 .../examples/rest/springboot/RootResources.java | 1 - .../apache/juneau/examples/rest/RootResources.java | 1 - .../juneau/examples/rest/UtilityBeansResource.java | 123 +++++++ .../org/apache/juneau/microservice/LogConfig.java | 211 ------------ .../apache/juneau/microservice/Microservice.java | 78 +---- .../microservice/resources/LogEntryFormatter.java | 272 --------------- .../juneau/microservice/resources/LogParser.java | 234 ------------- .../microservice/resources/LogsResource.java | 373 --------------------- .../microservice/resources/SampleRootResource.java | 2 +- .../java/org/apache/juneau/rest/test/Root.java | 1 - .../rest/test/client/ThirdPartyProxyResource.java | 1 + .../microservice/jetty/JettyMicroservice.java | 6 - .../microservice/jetty/template/RootResources.java | 2 - .../springboot/template/RootResources.java | 3 +- .../java/org/apache/juneau/rest/RestContext.java | 4 +- pom.xml | 1 + 21 files changed, 134 insertions(+), 1185 deletions(-) diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java index eb33c0b13..ea7d195e6 100644 --- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java +++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java @@ -120,7 +120,7 @@ public final class ClassInfo { * @return The constructed class info, or <jk>null</jk> if the object was <jk>null</jk>. */ public static ClassInfo of(Object o) { - return of(o == null ? null : o.getClass()); + return of(o == null ? null : o instanceof Class ? (Class<?>)o : o.getClass()); } /** diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/logs/.gitignore b/juneau-examples/juneau-examples-rest-jetty-ftest/logs/.gitignore new file mode 100644 index 000000000..bd317cc13 --- /dev/null +++ b/juneau-examples/juneau-examples-rest-jetty-ftest/logs/.gitignore @@ -0,0 +1 @@ +/*log* diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java index 9dcd8764c..1383e0493 100644 --- a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java +++ b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java @@ -95,7 +95,7 @@ public class RootContentTest extends ContentComboTestBase { }, { /* 10 */ new ComboInput("HTML-content-octal/msgpack", "/", MediaType.MSGPACK, - "95 82 A4" + "94 82 A4" ) }, { /* 11 */ diff --git a/juneau-examples/juneau-examples-rest-jetty/logs/.gitignore b/juneau-examples/juneau-examples-rest-jetty/logs/.gitignore new file mode 100644 index 000000000..bd317cc13 --- /dev/null +++ b/juneau-examples/juneau-examples-rest-jetty/logs/.gitignore @@ -0,0 +1 @@ +/*log* diff --git a/juneau-examples/juneau-examples-rest-jetty/logs/empty.txt b/juneau-examples/juneau-examples-rest-jetty/logs/empty.txt new file mode 100644 index 000000000..e69de29bb diff --git a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java index e560cf1d2..dc6f6bd2c 100644 --- a/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java +++ b/juneau-examples/juneau-examples-rest-springboot/src/main/java/org/apache/juneau/examples/rest/springboot/RootResources.java @@ -39,7 +39,6 @@ import org.apache.juneau.serializer.annotation.*; HelloWorldResource.class, DtoExamples.class, ConfigResource.class, - LogsResource.class, ShutdownResource.class } ) diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java index bae630594..de6fb06c3 100644 --- a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/RootResources.java @@ -39,7 +39,6 @@ import org.apache.juneau.serializer.annotation.*; HelloWorldResource.class, DtoExamples.class, ConfigResource.class, - LogsResource.class, ShutdownResource.class } ) diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java new file mode 100644 index 000000000..b958bd0eb --- /dev/null +++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/UtilityBeansResource.java @@ -0,0 +1,123 @@ +// *************************************************************************************************************************** +// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * +// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * +// * to you 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 * +// * * +// * http://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 org.apache.juneau.examples.rest; + +import java.util.*; + +import org.apache.juneau.annotation.*; +import org.apache.juneau.examples.parser.*; +import org.apache.juneau.examples.serializer.*; +import org.apache.juneau.html.annotation.*; +import org.apache.juneau.http.annotation.*; +import org.apache.juneau.http.response.*; +import org.apache.juneau.rest.annotation.*; +import org.apache.juneau.rest.beans.*; +import org.apache.juneau.rest.config.*; +import org.apache.juneau.rest.servlet.*; + +import java.awt.image.*; +import java.net.*; + +/** + * Sample resource that allows images to be uploaded and retrieved. + * + * <ul class='seealso'> + * <li class='link'>{@doc jrs.Marshalling REST Marshalling} + * <li class='jc'>{@link ImageSerializer} + * <li class='jc'>{@link ImageParser} + * <li class='extlink'>{@source} + * </ul> + */ +@Rest( + path="/utilitybeans", + title="Utility beans examples", + description="Examples of utility bean usage." +) +@HtmlDocConfig( + navlinks="options: ?method=OPTIONS" +) +public class UtilityBeansResource extends BasicRestServlet implements BasicUniversalConfig { + + private static final long serialVersionUID = 1L; + + @RestGet("/") + public ResourceDescriptions getDescriptions() { + return ResourceDescriptions + .create() + .append("BeanDescription", "Example of BeanDescription bean"); + } + + + @RestGet("/BeanDescription") + public BeanDescription aBeanDescription() { + return BeanDescription.of(AddressBook.class); + } + + public static class AddressBook extends LinkedList<Person> { + + public AddressBook init() { + add( + new Person("Bill Clinton", 65, + new Address("55W. 125th Street", "New York", "NY", 10027, true) + ) + ); + return this; + } + } + + @Bean(p="street,city,state,zip,isCurrent") + public static class Address { + public String street; + public String city; + public String state; + public int zip; + public boolean isCurrent; + + public Address() {} + + public Address(String street, String city, String state, int zip, boolean isCurrent) { + this.street = street; + this.city = city; + this.state = state; + this.zip = zip; + this.isCurrent = isCurrent; + } + @Override /* Object */ + public String toString() { + return "Address(street="+street+",city="+city+",state="+state+",zip="+zip+",isCurrent="+isCurrent+")"; + } + } + + @Bean(typeName="Person",p="name,age,addresses") + public static class Person { + public String name; + public int age; + public Address[] addresses; + + public Person() {} + + public Person(String name, int age, Address...addresses) { + this.name = name; + this.age = age; + this.addresses = addresses; + } + + @Override /* Object */ + public String toString() { + return "Person(name="+name+",age="+age+")"; + } + } + + + +} \ No newline at end of file diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/LogConfig.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/LogConfig.java deleted file mode 100644 index 5221f8b85..000000000 --- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/LogConfig.java +++ /dev/null @@ -1,211 +0,0 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you 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 * -// * * -// * http://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 org.apache.juneau.microservice; - -import static org.apache.juneau.internal.CollectionUtils.*; - -import java.util.*; -import java.util.logging.*; -import java.util.logging.Formatter; - -import org.apache.juneau.microservice.resources.*; - -/** - * Can be used for configuration of simple logging in the microservice. - * - * <p> - * Instances of this class can be created using {@link #create()} and passing the result to - * {@link Microservice.Builder#logConfig(LogConfig)}. - * - * <p> - * These values override values specified in the <js>"Logging"</js> configuration section. - * - * <ul class='seealso'> - * <li class='link'>{@doc juneau-microservice-core} - * <li class='extlink'>{@source} - * </ul> - */ -public class LogConfig { - - String logFile, logDir; - Boolean append; - Integer limit, count; - Level fileLevel, consoleLevel; - Map<String,Level> levels = map(); - Formatter formatter; - - LogConfig() {} - - /** - * Copy constructor. - * - * @param copyFrom The log config to copy from. - */ - protected LogConfig(LogConfig copyFrom) { - this.logFile = copyFrom.logFile; - this.logDir = copyFrom.logDir; - this.append = copyFrom.append; - this.limit = copyFrom.limit; - this.count = copyFrom.count; - this.fileLevel = copyFrom.fileLevel; - this.consoleLevel = copyFrom.consoleLevel; - this.levels = copyOf(copyFrom.levels); - this.formatter = copyFrom.formatter; - } - - /** - * Creates a copy of this log configuration. - * - * @return A new copy of this log configuration. - */ - public LogConfig copy() { - return new LogConfig(this); - } - - /** - * Creates a new instance of this config. - * - * @return A new instance of this config. - */ - public static LogConfig create() { - return new LogConfig(); - } - - /** - * Returns the name of the log file on the file system to store the log file for this microservice. - * - * <p> - * This overrides the configuration value <js>"Logging/logFile"</js>. - * If not specified, no file system logging will be used. - * - * @param logFile The log file. - * @return This object. - */ - public LogConfig logFile(String logFile) { - this.logFile = logFile; - return this; - } - - /** - * The location of the log directory to create the log file. - * - * <p> - * This overrides the configuration value <js>"Logging/logDir"</js>. - * If not specified, uses the JVM working directory. - * - * @param logDir The log directory location as a path relative to the working directory. - * @return This object. - */ - public LogConfig logDir(String logDir) { - this.logDir = logDir; - return this; - } - - /** - * The log entry formatter. - * - * <p> - * If not specified, uses the following values pulled from the configuration to construct a {@link LogEntryFormatter}: - * <ul> - * <li><js><js>"Logging/format"</js> (default is <js>"[{date} {level}] {msg}%n"</js>) - * <li><js><js>"Logging/dateFormat"</js> (default is <js>"yyyy.MM.dd hh:mm:ss"</js>) - * <li><js><js>"Logging/useStackTraceHashes"</js> (default is <jk>false</jk>) - * </ul> - * - * - * @param formatter The log entry formatter. - * @return This object. - * @see LogEntryFormatter - */ - public LogConfig formatter(Formatter formatter) { - this.formatter = formatter; - return this; - } - - /** - * Specified append mode for the log file. - * - * @return This object. - */ - public LogConfig append() { - this.append = true; - return this; - } - - /** - * The maximum number of bytes to write to any one log file. - * - * @param limit The number of bytes. - * @return This object. - */ - public LogConfig limit(int limit) { - this.limit = limit; - return this; - } - - /** - * The number of log files to use. - * - * @param count The number of log files. - * @return This object. - */ - public LogConfig count(int count) { - this.count = count; - return this; - } - - /** - * The default logging level for the log file. - * - * @param fileLevel The logging level. - * @return This object. - */ - public LogConfig fileLevel(Level fileLevel) { - this.fileLevel = fileLevel; - return this; - } - - /** - * The default logging level for the console. - * - * @param consoleLevel The logging level. - * @return This object. - */ - public LogConfig consoleLevel(Level consoleLevel) { - this.consoleLevel = consoleLevel; - return this; - } - - /** - * Default logging levels for loggers. - * - * @param levels A map of logger names to logger levels. - * @return This object. - */ - public LogConfig levels(Map<String,Level> levels) { - this.levels.putAll(levels); - return this; - } - - /** - * Default logging level for logger. - * - * @param logger Logger name. - * @param level Logger level. - * @return This object. - */ - public LogConfig level(String logger, Level level) { - this.levels.put(logger, level); - return this; - } -} diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java index 74ac9489c..7f12f0b61 100755 --- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java +++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/Microservice.java @@ -14,9 +14,7 @@ package org.apache.juneau.microservice; import static org.apache.juneau.internal.ClassUtils.*; import static org.apache.juneau.internal.CollectionUtils.*; -import static org.apache.juneau.internal.FileUtils.*; import static org.apache.juneau.internal.IOUtils.*; -import static org.apache.juneau.internal.ObjectUtils.*; import static org.apache.juneau.internal.StringUtils.*; import static org.apache.juneau.internal.ThrowableUtils.*; @@ -28,7 +26,6 @@ import java.util.*; import java.util.concurrent.*; import java.util.jar.*; import java.util.logging.*; -import java.util.logging.Formatter; import org.apache.juneau.*; import org.apache.juneau.collections.*; @@ -40,7 +37,6 @@ import org.apache.juneau.config.vars.*; import org.apache.juneau.cp.*; import org.apache.juneau.internal.*; import org.apache.juneau.microservice.console.*; -import org.apache.juneau.microservice.resources.*; import org.apache.juneau.parser.ParseException; import org.apache.juneau.svl.*; import org.apache.juneau.svl.vars.*; @@ -145,7 +141,6 @@ public class Microservice implements ConfigEventListener { Args args; ManifestFile manifest; Logger logger; - LogConfig logConfig; Config config; String configName; ConfigStore configStore; @@ -173,7 +168,6 @@ public class Microservice implements ConfigEventListener { this.manifest = copyFrom.manifest; this.logger = copyFrom.logger; this.configName = copyFrom.configName; - this.logConfig = copyFrom.logConfig == null ? null : copyFrom.logConfig.copy(); this.consoleEnabled = copyFrom.consoleEnabled; this.configBuilder = copyFrom.configBuilder; this.varResolver = copyFrom.varResolver; @@ -290,9 +284,6 @@ public class Microservice implements ConfigEventListener { /** * Specifies the logger used by the microservice and returned by the {@link Microservice#getLogger()} method. * - * <p> - * Calling this method overrides the default logging mechanism controlled by the {@link #logConfig(LogConfig)} method. - * * @param logger The logger to use for logging microservice messages. * @return This object. */ @@ -301,23 +292,6 @@ public class Microservice implements ConfigEventListener { return this; } - /** - * Specifies logging instructions for the microservice. - * - * <p> - * If not specified, the values are taken from the <js>"Logging"</js> section of the configuration. - * - * <p> - * This method is ignored if {@link #logger(Logger)} is used to set the microservice logger. - * - * @param logConfig The log configuration. - * @return This object. - */ - public Builder logConfig(LogConfig logConfig) { - this.logConfig = logConfig; - return this; - } - /** * Specifies the config for initializing this microservice. * @@ -549,7 +523,6 @@ public class Microservice implements ConfigEventListener { final Messages messages = Messages.of(Microservice.class); - private final Builder builder; private final Args args; private final Config config; private final ManifestFile manifest; @@ -563,7 +536,7 @@ public class Microservice implements ConfigEventListener { final File workingDir; private final String configName; - private volatile Logger logger; + private volatile Logger logger = Logger.getGlobal(); /** * Constructor. @@ -572,10 +545,8 @@ public class Microservice implements ConfigEventListener { * @throws IOException Problem occurred reading file. * @throws ParseException Malformed input encountered. */ - @SuppressWarnings("resource") protected Microservice(Builder builder) throws IOException, ParseException { setInstance(this); - this.builder = builder.copy(); this.workingDir = builder.workingDir; this.configName = builder.configName; @@ -764,53 +735,6 @@ public class Microservice implements ConfigEventListener { for (String key : spKeys) System.setProperty(key, config.get("SystemProperties/"+key).orElse(null)); - // -------------------------------------------------------------------------------- - // Initialize logging. - // -------------------------------------------------------------------------------- - this.logger = builder.logger; - LogConfig logConfig = builder.logConfig != null ? builder.logConfig : new LogConfig(); - if (this.logger == null) { - LogManager.getLogManager().reset(); - this.logger = Logger.getLogger(""); - String logFile = firstNonNull(logConfig.logFile, config.get("Logging/logFile").orElse(null)); - - if (isNotEmpty(logFile)) { - String logDir = firstNonNull(logConfig.logDir, config.get("Logging/logDir").orElse(".")); - File logDirFile = resolveFile(logDir); - mkdirs(logDirFile, false); - logDir = logDirFile.getAbsolutePath(); - System.setProperty("juneau.logDir", logDir); - - boolean append = firstNonNull(logConfig.append, config.get("Logging/append").asBoolean().orElse(false)); - int limit = firstNonNull(logConfig.limit, config.get("Logging/limit").asInteger().orElse(1024*1024)); - int count = firstNonNull(logConfig.count, config.get("Logging/count").asInteger().orElse(1)); - - FileHandler fh = new FileHandler(logDir + '/' + logFile, limit, count, append); - - Formatter f = logConfig.formatter; - if (f == null) { - String format = config.get("Logging/format").orElse("[{date} {level}] {msg}%n"); - String dateFormat = config.get("Logging/dateFormat").orElse("yyyy.MM.dd hh:mm:ss"); - boolean useStackTraceHashes = config.get("Logging/useStackTraceHashes").asBoolean().orElse(false); - f = new LogEntryFormatter(format, dateFormat, useStackTraceHashes); - } - fh.setFormatter(f); - fh.setLevel(firstNonNull(logConfig.fileLevel, config.get("Logging/fileLevel").as(Level.class).orElse(Level.INFO))); - logger.addHandler(fh); - - ConsoleHandler ch = new ConsoleHandler(); - ch.setLevel(firstNonNull(logConfig.consoleLevel, config.get("Logging/consoleLevel").as(Level.class).orElse(Level.WARNING))); - ch.setFormatter(f); - logger.addHandler(ch); - } - } - - JsonMap loggerLevels = config.get("Logging/levels").as(JsonMap.class).orElseGet(JsonMap::new); - for (String l : loggerLevels.keySet()) - Logger.getLogger(l).setLevel(loggerLevels.get(l, Level.class)); - for (String l : logConfig.levels.keySet()) - Logger.getLogger(l).setLevel(logConfig.levels.get(l)); - return this; } diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogEntryFormatter.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogEntryFormatter.java deleted file mode 100644 index 5b8d915b0..000000000 --- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogEntryFormatter.java +++ /dev/null @@ -1,272 +0,0 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you 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 * -// * * -// * http://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 org.apache.juneau.microservice.resources; - -import static org.apache.juneau.internal.CollectionUtils.*; -import static org.apache.juneau.internal.ThrowableUtils.*; - -import java.text.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.logging.*; -import java.util.logging.Formatter; -import java.util.regex.*; - -/** - * Log entry formatter. - * - * <p> - * Uses three simple parameter for configuring log entry formats: - * <ul class='spaced-list'> - * <li> - * <c>dateFormat</c> - A {@link SimpleDateFormat} string describing the format for dates. - * <li> - * <c>format</c> - A string with <c>{...}</c> replacement variables representing predefined fields. - * <li> - * <c>useStackTraceHashes</c> - A setting that causes duplicate stack traces to be replaced with 8-character - * hash strings. - * </ul> - * - * <p> - * This class converts the format strings into a regular expression that can be used to parse the resulting log file. - * - * <ul class='seealso'> - * <li class='link'>{@doc juneau-microservice-core} - * <li class='extlink'>{@source} - * </ul> - */ -public class LogEntryFormatter extends Formatter { - - private ConcurrentHashMap<String,AtomicInteger> hashes; - private DateFormat df; - private String format; - private Pattern rePattern; - private Map<String,Integer> fieldIndexes; - - /** - * Create a new formatter. - * - * @param format - * The log entry format. e.g. <js>"[{date} {level}] {msg}%n"</js> - * The string can contain any of the following variables: - * <ol> - * <li><js>"{date}"</js> - The date, formatted per <js>"Logging/dateFormat"</js>. - * <li><js>"{class}"</js> - The class name. - * <li><js>"{method}"</js> - The method name. - * <li><js>"{logger}"</js> - The logger name. - * <li><js>"{level}"</js> - The log level name. - * <li><js>"{msg}"</js> - The log message. - * <li><js>"{threadid}"</js> - The thread ID. - * <li><js>"{exception}"</js> - The localized exception message. - * </ol> - * @param dateFormat - * The {@link SimpleDateFormat} format to use for dates. e.g. <js>"yyyy.MM.dd hh:mm:ss"</js>. - * @param useStackTraceHashes - * If <jk>true</jk>, only print unique stack traces once and then refer to them by a simple 8 character hash - * identifier. - */ - public LogEntryFormatter(String format, String dateFormat, boolean useStackTraceHashes) { - this.df = new SimpleDateFormat(dateFormat); - if (useStackTraceHashes) - hashes = new ConcurrentHashMap<>(); - - fieldIndexes = new HashMap<>(); - - format = format - .replaceAll("\\{date\\}", "%1\\$s") - .replaceAll("\\{class\\}", "%2\\$s") - .replaceAll("\\{method\\}", "%3\\$s") - .replaceAll("\\{logger\\}", "%4\\$s") - .replaceAll("\\{level\\}", "%5\\$s") - .replaceAll("\\{msg\\}", "%6\\$s") - .replaceAll("\\{threadid\\}", "%7\\$s") - .replaceAll("\\{exception\\}", "%8\\$s"); - - this.format = format; - - // Construct a regular expression to match this log entry. - int index = 1; - StringBuilder re = new StringBuilder(); - int S1 = 1; // Looking for % - int S2 = 2; // Found %, looking for number. - int S3 = 3; // Found number, looking for $. - int S4 = 4; // Found $, looking for s. - int state = 1; - int i1 = 0; - for (int i = 0; i < format.length(); i++) { - char c = format.charAt(i); - if (state == S1) { - if (c == '%') - state = S2; - else { - if (! (Character.isLetterOrDigit(c) || Character.isWhitespace(c))) - re.append('\\'); - re.append(c); - } - } else if (state == S2) { - if (Character.isDigit(c)) { - i1 = i; - state = S3; - } else { - re.append("\\%").append(c); - state = S1; - } - } else if (state == S3) { - if (c == '$') { - state = S4; - } else { - re.append("\\%").append(format.substring(i1, i)); - state = S1; - } - } else if (state == S4) { - if (c == 's') { - int group = Integer.parseInt(format.substring(i1, i-1)); - switch (group) { - case 1: - fieldIndexes.put("date", index++); - re.append("(" + dateFormat.replaceAll("[mHhsSdMy]", "\\\\d").replaceAll("\\.", "\\\\.") + ")"); - break; - case 2: - fieldIndexes.put("class", index++); - re.append("([\\p{javaJavaIdentifierPart}\\.]+)"); - break; - case 3: - fieldIndexes.put("method", index++); - re.append("([\\p{javaJavaIdentifierPart}\\.]+)"); - break; - case 4: - fieldIndexes.put("logger", index++); - re.append("([\\w\\d\\.\\_]+)"); - break; - case 5: - fieldIndexes.put("level", index++); - re.append("(SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST)"); - break; - case 6: - fieldIndexes.put("msg", index++); - re.append("(.*)"); - break; - case 7: - fieldIndexes.put("threadid", index++); - re.append("(\\\\d+)"); - break; - case 8: - fieldIndexes.put("exception", index++); - re.append("(.*)"); - break; - default: // Fall through. - } - } else { - re.append("\\%").append(format.substring(i1, i)); - } - state = S1; - } - } - - // The log parser - String sre = re.toString(); - if (sre.endsWith("\\%n")) - sre = sre.substring(0, sre.length()-3); - - // Replace instances of %n. - sre = sre.replaceAll("\\\\%n", "\\\\n"); - - rePattern = Pattern.compile(sre); - fieldIndexes = unmodifiable(fieldIndexes); - } - - /** - * Returns the regular expression pattern used for matching log entries. - * - * @return The regular expression pattern used for matching log entries. - */ - public Pattern getLogEntryPattern() { - return rePattern; - } - - /** - * Returns the {@link DateFormat} used for matching dates. - * - * @return The {@link DateFormat} used for matching dates. - */ - public DateFormat getDateFormat() { - return df; - } - - /** - * Given a matcher that has matched the pattern specified by {@link #getLogEntryPattern()}, returns the field value - * from the match. - * - * @param fieldName - * The field name. - * Possible values are: - * <ul> - * <li><js>"date"</js> - * <li><js>"class"</js> - * <li><js>"method"</js> - * <li><js>"logger"</js> - * <li><js>"level"</js> - * <li><js>"msg"</js> - * <li><js>"threadid"</js> - * <li><js>"exception"</js> - * </ul> - * @param m The matcher. - * @return The field value, or <jk>null</jk> if the specified field does not exist. - */ - public String getField(String fieldName, Matcher m) { - Integer i = fieldIndexes.get(fieldName); - return (i == null ? null : m.group(i)); - } - - @Override /* Formatter */ - public String format(LogRecord r) { - String msg = formatMessage(r); - Throwable t = r.getThrown(); - String hash = null; - int c = 0; - if (hashes != null && t != null) { - hash = hashCode(t); - hashes.putIfAbsent(hash, new AtomicInteger(0)); - c = hashes.get(hash).incrementAndGet(); - if (c <= 5) { - msg = '[' + hash + '.' + c + "] " + msg; - } else { - msg = '[' + hash + '.' + c + "] " + msg + ", " + t.getLocalizedMessage(); - t = null; - } - } - String s = String.format(format, - df.format(new Date(r.getMillis())), - r.getSourceClassName(), - r.getSourceMethodName(), - r.getLoggerName(), - r.getLevel(), - msg, - r.getThreadID(), - r.getThrown() == null ? "" : r.getThrown().getMessage()); - if (t != null) - s += String.format("%s", getStackTrace(r.getThrown())); - return s; - } - - private static String hashCode(Throwable t) { - int i = 0; - while (t != null) { - for (StackTraceElement e : t.getStackTrace()) - i ^= e.hashCode(); - t = t.getCause(); - } - return Integer.toHexString(i); - } -} diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogParser.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogParser.java deleted file mode 100644 index 7e1b310e8..000000000 --- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogParser.java +++ /dev/null @@ -1,234 +0,0 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you 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 * -// * * -// * http://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 org.apache.juneau.microservice.resources; - -import static org.apache.juneau.internal.CollectionUtils.*; -import static org.apache.juneau.internal.ThrowableUtils.*; - -import java.io.*; -import java.nio.charset.*; -import java.text.*; -import java.util.*; -import java.util.regex.*; - -/** - * Utility class for reading log files. - * - * <p> - * Provides the capability of returning splices of log files based on dates and filtering based on thread and logger - * names. - * - * <ul class='seealso'> - * <li class='link'>{@doc juneau-microservice-core} - * <li class='extlink'>{@source} - * </ul> - */ -public final class LogParser implements Iterable<LogParser.Entry>, Iterator<LogParser.Entry>, Closeable { - private BufferedReader br; - LogEntryFormatter formatter; - Date start, end; - Set<String> loggerFilter, severityFilter; - String threadFilter; - private Entry next; - - /** - * Constructor. - * - * @param formatter The log entry formatter. - * @param f The log file. - * @param start Don't return rows before this date. If <jk>null</jk>, start from the beginning of the file. - * @param end Don't return rows after this date. If <jk>null</jk>, go to the end of the file. - * @param thread Only return log entries with this thread name. - * @param loggers Only return log entries produced by these loggers (simple class names). - * @param severity Only return log entries with the specified severity. - * @throws IOException Thrown by underlying stream. - */ - public LogParser(LogEntryFormatter formatter, File f, Date start, Date end, String thread, String[] loggers, String[] severity) throws IOException { - br = new BufferedReader(new InputStreamReader(new FileInputStream(f), Charset.defaultCharset())); - this.formatter = formatter; - this.start = start; - this.end = end; - this.threadFilter = thread; - if (loggers != null) - this.loggerFilter = set(loggers); - if (severity != null) - this.severityFilter = set(severity); - - // Find the first line. - String line; - while (next == null && (line = br.readLine()) != null) { - Entry e = new Entry(line); - if (e.matches()) - next = e; - } - } - - @Override /* Iterator */ - public boolean hasNext() { - return next != null; - } - - @Override /* Iterator */ - public Entry next() { - Entry current = next; - Entry prev = next; - try { - next = null; - String line = null; - while (next == null && (line = br.readLine()) != null) { - Entry e = new Entry(line); - if (e.isRecord) { - if (e.matches()) - next = e; - prev = null; - } else { - if (prev != null) - prev.addText(e.line); - } - } - } catch (IOException e) { - throw runtimeException(e); - } - return current; - } - - @Override /* Iterator */ - public void remove() { - throw new NoSuchMethodError(); - } - - @Override /* Iterable */ - public Iterator<Entry> iterator() { - return this; - } - - @Override /* Closeable */ - public void close() throws IOException { - br.close(); - } - - /** - * Serializes the contents of the parsed log file to the specified writer and then closes the underlying reader. - * - * @param w The writer to write the log file to. - * @throws IOException Thrown by underlying stream. - */ - public void writeTo(Writer w) throws IOException { - try { - if (! hasNext()) - w.append("[EMPTY]"); - else { - forEach(le -> safeRun(()->le.append(w))); - } - } finally { - close(); - } - } - - /** - * Represents a single line from the log file. - */ - @SuppressWarnings("javadoc") - public final class Entry { - public Date date; - public String severity, logger; - protected String line, text; - protected String thread; - protected List<String> additionalText; - protected boolean isRecord; - - Entry(String line) throws IOException { - try { - this.line = line; - Matcher m = formatter.getLogEntryPattern().matcher(line); - if (m.matches()) { - isRecord = true; - String s = formatter.getField("date", m); - if (s != null) - date = formatter.getDateFormat().parse(s); - thread = formatter.getField("thread", m); - severity = formatter.getField("level", m); - logger = formatter.getField("logger", m); - text = formatter.getField("msg", m); - if (logger != null && logger.indexOf('.') > -1) - logger = logger.substring(logger.lastIndexOf('.')+1); - } - } catch (ParseException e) { - throw ioException(e); - } - } - - void addText(String t) { - if (additionalText == null) - additionalText = new LinkedList<>(); - additionalText.add(t); - } - - public String getText() { - if (additionalText == null) - return text; - if (text == null) - return ""; - int i = text.length(); - for (String s : additionalText) - i += s.length() + 1; - StringBuilder sb = new StringBuilder(i); - sb.append(text); - additionalText.forEach(s -> sb.append('\n').append(s)); - return sb.toString(); - } - - public String getThread() { - return thread; - } - - public Writer appendHtml(Writer w) throws IOException { - w.append(toHtml(line)).append("<br>"); - if (additionalText != null) - for (String t : additionalText) - w.append(toHtml(t)).append("<br>"); - return w; - } - - protected Writer append(Writer w) throws IOException { - w.append(line).append('\n'); - if (additionalText != null) - for (String t : additionalText) - w.append(t).append('\n'); - return w; - } - - boolean matches() { - if (! isRecord) - return false; - if (start != null && date.before(start)) - return false; - if (end != null && date.after(end)) - return false; - if (threadFilter != null && ! threadFilter.equals(thread)) - return false; - if (loggerFilter != null && ! loggerFilter.contains(logger)) - return false; - if (severityFilter != null && ! severityFilter.contains(severity)) - return false; - return true; - } - } - - static final String toHtml(String s) { - if (s.indexOf('<') != -1) - return s.replaceAll("<", "<");//$NON-NLS-2$ - return s; - } -} - diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java deleted file mode 100755 index fb1da1227..000000000 --- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/LogsResource.java +++ /dev/null @@ -1,373 +0,0 @@ -// *************************************************************************************************************************** -// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * -// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * -// * to you 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 * -// * * -// * http://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 org.apache.juneau.microservice.resources; - -import static org.apache.juneau.internal.CollectionUtils.*; -import static org.apache.juneau.internal.StringUtils.*; - -import java.io.*; -import java.nio.charset.*; -import java.util.*; - -import org.apache.juneau.annotation.*; -import org.apache.juneau.config.*; -import org.apache.juneau.dto.*; -import org.apache.juneau.html.annotation.*; -import org.apache.juneau.http.annotation.*; -import org.apache.juneau.http.response.*; -import org.apache.juneau.rest.*; -import org.apache.juneau.rest.annotation.*; -import org.apache.juneau.rest.beans.*; -import org.apache.juneau.rest.config.*; -import org.apache.juneau.rest.converter.*; -import org.apache.juneau.rest.servlet.*; - -/** - * REST resource for viewing and accessing log files. - * - * <ul class='seealso'> - * <li class='link'>{@doc juneau-microservice-core} - * <li class='extlink'>{@source} - * </ul> - * - * @serial exclude - */ -@Rest( - path="/logs", - title="Log files", - description="Log files from this service", - allowedMethodParams="*" -) -@HtmlConfig(uriAnchorText="PROPERTY_NAME") -@SuppressWarnings("javadoc") -public class LogsResource extends BasicRestServlet implements BasicUniversalConfig { - private static final long serialVersionUID = 1L; - - //------------------------------------------------------------------------------------------------------------------- - // Configurable properties - //------------------------------------------------------------------------------------------------------------------- - - private static final String PREFIX = "LogsResource."; - - /** - * Root directory. - */ - public static final String LOGS_RESOURCE_logDir = PREFIX + "logDir.s"; - - /** - * Allow deletes on files. - */ - public static final String LOGS_RESOURCE_allowDeletes = PREFIX + "allowDeletes.b"; - - /** - * Log entry format. - */ - public static final String LOGS_RESOURCE_logFormat = PREFIX + "logFormat.s"; - - /** - * Log entry format. - */ - public static final String LOGS_RESOURCE_dateFormat = PREFIX + "dateFormat.s"; - - /** - * Log entry format. - */ - public static final String LOGS_RESOURCE_useStackTraceHashes = PREFIX + "useStackTraceHashes.b"; - - //------------------------------------------------------------------------------------------------------------------- - // Instance - //------------------------------------------------------------------------------------------------------------------- - - private final File logDir; - private final LogEntryFormatter leFormatter; - final boolean allowDeletes; - - public LogsResource(Config c) { - logDir = new File(c.get(LOGS_RESOURCE_logDir).orElse("logDir")); - allowDeletes = c.get(LOGS_RESOURCE_allowDeletes).asBoolean().orElse(true); - leFormatter = new LogEntryFormatter( - c.get(LOGS_RESOURCE_logFormat).orElse("[{date} {level}] {msg}%n"), - c.get(LOGS_RESOURCE_dateFormat).orElse("yyyy.MM.dd hh:mm:ss"), - c.get(LOGS_RESOURCE_useStackTraceHashes).asBoolean().orElse(true) - ); - } - - @RestGet( - path="/*", - summary="View information on file or directory", - description="Returns information about the specified file or directory." - ) - @HtmlDocConfig( - nav={"<h5>Folder: $RA{fullPath}</h5>"} - ) - public FileResource getFile(RestRequest req, @Path("/*") String path) throws NotFound, Exception { - - File dir = getFile(path); - req.setAttribute("fullPath", dir.getAbsolutePath()); - - return new FileResource(dir, path, allowDeletes, true); - } - - @RestOp( - method="VIEW", - path="/*", - summary="View contents of log file", - description="View the contents of a log file." - ) - public void viewFile( - RestResponse res, - @Path("/*") String path, - @Query("highlight") @Schema(d="Add severity color highlighting.") boolean highlight, - @Query("start") @Schema(d="Start timestamp (ISO8601, full or partial).\nDon't print lines logged before the specified timestamp.\nUse any of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") String start, - @Query("end") @Schema(d="End timestamp (ISO8601, full or partial).\nDon't print lines logged after the specified timestamp.\nUse any of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") String end, - @Query("thread") @Schema(d="Thread name filter.\nOnly show log entries with the specified thread name.") String thread, - @Query("loggers") @Schema(d="Logger filter (simple class name).\nOnly show log entries if they were produced by one of the specified loggers.") String[] loggers, - @Query("severity") @Schema(d="Severity filter.\nOnly show log entries with the specified severity.") String[] severity - ) throws NotFound, MethodNotAllowed, IOException { - - File f = getFile(path); - - Date startDate = parseIsoDate(start), endDate = parseIsoDate(end); - - if (! highlight) { - Object o = getReader(f, startDate, endDate, thread, loggers, severity); - res.setContentType("text/plain"); - if (o instanceof Reader) - res.setContent(o); - else { - try (LogParser p = (LogParser)o; Writer w = res.getNegotiatedWriter()) { - p.writeTo(w); - } - } - return; - } - - res.setContentType("text/html"); - try (PrintWriter w = res.getNegotiatedWriter()) { - w.println("<html><body style='font-family:monospace;font-size:8pt;white-space:pre;'>"); - try (LogParser lp = getLogParser(f, startDate, endDate, thread, loggers, severity)) { - if (! lp.hasNext()) - w.append("<span style='color:gray'>[EMPTY]</span>"); - else for (LogParser.Entry le : lp) { - char s = le.severity.charAt(0); - String color = "black"; - //SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST - if (s == 'I') - color = "#006400"; - else if (s == 'W') - color = "#CC8400"; - else if (s == 'E' || s == 'S') - color = "#DD0000"; - else if (s == 'D' || s == 'F' || s == 'T') - color = "#000064"; - w.append("<span style='color:").append(color).append("'>"); - le.appendHtml(w).append("</span>"); - } - w.append("</body></html>"); - } - } - } - - @RestOp( - method="PARSE", - path="/*", - converters=Queryable.class, - summary="View parsed contents of file", - description="View the parsed contents of a file.", - swagger=@OpSwagger( - parameters={ - Queryable.SWAGGER_PARAMS - } - ) - ) - @HtmlDocConfig( - nav={"<h5>Folder: $RA{fullPath}</h5>"} - ) - public LogParser viewParsedEntries( - RestRequest req, - @Path("/*") String path, - @Query("start") @Schema(d="Start timestamp (ISO8601, full or partial).\nDon't print lines logged before the specified timestamp.\nUse any of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") String start, - @Query("end") @Schema(d="End timestamp (ISO8601, full or partial).\nDon't print lines logged after the specified timestamp.\nUse any of the following formats: yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddThh, yyyy-MM-ddThh:mm, yyyy-MM-ddThh:mm:ss, yyyy-MM-ddThh:mm:ss.SSS") String end, - @Query("thread") @Schema(d="Thread name filter.\nOnly show log entries with the specified thread name.") String thread, - @Query("loggers") @Schema(d="Logger filter (simple class name).\nOnly show log entries if they were produced by one of the specified loggers.") String[] loggers, - @Query("severity") @Schema(d="Severity filter.\nOnly show log entries with the specified severity.") String[] severity - ) throws NotFound, IOException { - - File f = getFile(path); - req.setAttribute("fullPath", f.getAbsolutePath()); - - Date startDate = parseIsoDate(start), endDate = parseIsoDate(end); - - return getLogParser(f, startDate, endDate, thread, loggers, severity); - } - - @RestOp( - method="DOWNLOAD", - path="/*", - summary="Download file", - description="Download the contents of a file.\nContent-Type is set to 'application/octet-stream'." - ) - public FileContents downloadFile(RestResponse res, @Path("/*") String path) throws NotFound, MethodNotAllowed { - res.setContentType("application/octet-stream"); - try { - return new FileContents(getFile(path)); - } catch (FileNotFoundException e) { - throw new NotFound("File not found"); - } - } - - @RestDelete( - path="/*", - summary="Delete log file", - description="Delete a log file on the file system." - ) - public RedirectToRoot deleteFile(@Path("/*") String path) throws MethodNotAllowed { - deleteFile(getFile(path)); - return new RedirectToRoot(); - } - - - //----------------------------------------------------------------------------------------------------------------- - // Helper beans - //----------------------------------------------------------------------------------------------------------------- - - @Response @Schema(type="string",format="binary",description="Contents of file") - static class FileContents extends FileInputStream { - public FileContents(File file) throws FileNotFoundException { - super(file); - } - } - - @Response @Schema(description="Redirect to root page on success") - static class RedirectToRoot extends SeeOtherRoot {} - - @Response @Schema(description="File action") - public static class Action extends LinkString { - public Action(String name, String uri, Object...uriArgs) { - super(name, uri, uriArgs); - } - } - - @Response @Schema(description="File or directory details") - @Bean(properties="type,name,size,lastModified,actions,files") - public static class FileResource { - private final File f; - private final String path; - private final String uri; - private final boolean includeChildren, allowDeletes; - - public FileResource(File f, String path, boolean allowDeletes, boolean includeChildren) { - this.f = f; - this.path = path; - this.uri = "servlet:/"+(path == null ? "" : path); - this.includeChildren = includeChildren; - this.allowDeletes = allowDeletes; - } - - public String getType() { - return (f.isDirectory() ? "dir" : "file"); - } - - public LinkString getName() { - return new LinkString(f.getName(), uri); - } - - public long getSize() { - return f.isDirectory() ? f.listFiles().length : f.length(); - } - - public Date getLastModified() { - return new Date(f.lastModified()); - } - - @Html(format=HtmlFormat.HTML_CDC) - public List<Action> getActions() throws Exception { - List<Action> l = list(); - if (f.canRead() && ! f.isDirectory()) { - l.add(new Action("view", uri + "?method=VIEW")); - l.add(new Action("highlighted", uri + "?method=VIEW&highlight=true")); - l.add(new Action("parsed", uri + "?method=PARSE")); - l.add(new Action("download", uri + "?method=DOWNLOAD")); - if (allowDeletes) - l.add(new Action("delete", uri + "?method=DELETE")); - } - return l; - } - - public Set<FileResource> getFiles() { - if (f.isFile() || ! includeChildren) - return null; - Set<FileResource> s = new TreeSet<>(FILE_COMPARATOR); - for (File fc : f.listFiles(FILE_FILTER)) - s.add(new FileResource(fc, (path != null ? (path + '/') : "") + urlEncode(fc.getName()), allowDeletes, false)); - return s; - } - - static final FileFilter FILE_FILTER = new FileFilter() { - @Override /* FileFilter */ - public boolean accept(File f) { - return f.isDirectory() || f.getName().endsWith(".log"); - } - }; - - static final Comparator<FileResource> FILE_COMPARATOR = new Comparator<FileResource>() { - @Override /* Comparator */ - public int compare(FileResource o1, FileResource o2) { - int c = o1.getType().compareTo(o2.getType()); - return c != 0 ? c : o1.getName().compareTo(o2.getName()); - } - }; - } - - - //----------------------------------------------------------------------------------------------------------------- - // Helper methods - //----------------------------------------------------------------------------------------------------------------- - - private File getFile(String path) throws NotFound { - if (path == null) - return logDir; - File f = new File(logDir.getAbsolutePath() + '/' + path); - if (f.exists()) - return f; - throw new NotFound("File not found."); - } - - private void deleteFile(File f) { - if (! allowDeletes) - throw new MethodNotAllowed("DELETE not enabled"); - if (f.isDirectory()) { - File[] files = f.listFiles(); - if (files != null) { - for (File fc : files) - deleteFile(fc); - } - } - if (! f.delete()) - throw new Forbidden("Could not delete file {0}", f.getAbsolutePath()) ; - } - - private static BufferedReader getReader(File f) throws IOException { - return new BufferedReader(new InputStreamReader(new FileInputStream(f), Charset.defaultCharset())); - } - - private Object getReader(File f, final Date start, final Date end, final String thread, final String[] loggers, final String[] severity) throws IOException { - if (start == null && end == null && thread == null && loggers == null) - return getReader(f); - return getLogParser(f, start, end, thread, loggers, severity); - } - - private LogParser getLogParser(File f, final Date start, final Date end, final String thread, final String[] loggers, final String[] severity) throws IOException { - return new LogParser(leFormatter, f, start, end, thread, loggers, severity); - } -} diff --git a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java index 46ceccf5e..4f3a68257 100755 --- a/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java +++ b/juneau-microservice/juneau-microservice-core/src/main/java/org/apache/juneau/microservice/resources/SampleRootResource.java @@ -30,7 +30,7 @@ import org.apache.juneau.rest.servlet.*; path="/", title="Sample Root Resource", description="This is a sample router page", - children={ConfigResource.class,LogsResource.class} + children={ConfigResource.class} ) public class SampleRootResource extends BasicRestServletGroup implements BasicUniversalConfig { private static final long serialVersionUID = 1L; diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java index d382b039d..80f3efc74 100644 --- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java +++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/Root.java @@ -27,7 +27,6 @@ import org.apache.juneau.rest.test.client.*; path="/*", children={ DebugResource.class, - LogsResource.class, ConfigResource.class, LargePojosResource.class, ThirdPartyProxyResource.class, diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java index e32eac2e1..193375a41 100644 --- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java +++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyResource.java @@ -45,6 +45,7 @@ public class ThirdPartyProxyResource extends BasicRestServlet implements BasicUn public static FileWriter logFile; static { try { + new File("./target/logs").mkdirs(); logFile = new FileWriter("./target/logs/third-party-proxy-resource.txt", false); } catch (IOException e) { e.printStackTrace(); diff --git a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java index 9c1f86162..04b89d3df 100644 --- a/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java +++ b/juneau-microservice/juneau-microservice-jetty/src/main/java/org/apache/juneau/microservice/jetty/JettyMicroservice.java @@ -371,12 +371,6 @@ public class JettyMicroservice extends Microservice { return this; } - @Override /* MicroserviceBuilder */ - public Builder logConfig(LogConfig logConfig) { - super.logConfig(logConfig); - return this; - } - @Override /* MicroserviceBuilder */ public Builder config(Config config) { super.config(config); diff --git a/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java b/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java index 7d22c775b..fd74c7ae8 100755 --- a/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java +++ b/juneau-microservice/juneau-my-jetty-microservice/src/main/java/org/apache/juneau/microservice/jetty/template/RootResources.java @@ -15,7 +15,6 @@ package org.apache.juneau.microservice.jetty.template; import org.apache.juneau.html.annotation.HtmlDocConfig; import org.apache.juneau.microservice.jetty.resources.DebugResource; import org.apache.juneau.microservice.resources.ConfigResource; -import org.apache.juneau.microservice.resources.LogsResource; import org.apache.juneau.rest.annotation.*; import org.apache.juneau.rest.servlet.BasicRestServletGroup; import org.apache.juneau.rest.widget.ContentTypeMenuItem; @@ -38,7 +37,6 @@ import org.apache.juneau.rest.widget.ThemeMenuItem; children={ HelloWorldResource.class, ConfigResource.class, - LogsResource.class, DebugResource.class } ) diff --git a/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java b/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java index 051ab0b4c..6122e8ba2 100644 --- a/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java +++ b/juneau-microservice/juneau-my-springboot-microservice/src/main/java/org/apache/juneau/microservice/springboot/template/RootResources.java @@ -36,8 +36,7 @@ import org.apache.juneau.serializer.annotation.*; description="Example of a router resource page.", children={ HelloWorldResource.class, - ConfigResource.class, - LogsResource.class + ConfigResource.class } ) @HtmlDocConfig( diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java index 79012cf3a..53d594b7b 100644 --- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java +++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java @@ -4202,12 +4202,12 @@ public class RestContext extends Context { RestContext cc = cb.init(so).build(); - MethodInfo mi = ClassInfo.of(o).getPublicMethod( + MethodInfo mi = ClassInfo.of(so.get()).getMethod( x -> x.hasName("setContext") && x.hasParamTypes(RestContext.class) ); if (mi != null) - mi.accessible().invoke(o, cc); + mi.accessible().invoke(so.get(), cc); v.get().add(cc); } diff --git a/pom.xml b/pom.xml index ef445293d..d35bd162f 100644 --- a/pom.xml +++ b/pom.xml @@ -187,6 +187,7 @@ <!-- Generated by embedded jetty server --> <exclude>**/jetty.out.xml</exclude> <exclude>**/*.log</exclude> + <exclude>**/*.log.*</exclude> <!-- Generated in juneau-microservice-template for some reason --> <exclude>**/dependency-reduced-pom.xml</exclude>