Merge branch 'eugenp:master' into master
This commit is contained in:
commit
ec403bd427
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>apache-tomcat</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<name>apache-tomcat</name>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-modules</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<module>sso</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<defaultGoal>install</defaultGoal>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
</build>
|
||||||
|
</project>
|
|
@ -0,0 +1,24 @@
|
||||||
|
**/.classpath
|
||||||
|
**/.dockerignore
|
||||||
|
**/.env
|
||||||
|
**/.git
|
||||||
|
**/.gitignore
|
||||||
|
**/.project
|
||||||
|
**/.settings
|
||||||
|
**/.toolstarget
|
||||||
|
**/.vs
|
||||||
|
**/.vscode
|
||||||
|
**/*.*proj.user
|
||||||
|
**/*.dbmdl
|
||||||
|
**/*.jfm
|
||||||
|
**/bin
|
||||||
|
**/charts
|
||||||
|
**/docker-compose*
|
||||||
|
**/compose*
|
||||||
|
**/Dockerfile*
|
||||||
|
**/node_modules
|
||||||
|
**/npm-debug.log
|
||||||
|
**/obj
|
||||||
|
**/secrets.dev.yaml
|
||||||
|
**/values.dev.yaml
|
||||||
|
README.md
|
|
@ -0,0 +1,5 @@
|
||||||
|
### Related articles
|
||||||
|
|
||||||
|
### Launch Example using Docker
|
||||||
|
|
||||||
|
$ docker-compose up
|
|
@ -0,0 +1,11 @@
|
||||||
|
version: '3.4'
|
||||||
|
|
||||||
|
services:
|
||||||
|
tomcatsso:
|
||||||
|
image: tomcat:10-jdk17-openjdk-slim-buster
|
||||||
|
volumes:
|
||||||
|
- ./res/conf:/usr/local/tomcat/conf
|
||||||
|
- ./webapps:/usr/local/tomcat/webapps
|
||||||
|
ports:
|
||||||
|
- 8080:8080
|
||||||
|
command: ["catalina.sh", "run"]
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.baeldung.apache_tomcat</groupId>
|
||||||
|
<artifactId>sso</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>apache-tomcat</artifactId>
|
||||||
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,264 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
// catalina.policy - Security Policy Permissions for Tomcat
|
||||||
|
//
|
||||||
|
// This file contains a default set of security policies to be enforced (by the
|
||||||
|
// JVM) when Catalina is executed with the "-security" option. In addition
|
||||||
|
// to the permissions granted here, the following additional permissions are
|
||||||
|
// granted to each web application:
|
||||||
|
//
|
||||||
|
// * Read access to the web application's document root directory
|
||||||
|
// * Read, write and delete access to the web application's working directory
|
||||||
|
// ============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
// ========== SYSTEM CODE PERMISSIONS =========================================
|
||||||
|
|
||||||
|
|
||||||
|
// These permissions apply to javac
|
||||||
|
grant codeBase "file:${java.home}/lib/-" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These permissions apply to all shared system extensions
|
||||||
|
grant codeBase "file:${java.home}/jre/lib/ext/-" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These permissions apply to javac when ${java.home} points at $JAVA_HOME/jre
|
||||||
|
grant codeBase "file:${java.home}/../lib/-" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These permissions apply to all shared system extensions when
|
||||||
|
// ${java.home} points at $JAVA_HOME/jre
|
||||||
|
grant codeBase "file:${java.home}/lib/ext/-" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
// This permission is required when using javac to compile JSPs on Java 9
|
||||||
|
// onwards
|
||||||
|
//grant codeBase "jrt:/jdk.compiler" {
|
||||||
|
// permission java.security.AllPermission;
|
||||||
|
//};
|
||||||
|
|
||||||
|
|
||||||
|
// ========== CATALINA CODE PERMISSIONS =======================================
|
||||||
|
|
||||||
|
// These permissions apply to the daemon code
|
||||||
|
grant codeBase "file:${catalina.home}/bin/commons-daemon.jar" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These permissions apply to the logging API
|
||||||
|
// Note: If tomcat-juli.jar is in ${catalina.base} and not in ${catalina.home},
|
||||||
|
// update this section accordingly.
|
||||||
|
// grant codeBase "file:${catalina.base}/bin/tomcat-juli.jar" {..}
|
||||||
|
grant codeBase "file:${catalina.home}/bin/tomcat-juli.jar" {
|
||||||
|
permission java.io.FilePermission
|
||||||
|
"${java.home}${file.separator}lib${file.separator}logging.properties", "read";
|
||||||
|
|
||||||
|
permission java.io.FilePermission
|
||||||
|
"${catalina.base}${file.separator}conf${file.separator}logging.properties", "read";
|
||||||
|
permission java.io.FilePermission
|
||||||
|
"${catalina.base}${file.separator}logs", "read, write";
|
||||||
|
permission java.io.FilePermission
|
||||||
|
"${catalina.base}${file.separator}logs${file.separator}*", "read, write, delete";
|
||||||
|
|
||||||
|
permission java.lang.RuntimePermission "shutdownHooks";
|
||||||
|
permission java.lang.RuntimePermission "getClassLoader";
|
||||||
|
permission java.lang.RuntimePermission "setContextClassLoader";
|
||||||
|
|
||||||
|
permission java.lang.management.ManagementPermission "monitor";
|
||||||
|
|
||||||
|
permission java.util.logging.LoggingPermission "control";
|
||||||
|
|
||||||
|
permission java.util.PropertyPermission "java.util.logging.config.class", "read";
|
||||||
|
permission java.util.PropertyPermission "java.util.logging.config.file", "read";
|
||||||
|
permission java.util.PropertyPermission "org.apache.juli.AsyncMaxRecordCount", "read";
|
||||||
|
permission java.util.PropertyPermission "org.apache.juli.AsyncOverflowDropType", "read";
|
||||||
|
permission java.util.PropertyPermission "org.apache.juli.ClassLoaderLogManager.debug", "read";
|
||||||
|
permission java.util.PropertyPermission "catalina.base", "read";
|
||||||
|
|
||||||
|
// Note: To enable per context logging configuration, permit read access to
|
||||||
|
// the appropriate file. Be sure that the logging configuration is
|
||||||
|
// secure before enabling such access.
|
||||||
|
// E.g. for the examples web application (uncomment and unwrap
|
||||||
|
// the following to be on a single line):
|
||||||
|
// permission java.io.FilePermission "${catalina.base}${file.separator}
|
||||||
|
// webapps${file.separator}examples${file.separator}WEB-INF
|
||||||
|
// ${file.separator}classes${file.separator}logging.properties", "read";
|
||||||
|
};
|
||||||
|
|
||||||
|
// These permissions apply to the server startup code
|
||||||
|
grant codeBase "file:${catalina.home}/bin/bootstrap.jar" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
// These permissions apply to the servlet API classes
|
||||||
|
// and those that are shared across all class loaders
|
||||||
|
// located in the "lib" directory
|
||||||
|
grant codeBase "file:${catalina.home}/lib/-" {
|
||||||
|
permission java.security.AllPermission;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// If using a per instance lib directory, i.e. ${catalina.base}/lib,
|
||||||
|
// then the following permission will need to be uncommented
|
||||||
|
// grant codeBase "file:${catalina.base}/lib/-" {
|
||||||
|
// permission java.security.AllPermission;
|
||||||
|
// };
|
||||||
|
|
||||||
|
|
||||||
|
// ========== WEB APPLICATION PERMISSIONS =====================================
|
||||||
|
|
||||||
|
|
||||||
|
// These permissions are granted by default to all web applications
|
||||||
|
// In addition, a web application will be given a read FilePermission
|
||||||
|
// for all files and directories in its document root.
|
||||||
|
grant {
|
||||||
|
// Required for JNDI lookup of named JDBC DataSource's and
|
||||||
|
// javamail named MimePart DataSource used to send mail
|
||||||
|
permission java.util.PropertyPermission "java.home", "read";
|
||||||
|
permission java.util.PropertyPermission "java.naming.*", "read";
|
||||||
|
permission java.util.PropertyPermission "javax.sql.*", "read";
|
||||||
|
|
||||||
|
// OS Specific properties to allow read access
|
||||||
|
permission java.util.PropertyPermission "os.name", "read";
|
||||||
|
permission java.util.PropertyPermission "os.version", "read";
|
||||||
|
permission java.util.PropertyPermission "os.arch", "read";
|
||||||
|
permission java.util.PropertyPermission "file.separator", "read";
|
||||||
|
permission java.util.PropertyPermission "path.separator", "read";
|
||||||
|
permission java.util.PropertyPermission "line.separator", "read";
|
||||||
|
|
||||||
|
// JVM properties to allow read access
|
||||||
|
permission java.util.PropertyPermission "java.version", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vendor", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vendor.url", "read";
|
||||||
|
permission java.util.PropertyPermission "java.class.version", "read";
|
||||||
|
permission java.util.PropertyPermission "java.specification.version", "read";
|
||||||
|
permission java.util.PropertyPermission "java.specification.vendor", "read";
|
||||||
|
permission java.util.PropertyPermission "java.specification.name", "read";
|
||||||
|
|
||||||
|
permission java.util.PropertyPermission "java.vm.specification.version", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vm.specification.vendor", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vm.specification.name", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vm.version", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vm.vendor", "read";
|
||||||
|
permission java.util.PropertyPermission "java.vm.name", "read";
|
||||||
|
|
||||||
|
// Required for OpenJMX
|
||||||
|
permission java.lang.RuntimePermission "getAttribute";
|
||||||
|
|
||||||
|
// Allow read of JAXP compliant XML parser debug
|
||||||
|
permission java.util.PropertyPermission "jaxp.debug", "read";
|
||||||
|
|
||||||
|
// All JSPs need to be able to read this package
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat";
|
||||||
|
|
||||||
|
// Precompiled JSPs need access to these packages.
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.el";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.jasper.runtime";
|
||||||
|
permission java.lang.RuntimePermission
|
||||||
|
"accessClassInPackage.org.apache.jasper.runtime.*";
|
||||||
|
|
||||||
|
// Applications using WebSocket need to be able to access these packages
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.websocket.server";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// The Manager application needs access to the following packages to support the
|
||||||
|
// session display functionality. It also requires the custom Tomcat
|
||||||
|
// DeployXmlPermission to enable the use of META-INF/context.xml
|
||||||
|
// These settings support the following configurations:
|
||||||
|
// - default CATALINA_HOME == CATALINA_BASE
|
||||||
|
// - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE
|
||||||
|
// - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME
|
||||||
|
grant codeBase "file:${catalina.base}/webapps/manager/-" {
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util";
|
||||||
|
permission org.apache.catalina.security.DeployXmlPermission "manager";
|
||||||
|
};
|
||||||
|
grant codeBase "file:${catalina.home}/webapps/manager/-" {
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.ha.session";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.manager.util";
|
||||||
|
permission java.lang.RuntimePermission "accessClassInPackage.org.apache.catalina.util";
|
||||||
|
permission org.apache.catalina.security.DeployXmlPermission "manager";
|
||||||
|
};
|
||||||
|
|
||||||
|
// The Host Manager application needs the custom Tomcat DeployXmlPermission to
|
||||||
|
// enable the use of META-INF/context.xml
|
||||||
|
// These settings support the following configurations:
|
||||||
|
// - default CATALINA_HOME == CATALINA_BASE
|
||||||
|
// - CATALINA_HOME != CATALINA_BASE, per instance Host Manager in CATALINA_BASE
|
||||||
|
// - CATALINA_HOME != CATALINA_BASE, shared Host Manager in CATALINA_HOME
|
||||||
|
grant codeBase "file:${catalina.base}/webapps/host-manager/-" {
|
||||||
|
permission org.apache.catalina.security.DeployXmlPermission "host-manager";
|
||||||
|
};
|
||||||
|
grant codeBase "file:${catalina.home}/webapps/host-manager/-" {
|
||||||
|
permission org.apache.catalina.security.DeployXmlPermission "host-manager";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// You can assign additional permissions to particular web applications by
|
||||||
|
// adding additional "grant" entries here, based on the code base for that
|
||||||
|
// application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.
|
||||||
|
//
|
||||||
|
// Different permissions can be granted to JSP pages, classes loaded from
|
||||||
|
// the /WEB-INF/classes/ directory, all jar files in the /WEB-INF/lib/
|
||||||
|
// directory, or even to individual jar files in the /WEB-INF/lib/ directory.
|
||||||
|
//
|
||||||
|
// For instance, assume that the standard "examples" application
|
||||||
|
// included a JDBC driver that needed to establish a network connection to the
|
||||||
|
// corresponding database and used the scrape taglib to get the weather from
|
||||||
|
// the NOAA web server. You might create a "grant" entries like this:
|
||||||
|
//
|
||||||
|
// The permissions granted to the context root directory apply to JSP pages.
|
||||||
|
// grant codeBase "file:${catalina.base}/webapps/examples/-" {
|
||||||
|
// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
|
||||||
|
// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// The permissions granted to the context WEB-INF/classes directory
|
||||||
|
// grant codeBase "file:${catalina.base}/webapps/examples/WEB-INF/classes/-" {
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// The permission granted to your JDBC driver
|
||||||
|
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/driver.jar!/-" {
|
||||||
|
// permission java.net.SocketPermission "dbhost.mycompany.com:5432", "connect";
|
||||||
|
// };
|
||||||
|
// The permission granted to the scrape taglib
|
||||||
|
// grant codeBase "jar:file:${catalina.base}/webapps/examples/WEB-INF/lib/scrape.jar!/-" {
|
||||||
|
// permission java.net.SocketPermission "*.noaa.gov:80", "connect";
|
||||||
|
// };
|
||||||
|
|
||||||
|
// To grant permissions for web applications using packed WAR files, use the
|
||||||
|
// Tomcat specific WAR url scheme.
|
||||||
|
//
|
||||||
|
// The permissions granted to the entire web application
|
||||||
|
// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/-" {
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// The permissions granted to a specific JAR
|
||||||
|
// grant codeBase "war:file:${catalina.base}/webapps/examples.war*/WEB-INF/lib/foo.jar" {
|
||||||
|
// };
|
|
@ -0,0 +1,208 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
#
|
||||||
|
# List of comma-separated packages that start with or equal this string
|
||||||
|
# will cause a security exception to be thrown when
|
||||||
|
# passed to checkPackageAccess unless the
|
||||||
|
# corresponding RuntimePermission ("accessClassInPackage."+package) has
|
||||||
|
# been granted.
|
||||||
|
package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat.
|
||||||
|
#
|
||||||
|
# List of comma-separated packages that start with or equal this string
|
||||||
|
# will cause a security exception to be thrown when
|
||||||
|
# passed to checkPackageDefinition unless the
|
||||||
|
# corresponding RuntimePermission ("defineClassInPackage."+package) has
|
||||||
|
# been granted.
|
||||||
|
#
|
||||||
|
# by default, no packages are restricted for definition, and none of
|
||||||
|
# the class loaders supplied with the JDK call checkPackageDefinition.
|
||||||
|
#
|
||||||
|
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,\
|
||||||
|
org.apache.jasper.,org.apache.naming.,org.apache.tomcat.
|
||||||
|
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# List of comma-separated paths defining the contents of the "common"
|
||||||
|
# classloader. Prefixes should be used to define what is the repository type.
|
||||||
|
# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
|
||||||
|
# If left as blank,the JVM system loader will be used as Catalina's "common"
|
||||||
|
# loader.
|
||||||
|
# Examples:
|
||||||
|
# "foo": Add this folder as a class repository
|
||||||
|
# "foo/*.jar": Add all the JARs of the specified folder as class
|
||||||
|
# repositories
|
||||||
|
# "foo/bar.jar": Add bar.jar as a class repository
|
||||||
|
#
|
||||||
|
# Note: Values are enclosed in double quotes ("...") in case either the
|
||||||
|
# ${catalina.base} path or the ${catalina.home} path contains a comma.
|
||||||
|
# Because double quotes are used for quoting, the double quote character
|
||||||
|
# may not appear in a path.
|
||||||
|
common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
|
||||||
|
|
||||||
|
#
|
||||||
|
# List of comma-separated paths defining the contents of the "server"
|
||||||
|
# classloader. Prefixes should be used to define what is the repository type.
|
||||||
|
# Path may be relative to the CATALINA_HOME or CATALINA_BASE path or absolute.
|
||||||
|
# If left as blank, the "common" loader will be used as Catalina's "server"
|
||||||
|
# loader.
|
||||||
|
# Examples:
|
||||||
|
# "foo": Add this folder as a class repository
|
||||||
|
# "foo/*.jar": Add all the JARs of the specified folder as class
|
||||||
|
# repositories
|
||||||
|
# "foo/bar.jar": Add bar.jar as a class repository
|
||||||
|
#
|
||||||
|
# Note: Values may be enclosed in double quotes ("...") in case either the
|
||||||
|
# ${catalina.base} path or the ${catalina.home} path contains a comma.
|
||||||
|
# Because double quotes are used for quoting, the double quote character
|
||||||
|
# may not appear in a path.
|
||||||
|
server.loader=
|
||||||
|
|
||||||
|
#
|
||||||
|
# List of comma-separated paths defining the contents of the "shared"
|
||||||
|
# classloader. Prefixes should be used to define what is the repository type.
|
||||||
|
# Path may be relative to the CATALINA_BASE path or absolute. If left as blank,
|
||||||
|
# the "common" loader will be used as Catalina's "shared" loader.
|
||||||
|
# Examples:
|
||||||
|
# "foo": Add this folder as a class repository
|
||||||
|
# "foo/*.jar": Add all the JARs of the specified folder as class
|
||||||
|
# repositories
|
||||||
|
# "foo/bar.jar": Add bar.jar as a class repository
|
||||||
|
# Please note that for single jars, e.g. bar.jar, you need the URL form
|
||||||
|
# starting with file:.
|
||||||
|
#
|
||||||
|
# Note: Values may be enclosed in double quotes ("...") in case either the
|
||||||
|
# ${catalina.base} path or the ${catalina.home} path contains a comma.
|
||||||
|
# Because double quotes are used for quoting, the double quote character
|
||||||
|
# may not appear in a path.
|
||||||
|
shared.loader=
|
||||||
|
|
||||||
|
# Default list of JAR files that should not be scanned using the JarScanner
|
||||||
|
# functionality. This is typically used to scan JARs for configuration
|
||||||
|
# information. JARs that do not contain such information may be excluded from
|
||||||
|
# the scan to speed up the scanning process. This is the default list. JARs on
|
||||||
|
# this list are excluded from all scans. The list must be a comma separated list
|
||||||
|
# of JAR file names.
|
||||||
|
# The list of JARs to skip may be over-ridden at a Context level for individual
|
||||||
|
# scan types by configuring a JarScanner with a nested JarScanFilter.
|
||||||
|
# The JARs listed below include:
|
||||||
|
# - Tomcat Bootstrap JARs
|
||||||
|
# - Tomcat API JARs
|
||||||
|
# - Catalina JARs
|
||||||
|
# - Jasper JARs
|
||||||
|
# - Tomcat JARs
|
||||||
|
# - Common non-Tomcat JARs
|
||||||
|
# - Test JARs (JUnit, Cobertura and dependencies)
|
||||||
|
tomcat.util.scan.StandardJarScanFilter.jarsToSkip=\
|
||||||
|
annotations-api.jar,\
|
||||||
|
ant-junit*.jar,\
|
||||||
|
ant-launcher.jar,\
|
||||||
|
ant.jar,\
|
||||||
|
asm-*.jar,\
|
||||||
|
aspectj*.jar,\
|
||||||
|
bootstrap.jar,\
|
||||||
|
catalina-ant.jar,\
|
||||||
|
catalina-ha.jar,\
|
||||||
|
catalina-ssi.jar,\
|
||||||
|
catalina-storeconfig.jar,\
|
||||||
|
catalina-tribes.jar,\
|
||||||
|
catalina.jar,\
|
||||||
|
cglib-*.jar,\
|
||||||
|
cobertura-*.jar,\
|
||||||
|
commons-beanutils*.jar,\
|
||||||
|
commons-codec*.jar,\
|
||||||
|
commons-collections*.jar,\
|
||||||
|
commons-daemon.jar,\
|
||||||
|
commons-dbcp*.jar,\
|
||||||
|
commons-digester*.jar,\
|
||||||
|
commons-fileupload*.jar,\
|
||||||
|
commons-httpclient*.jar,\
|
||||||
|
commons-io*.jar,\
|
||||||
|
commons-lang*.jar,\
|
||||||
|
commons-logging*.jar,\
|
||||||
|
commons-math*.jar,\
|
||||||
|
commons-pool*.jar,\
|
||||||
|
derby-*.jar,\
|
||||||
|
dom4j-*.jar,\
|
||||||
|
easymock-*.jar,\
|
||||||
|
ecj-*.jar,\
|
||||||
|
el-api.jar,\
|
||||||
|
geronimo-spec-jaxrpc*.jar,\
|
||||||
|
h2*.jar,\
|
||||||
|
hamcrest-*.jar,\
|
||||||
|
hibernate*.jar,\
|
||||||
|
httpclient*.jar,\
|
||||||
|
icu4j-*.jar,\
|
||||||
|
jakartaee-migration-*.jar,\
|
||||||
|
jasper-el.jar,\
|
||||||
|
jasper.jar,\
|
||||||
|
jaspic-api.jar,\
|
||||||
|
jaxb-*.jar,\
|
||||||
|
jaxen-*.jar,\
|
||||||
|
jdom-*.jar,\
|
||||||
|
jetty-*.jar,\
|
||||||
|
jmx-tools.jar,\
|
||||||
|
jmx.jar,\
|
||||||
|
jsp-api.jar,\
|
||||||
|
jstl.jar,\
|
||||||
|
jta*.jar,\
|
||||||
|
junit-*.jar,\
|
||||||
|
junit.jar,\
|
||||||
|
log4j*.jar,\
|
||||||
|
mail*.jar,\
|
||||||
|
objenesis-*.jar,\
|
||||||
|
oraclepki.jar,\
|
||||||
|
oro-*.jar,\
|
||||||
|
servlet-api-*.jar,\
|
||||||
|
servlet-api.jar,\
|
||||||
|
slf4j*.jar,\
|
||||||
|
taglibs-standard-spec-*.jar,\
|
||||||
|
tagsoup-*.jar,\
|
||||||
|
tomcat-api.jar,\
|
||||||
|
tomcat-coyote.jar,\
|
||||||
|
tomcat-dbcp.jar,\
|
||||||
|
tomcat-i18n-*.jar,\
|
||||||
|
tomcat-jdbc.jar,\
|
||||||
|
tomcat-jni.jar,\
|
||||||
|
tomcat-juli-adapters.jar,\
|
||||||
|
tomcat-juli.jar,\
|
||||||
|
tomcat-util-scan.jar,\
|
||||||
|
tomcat-util.jar,\
|
||||||
|
tomcat-websocket.jar,\
|
||||||
|
tools.jar,\
|
||||||
|
websocket-api.jar,\
|
||||||
|
wsdl4j*.jar,\
|
||||||
|
xercesImpl.jar,\
|
||||||
|
xml-apis.jar,\
|
||||||
|
xmlParserAPIs-*.jar,\
|
||||||
|
xmlParserAPIs.jar,\
|
||||||
|
xom-*.jar
|
||||||
|
|
||||||
|
# Default list of JAR files that should be scanned that overrides the default
|
||||||
|
# jarsToSkip list above. This is typically used to include a specific JAR that
|
||||||
|
# has been excluded by a broad file name pattern in the jarsToSkip list.
|
||||||
|
# The list of JARs to scan may be over-ridden at a Context level for individual
|
||||||
|
# scan types by configuring a JarScanner with a nested JarScanFilter.
|
||||||
|
tomcat.util.scan.StandardJarScanFilter.jarsToScan=\
|
||||||
|
log4j-taglib*.jar,\
|
||||||
|
log4j-web*.jar,\
|
||||||
|
log4javascript*.jar,\
|
||||||
|
slf4j-taglib*.jar
|
||||||
|
|
||||||
|
# String cache configuration.
|
||||||
|
tomcat.util.buf.StringCache.byte.enabled=true
|
||||||
|
#tomcat.util.buf.StringCache.char.enabled=true
|
||||||
|
#tomcat.util.buf.StringCache.trainThreshold=500000
|
||||||
|
#tomcat.util.buf.StringCache.cacheSize=5000
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<!-- The contents of this file will be loaded for each web application -->
|
||||||
|
<Context>
|
||||||
|
|
||||||
|
<!-- Default set of monitored resources. If one of these changes, the -->
|
||||||
|
<!-- web application will be reloaded. -->
|
||||||
|
<WatchedResource>WEB-INF/web.xml</WatchedResource>
|
||||||
|
<WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
|
||||||
|
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
|
||||||
|
|
||||||
|
<!-- Uncomment this to enable session persistence across Tomcat restarts -->
|
||||||
|
<!--
|
||||||
|
<Manager pathname="SESSIONS.ser" />
|
||||||
|
-->
|
||||||
|
</Context>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<jaspic-providers xmlns="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://tomcat.apache.org/xml jaspic-providers.xsd"
|
||||||
|
version="1.0">
|
||||||
|
<!-- No JASPIC providers configured by default -->
|
||||||
|
</jaspic-providers>
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||||
|
targetNamespace="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:jaspic="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
elementFormDefault="qualified"
|
||||||
|
attributeFormDefault="unqualified"
|
||||||
|
version="1.0">
|
||||||
|
<xs:element name="jaspic-providers">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="provider" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="property" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="name" use="required" type="jaspic:propertyname" />
|
||||||
|
<xs:attribute name="value" use="required" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="className" type="xs:string" />
|
||||||
|
<xs:attribute name="layer" type="xs:string" />
|
||||||
|
<xs:attribute name="appContext" type="xs:string" />
|
||||||
|
<xs:attribute name="description" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
<xs:attribute name="version" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:simpleType name="propertyname">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:minLength value="1"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
</xs:schema>
|
|
@ -0,0 +1,90 @@
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
handlers = 1catalina.org.apache.juli.AsyncFileHandler, 2localhost.org.apache.juli.AsyncFileHandler, 3manager.org.apache.juli.AsyncFileHandler, 4host-manager.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
|
||||||
|
|
||||||
|
.handlers = 1catalina.org.apache.juli.AsyncFileHandler, java.util.logging.ConsoleHandler
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# Handler specific properties.
|
||||||
|
# Describes specific configuration info for Handlers.
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
1catalina.org.apache.juli.AsyncFileHandler.level = ALL
|
||||||
|
1catalina.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
||||||
|
1catalina.org.apache.juli.AsyncFileHandler.prefix = catalina.
|
||||||
|
1catalina.org.apache.juli.AsyncFileHandler.maxDays = 90
|
||||||
|
1catalina.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
||||||
|
|
||||||
|
2localhost.org.apache.juli.AsyncFileHandler.level = FINE
|
||||||
|
2localhost.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
||||||
|
2localhost.org.apache.juli.AsyncFileHandler.prefix = localhost.
|
||||||
|
2localhost.org.apache.juli.AsyncFileHandler.maxDays = 90
|
||||||
|
2localhost.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
||||||
|
|
||||||
|
3manager.org.apache.juli.AsyncFileHandler.level = FINE
|
||||||
|
3manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
||||||
|
3manager.org.apache.juli.AsyncFileHandler.prefix = manager.
|
||||||
|
3manager.org.apache.juli.AsyncFileHandler.maxDays = 90
|
||||||
|
3manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
||||||
|
|
||||||
|
4host-manager.org.apache.juli.AsyncFileHandler.level = FINE
|
||||||
|
4host-manager.org.apache.juli.AsyncFileHandler.directory = ${catalina.base}/logs
|
||||||
|
4host-manager.org.apache.juli.AsyncFileHandler.prefix = host-manager.
|
||||||
|
4host-manager.org.apache.juli.AsyncFileHandler.maxDays = 90
|
||||||
|
4host-manager.org.apache.juli.AsyncFileHandler.encoding = UTF-8
|
||||||
|
|
||||||
|
java.util.logging.ConsoleHandler.level = FINE
|
||||||
|
java.util.logging.ConsoleHandler.formatter = org.apache.juli.OneLineFormatter
|
||||||
|
java.util.logging.ConsoleHandler.encoding = UTF-8
|
||||||
|
|
||||||
|
org.apache.catalina.authenticator.level = FINE
|
||||||
|
org.apache.catalina.authenticator.formatter = org.apache.juli.OneLineFormatter
|
||||||
|
org.apache.catalina.authenticator.encoding = UTF-8
|
||||||
|
|
||||||
|
org.apache.catalina.Realm.level = FINE
|
||||||
|
org.apache.catalina.Realm.formatter = org.apache.juli.OneLineFormatter
|
||||||
|
org.apache.catalina.Realm.encoding = UTF-8
|
||||||
|
|
||||||
|
org.apache.catalina.realm.level = FINE
|
||||||
|
org.apache.catalina.realm.formatter = org.apache.juli.OneLineFormatter
|
||||||
|
org.apache.catalina.realm.encoding = UTF-8
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# Facility specific properties.
|
||||||
|
# Provides extra control for each logger.
|
||||||
|
############################################################
|
||||||
|
|
||||||
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].level = ALL
|
||||||
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].handlers = 2localhost.org.apache.juli.AsyncFileHandler
|
||||||
|
|
||||||
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].level = INFO
|
||||||
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/manager].handlers = 3manager.org.apache.juli.AsyncFileHandler
|
||||||
|
|
||||||
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].level = INFO
|
||||||
|
org.apache.catalina.core.ContainerBase.[Catalina].[localhost].[/host-manager].handlers = 4host-manager.org.apache.juli.AsyncFileHandler
|
||||||
|
|
||||||
|
# For example, set the org.apache.catalina.util.LifecycleBase logger to log
|
||||||
|
# each component that extends LifecycleBase changing state:
|
||||||
|
# org.apache.catalina.util.LifecycleBase.level = FINE
|
||||||
|
|
||||||
|
# To see debug messages in TldLocationsCache, uncomment the following line:
|
||||||
|
#org.apache.jasper.compiler.TldLocationsCache.level = FINE
|
||||||
|
|
||||||
|
# To see debug messages for HTTP/2 handling, uncomment the following line:
|
||||||
|
#org.apache.coyote.http2.level = FINE
|
||||||
|
|
||||||
|
# To see debug messages for WebSocket handling, uncomment the following line:
|
||||||
|
#org.apache.tomcat.websocket.level = FINE
|
|
@ -0,0 +1,151 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<!-- Note: A "Server" is not itself a "Container", so you may not
|
||||||
|
define subcomponents such as "Valves" at this level.
|
||||||
|
Documentation at /docs/config/server.html
|
||||||
|
-->
|
||||||
|
<Server port="8005" shutdown="SHUTDOWN">
|
||||||
|
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
|
||||||
|
<!-- Security listener. Documentation at /docs/config/listeners.html
|
||||||
|
<Listener className="org.apache.catalina.security.SecurityListener" />
|
||||||
|
-->
|
||||||
|
<!-- APR library loader. Documentation at /docs/apr.html -->
|
||||||
|
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
|
||||||
|
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
|
||||||
|
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
|
||||||
|
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
|
||||||
|
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
|
||||||
|
|
||||||
|
<!-- Global JNDI resources
|
||||||
|
Documentation at /docs/jndi-resources-howto.html
|
||||||
|
-->
|
||||||
|
<GlobalNamingResources>
|
||||||
|
<!-- Editable user database that can also be used by
|
||||||
|
UserDatabaseRealm to authenticate users
|
||||||
|
-->
|
||||||
|
<Resource name="UserDatabase" auth="Container"
|
||||||
|
type="org.apache.catalina.UserDatabase"
|
||||||
|
description="User database that can be updated and saved"
|
||||||
|
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
|
||||||
|
pathname="conf/tomcat-users.xml" />
|
||||||
|
</GlobalNamingResources>
|
||||||
|
|
||||||
|
<!-- A "Service" is a collection of one or more "Connectors" that share
|
||||||
|
a single "Container" Note: A "Service" is not itself a "Container",
|
||||||
|
so you may not define subcomponents such as "Valves" at this level.
|
||||||
|
Documentation at /docs/config/service.html
|
||||||
|
-->
|
||||||
|
<Service name="Catalina">
|
||||||
|
|
||||||
|
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
|
||||||
|
<!--
|
||||||
|
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
|
||||||
|
maxThreads="150" minSpareThreads="4"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- A "Connector" represents an endpoint by which requests are received
|
||||||
|
and responses are returned. Documentation at :
|
||||||
|
HTTP Connector: /docs/config/http.html
|
||||||
|
AJP Connector: /docs/config/ajp.html
|
||||||
|
Define a non-SSL/TLS HTTP/1.1 Connector on port 8080
|
||||||
|
-->
|
||||||
|
<Connector port="8080" protocol="HTTP/1.1"
|
||||||
|
connectionTimeout="20000"
|
||||||
|
redirectPort="8443" />
|
||||||
|
<!-- A "Connector" using the shared thread pool-->
|
||||||
|
<!--
|
||||||
|
<Connector executor="tomcatThreadPool"
|
||||||
|
port="8080" protocol="HTTP/1.1"
|
||||||
|
connectionTimeout="20000"
|
||||||
|
redirectPort="8443" />
|
||||||
|
-->
|
||||||
|
<!-- Define an SSL/TLS HTTP/1.1 Connector on port 8443 with HTTP/2
|
||||||
|
This connector uses the NIO implementation. The default
|
||||||
|
SSLImplementation will depend on the presence of the APR/native
|
||||||
|
library and the useOpenSSL attribute of the AprLifecycleListener.
|
||||||
|
Either JSSE or OpenSSL style configuration may be used regardless of
|
||||||
|
the SSLImplementation selected. JSSE style configuration is used below.
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
|
||||||
|
maxThreads="150" SSLEnabled="true">
|
||||||
|
<UpgradeProtocol className="org.apache.coyote.http2.Http2Protocol" />
|
||||||
|
<SSLHostConfig>
|
||||||
|
<Certificate certificateKeystoreFile="conf/localhost-rsa.jks"
|
||||||
|
type="RSA" />
|
||||||
|
</SSLHostConfig>
|
||||||
|
</Connector>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Define an AJP 1.3 Connector on port 8009 -->
|
||||||
|
<!--
|
||||||
|
<Connector protocol="AJP/1.3"
|
||||||
|
address="::1"
|
||||||
|
port="8009"
|
||||||
|
redirectPort="8443" />
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- An Engine represents the entry point (within Catalina) that processes
|
||||||
|
every request. The Engine implementation for Tomcat stand alone
|
||||||
|
analyzes the HTTP headers included with the request, and passes them
|
||||||
|
on to the appropriate Host (virtual host).
|
||||||
|
Documentation at /docs/config/engine.html -->
|
||||||
|
|
||||||
|
<!-- You should set jvmRoute to support load-balancing via AJP ie :
|
||||||
|
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
|
||||||
|
-->
|
||||||
|
<Engine name="Catalina" defaultHost="localhost">
|
||||||
|
|
||||||
|
<!--For clustering, please take a look at documentation at:
|
||||||
|
/docs/cluster-howto.html (simple how to)
|
||||||
|
/docs/config/cluster.html (reference documentation) -->
|
||||||
|
<!--
|
||||||
|
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
|
||||||
|
via a brute-force attack -->
|
||||||
|
<Realm className="org.apache.catalina.realm.LockOutRealm">
|
||||||
|
<!-- This Realm uses the UserDatabase configured in the global JNDI
|
||||||
|
resources under the key "UserDatabase". Any edits
|
||||||
|
that are performed against this UserDatabase are immediately
|
||||||
|
available for use by the Realm. -->
|
||||||
|
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
|
||||||
|
resourceName="UserDatabase"/>
|
||||||
|
</Realm>
|
||||||
|
|
||||||
|
<Host name="localhost" appBase="webapps"
|
||||||
|
unpackWARs="true" autoDeploy="true">
|
||||||
|
|
||||||
|
<!-- SingleSignOn valve, share authentication between web applications
|
||||||
|
Documentation at: /docs/config/valve.html -->
|
||||||
|
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Access log processes all example.
|
||||||
|
Documentation at: /docs/config/valve.html
|
||||||
|
Note: The pattern used is equivalent to using pattern="common" -->
|
||||||
|
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
|
||||||
|
prefix="localhost_access_log" suffix=".txt"
|
||||||
|
pattern="%h %l %u %t "%r" %s %b" />
|
||||||
|
|
||||||
|
</Host>
|
||||||
|
</Engine>
|
||||||
|
</Service>
|
||||||
|
</Server>
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<tomcat-users xmlns="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
|
||||||
|
version="1.0">
|
||||||
|
<!--
|
||||||
|
By default, no user is included in the "manager-gui" role required
|
||||||
|
to operate the "/manager/html" web application. If you wish to use this app,
|
||||||
|
you must define such a user - the username and password are arbitrary.
|
||||||
|
|
||||||
|
Built-in Tomcat manager roles:
|
||||||
|
- manager-gui - allows access to the HTML GUI and the status pages
|
||||||
|
- manager-script - allows access to the HTTP API and the status pages
|
||||||
|
- manager-jmx - allows access to the JMX proxy and the status pages
|
||||||
|
- manager-status - allows access to the status pages only
|
||||||
|
|
||||||
|
The users below are wrapped in a comment and are therefore ignored. If you
|
||||||
|
wish to configure one or more of these users for use with the manager web
|
||||||
|
application, do not forget to remove the <!.. ..> that surrounds them. You
|
||||||
|
will also need to set the passwords to something appropriate.
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<user username="admin" password="<must-be-changed>" roles="manager-gui"/>
|
||||||
|
<user username="robot" password="<must-be-changed>" roles="manager-script"/>
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
The sample user and role entries below are intended for use with the
|
||||||
|
examples web application. They are wrapped in a comment and thus are ignored
|
||||||
|
when reading this file. If you wish to configure these users for use with the
|
||||||
|
examples web application, do not forget to remove the <!.. ..> that surrounds
|
||||||
|
them. You will also need to set the passwords to something appropriate.
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
<role rolename="tomcat"/>
|
||||||
|
<role rolename="role1"/>
|
||||||
|
<user username="tomcat" password="<must-be-changed>" roles="tomcat"/>
|
||||||
|
<user username="both" password="<must-be-changed>" roles="tomcat,role1"/>
|
||||||
|
<user username="role1" password="<must-be-changed>" roles="role1"/>
|
||||||
|
-->
|
||||||
|
<role rolename="admin"/>
|
||||||
|
<user username="demo" password="demo" roles="admin"/>
|
||||||
|
|
||||||
|
</tomcat-users>
|
|
@ -0,0 +1,59 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
||||||
|
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema"
|
||||||
|
targetNamespace="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:users="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:xs="http://www.w3.org/2001/XMLSchema"
|
||||||
|
elementFormDefault="qualified"
|
||||||
|
attributeFormDefault="unqualified"
|
||||||
|
version="1.0">
|
||||||
|
<xs:element name="tomcat-users">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:choice minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:element name="role">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="rolename" use="required" type="users:entityname" />
|
||||||
|
<xs:attribute name="description" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="group">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="groupname" use="required" type="users:entityname" />
|
||||||
|
<xs:attribute name="description" type="xs:string" />
|
||||||
|
<xs:attribute name="roles" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:element name="user">
|
||||||
|
<xs:complexType>
|
||||||
|
<xs:attribute name="username" use="required" type="users:entityname" />
|
||||||
|
<xs:attribute name="fullname" type="xs:string" />
|
||||||
|
<xs:attribute name="password" type="xs:string" />
|
||||||
|
<xs:attribute name="roles" type="xs:string" />
|
||||||
|
<xs:attribute name="groups" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
</xs:choice>
|
||||||
|
<xs:attribute name="version" type="xs:string" />
|
||||||
|
</xs:complexType>
|
||||||
|
</xs:element>
|
||||||
|
<xs:simpleType name="entityname">
|
||||||
|
<xs:restriction base="xs:string">
|
||||||
|
<xs:minLength value="1"/>
|
||||||
|
</xs:restriction>
|
||||||
|
</xs:simpleType>
|
||||||
|
</xs:schema>
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_4_0.xsd"
|
||||||
|
id="ping"
|
||||||
|
version="3.0">
|
||||||
|
<display-name>Ping</display-name>
|
||||||
|
|
||||||
|
<security-constraint>
|
||||||
|
<display-name>Ping Login Auth</display-name>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>PingRestrictedAccess</web-resource-name>
|
||||||
|
<url-pattern>/private/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
<user-data-constraint>
|
||||||
|
<transport-guarantee>NONE</transport-guarantee>
|
||||||
|
</user-data-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</security-role>
|
||||||
|
|
||||||
|
<login-config>
|
||||||
|
<auth-method>FORM</auth-method>
|
||||||
|
<form-login-config>
|
||||||
|
<form-login-page>/logging.html</form-login-page>
|
||||||
|
<form-error-page>/logging_error.html</form-error-page>
|
||||||
|
</form-login-config>
|
||||||
|
</login-config>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<filter-name>PingExpiresFilter</filter-name>
|
||||||
|
<filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>ExpiresByType text/html</param-name>
|
||||||
|
<param-value>access plus 0 seconds</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>PingExpiresFilter</filter-name>
|
||||||
|
<url-pattern>/private/*</url-pattern>
|
||||||
|
<dispatcher>REQUEST</dispatcher>
|
||||||
|
</filter-mapping>
|
||||||
|
</web-app>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Ping</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a href="private/index.html">Start pinging</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Ping - Login</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<form method="post" action="j_security_check">
|
||||||
|
<table >
|
||||||
|
<tr>
|
||||||
|
<td>User name: </td>
|
||||||
|
<td><input type="text" name="j_username"
|
||||||
|
size="20"/></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Password: </td>
|
||||||
|
<td><input type="password" name="j_password"
|
||||||
|
size="20"/></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<p></p>
|
||||||
|
<input type="submit" value="Submit"/>
|
||||||
|
|
||||||
|
<input type="reset" value="Reset"/>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Ping</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
Error logging in!
|
||||||
|
<a href="index.html">Try again</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Ping - Pinging</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a href="/pong/private/index.html">Pong!</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,47 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
|
||||||
|
<display-name>Pong</display-name>
|
||||||
|
<welcome-file-list>
|
||||||
|
<welcome-file>index.html</welcome-file>
|
||||||
|
</welcome-file-list>
|
||||||
|
|
||||||
|
|
||||||
|
<security-constraint>
|
||||||
|
<display-name>Pong Login Auth</display-name>
|
||||||
|
<web-resource-collection>
|
||||||
|
<web-resource-name>PongRestrictedAccess</web-resource-name>
|
||||||
|
<url-pattern>/private/*</url-pattern>
|
||||||
|
</web-resource-collection>
|
||||||
|
<auth-constraint>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</auth-constraint>
|
||||||
|
<user-data-constraint>
|
||||||
|
<transport-guarantee>NONE</transport-guarantee>
|
||||||
|
</user-data-constraint>
|
||||||
|
</security-constraint>
|
||||||
|
|
||||||
|
<security-role>
|
||||||
|
<role-name>admin</role-name>
|
||||||
|
</security-role>
|
||||||
|
|
||||||
|
|
||||||
|
<login-config>
|
||||||
|
<auth-method>DIGEST</auth-method>
|
||||||
|
</login-config>
|
||||||
|
|
||||||
|
<filter>
|
||||||
|
<filter-name>PongExpiresFilter</filter-name>
|
||||||
|
<filter-class>org.apache.catalina.filters.ExpiresFilter</filter-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>ExpiresByType text/html</param-name>
|
||||||
|
<param-value>access plus 0 seconds</param-value>
|
||||||
|
</init-param>
|
||||||
|
</filter>
|
||||||
|
|
||||||
|
<filter-mapping>
|
||||||
|
<filter-name>PongExpiresFilter</filter-name>
|
||||||
|
<url-pattern>/private/*</url-pattern>
|
||||||
|
<dispatcher>REQUEST</dispatcher>
|
||||||
|
</filter-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Pong</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a href="private/index.html">Start ponging</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Pong - Ponging</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<a href="/ping/private/index.html">Ping!</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -5,3 +5,4 @@
|
||||||
- [Start Two Threads at the Exact Same Time in Java](https://www.baeldung.com/java-start-two-threads-at-same-time)
|
- [Start Two Threads at the Exact Same Time in Java](https://www.baeldung.com/java-start-two-threads-at-same-time)
|
||||||
- [Volatile Variables and Thread Safety](https://www.baeldung.com/java-volatile-variables-thread-safety)
|
- [Volatile Variables and Thread Safety](https://www.baeldung.com/java-volatile-variables-thread-safety)
|
||||||
- [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem)
|
- [Producer-Consumer Problem With Example in Java](https://www.baeldung.com/java-producer-consumer-problem)
|
||||||
|
- [Acquire a Lock by a Key in Java](https://www.baeldung.com/java-acquire-lock-by-key)
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
public class Consumer implements Runnable {
|
||||||
|
private final DataQueue dataQueue;
|
||||||
|
private volatile boolean runFlag;
|
||||||
|
|
||||||
|
public Consumer(DataQueue dataQueue) {
|
||||||
|
this.dataQueue = dataQueue;
|
||||||
|
runFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
consume();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void consume() {
|
||||||
|
while (runFlag) {
|
||||||
|
Message message;
|
||||||
|
if (dataQueue.isEmpty()) {
|
||||||
|
try {
|
||||||
|
dataQueue.waitOnEmpty();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!runFlag) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
message = dataQueue.remove();
|
||||||
|
dataQueue.notifyAllForFull();
|
||||||
|
useMessage(message);
|
||||||
|
}
|
||||||
|
System.out.println("Consumer Stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void useMessage(Message message) {
|
||||||
|
if (message != null) {
|
||||||
|
System.out.printf("[%s] Consuming Message. Id: %d, Data: %f\n", Thread.currentThread().getName(), message.getId(), message.getData());
|
||||||
|
|
||||||
|
//Sleeping on random time to make it realistic
|
||||||
|
ThreadUtil.sleep((long) (message.getData() * 100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
runFlag = false;
|
||||||
|
dataQueue.notifyAllForEmpty();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.Queue;
|
||||||
|
|
||||||
|
public class DataQueue {
|
||||||
|
private final Queue<Message> queue = new LinkedList<>();
|
||||||
|
private final int maxSize;
|
||||||
|
private final Object FULL_QUEUE = new Object();
|
||||||
|
private final Object EMPTY_QUEUE = new Object();
|
||||||
|
|
||||||
|
DataQueue(int maxSize) {
|
||||||
|
this.maxSize = maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isFull() {
|
||||||
|
return queue.size() == maxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return queue.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitOnFull() throws InterruptedException {
|
||||||
|
synchronized (FULL_QUEUE) {
|
||||||
|
FULL_QUEUE.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void waitOnEmpty() throws InterruptedException {
|
||||||
|
synchronized (EMPTY_QUEUE) {
|
||||||
|
EMPTY_QUEUE.wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyAllForFull() {
|
||||||
|
synchronized (FULL_QUEUE) {
|
||||||
|
FULL_QUEUE.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyAllForEmpty() {
|
||||||
|
synchronized (EMPTY_QUEUE) {
|
||||||
|
EMPTY_QUEUE.notifyAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void add(Message message) {
|
||||||
|
synchronized (queue) {
|
||||||
|
queue.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Message remove() {
|
||||||
|
synchronized (queue) {
|
||||||
|
return queue.poll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
public class Message {
|
||||||
|
private int id;
|
||||||
|
private double data;
|
||||||
|
|
||||||
|
public Message(int id, double data) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setData(double data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
public class Producer implements Runnable {
|
||||||
|
private final DataQueue dataQueue;
|
||||||
|
private volatile boolean runFlag;
|
||||||
|
|
||||||
|
private static int idSequence = 0;
|
||||||
|
|
||||||
|
public Producer(DataQueue dataQueue) {
|
||||||
|
this.dataQueue = dataQueue;
|
||||||
|
runFlag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
produce();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void produce() {
|
||||||
|
while (runFlag) {
|
||||||
|
Message message = generateMessage();
|
||||||
|
while (dataQueue.isFull()) {
|
||||||
|
try {
|
||||||
|
dataQueue.waitOnFull();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!runFlag) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dataQueue.add(message);
|
||||||
|
dataQueue.notifyAllForEmpty();
|
||||||
|
}
|
||||||
|
System.out.println("Producer Stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Message generateMessage() {
|
||||||
|
Message message = new Message(++idSequence, Math.random());
|
||||||
|
System.out.printf("[%s] Generated Message. Id: %d, Data: %f\n", Thread.currentThread().getName(), message.getId(), message.getData());
|
||||||
|
|
||||||
|
//Sleeping on random time to make it realistic
|
||||||
|
ThreadUtil.sleep((long) (message.getData() * 100));
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
runFlag = false;
|
||||||
|
dataQueue.notifyAllForFull();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.baeldung.producerconsumer.ThreadUtil.*;
|
||||||
|
|
||||||
|
public class ProducerConsumerDemonstrator {
|
||||||
|
private static final int MAX_QUEUE_CAPACITY = 5;
|
||||||
|
|
||||||
|
public static void demoSingleProducerAndSingleConsumer() {
|
||||||
|
DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY);
|
||||||
|
|
||||||
|
Producer producer = new Producer(dataQueue);
|
||||||
|
Thread producerThread = new Thread(producer);
|
||||||
|
|
||||||
|
Consumer consumer = new Consumer(dataQueue);
|
||||||
|
Thread consumerThread = new Thread(consumer);
|
||||||
|
|
||||||
|
producerThread.start();
|
||||||
|
consumerThread.start();
|
||||||
|
|
||||||
|
List<Thread> threads = new ArrayList<>();
|
||||||
|
threads.add(producerThread);
|
||||||
|
threads.add(consumerThread);
|
||||||
|
|
||||||
|
// let threads run for two seconds
|
||||||
|
sleep(2000);
|
||||||
|
|
||||||
|
// Stop threads
|
||||||
|
producer.stop();
|
||||||
|
consumer.stop();
|
||||||
|
|
||||||
|
waitForAllThreadsToComplete(threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void demoMultipleProducersAndMultipleConsumers() {
|
||||||
|
DataQueue dataQueue = new DataQueue(MAX_QUEUE_CAPACITY);
|
||||||
|
int producerCount = 3;
|
||||||
|
int consumerCount = 3;
|
||||||
|
List<Thread> threads = new ArrayList<>();
|
||||||
|
Producer producer = new Producer(dataQueue);
|
||||||
|
for(int i = 0; i < producerCount; i++) {
|
||||||
|
Thread producerThread = new Thread(producer);
|
||||||
|
producerThread.start();
|
||||||
|
threads.add(producerThread);
|
||||||
|
}
|
||||||
|
Consumer consumer = new Consumer(dataQueue);
|
||||||
|
for(int i = 0; i < consumerCount; i++) {
|
||||||
|
Thread consumerThread = new Thread(consumer);
|
||||||
|
consumerThread.start();
|
||||||
|
threads.add(consumerThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let threads run for two seconds
|
||||||
|
sleep(2000);
|
||||||
|
|
||||||
|
// Stop threads
|
||||||
|
producer.stop();
|
||||||
|
consumer.stop();
|
||||||
|
|
||||||
|
waitForAllThreadsToComplete(threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
demoSingleProducerAndSingleConsumer();
|
||||||
|
demoMultipleProducersAndMultipleConsumers();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.LinkedBlockingDeque;
|
||||||
|
|
||||||
|
import static com.baeldung.producerconsumer.ThreadUtil.sleep;
|
||||||
|
|
||||||
|
public class SimpleProducerConsumerDemonstrator {
|
||||||
|
BlockingQueue<Double> blockingQueue = new LinkedBlockingDeque<>(5);
|
||||||
|
|
||||||
|
private void produce() {
|
||||||
|
while (true) {
|
||||||
|
double value = generateValue();
|
||||||
|
try {
|
||||||
|
blockingQueue.put(value);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
System.out.printf("[%s] Value produced: %f\n", Thread.currentThread().getName(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void consume() {
|
||||||
|
while (true) {
|
||||||
|
Double value;
|
||||||
|
try {
|
||||||
|
value = blockingQueue.take();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Consume value
|
||||||
|
System.out.printf("[%s] Value consumed: %f\n", Thread.currentThread().getName(), value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double generateValue() {
|
||||||
|
return Math.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runProducerConsumer() {
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
Thread producerThread = new Thread(this::produce);
|
||||||
|
producerThread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Thread consumerThread = new Thread(this::consume);
|
||||||
|
consumerThread.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SimpleProducerConsumerDemonstrator simpleProducerConsumerDemonstrator = new SimpleProducerConsumerDemonstrator();
|
||||||
|
simpleProducerConsumerDemonstrator.runProducerConsumer();
|
||||||
|
sleep(2000);
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.baeldung.producerconsumer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ThreadUtil {
|
||||||
|
public static void waitForAllThreadsToComplete(List<Thread> threads) {
|
||||||
|
for(Thread thread: threads) {
|
||||||
|
try {
|
||||||
|
thread.join();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sleep(long interval) {
|
||||||
|
try {
|
||||||
|
// Wait for some time to demonstrate threads
|
||||||
|
Thread.sleep(interval);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,4 +11,5 @@ This module contains articles about date operations in Java.
|
||||||
- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week)
|
- [How to determine day of week by passing specific date in Java?](https://www.baeldung.com/java-get-day-of-week)
|
||||||
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
- [Finding Leap Years in Java](https://www.baeldung.com/java-leap-year)
|
||||||
- [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number)
|
- [Getting the Week Number From Any Date](https://www.baeldung.com/java-get-week-number)
|
||||||
|
- [Subtract Days from a Date in Java](https://www.baeldung.com/java-subtract-days-from-a-date)
|
||||||
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
- [[<-- Prev]](/core-java-modules/core-java-date-operations-1)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.subtractdays;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
import org.joda.time.DateTime;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class SubtractDaysFromDateUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenCalendarDate_whenSubtractingFiveDays_dateIsChangedCorrectly() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.set(2022, Calendar.APRIL, 20);
|
||||||
|
|
||||||
|
calendar.add(Calendar.DATE, -5);
|
||||||
|
|
||||||
|
assertEquals(15, calendar.get(Calendar.DAY_OF_MONTH));
|
||||||
|
assertEquals(Calendar.APRIL, calendar.get(Calendar.MONTH));
|
||||||
|
assertEquals(2022, calendar.get(Calendar.YEAR));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenJodaDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() {
|
||||||
|
DateTime dateTime = new DateTime(2022, 4, 20, 12, 0, 0);
|
||||||
|
|
||||||
|
dateTime = dateTime.minusDays(5);
|
||||||
|
|
||||||
|
assertEquals(15, dateTime.getDayOfMonth());
|
||||||
|
assertEquals(4, dateTime.getMonthOfYear());
|
||||||
|
assertEquals(2022, dateTime.getYear());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenLocalDateTime_whenSubtractingFiveDays_dateIsChangedCorrectly() {
|
||||||
|
LocalDate localDateTime = LocalDate.of(2022, 4, 20);
|
||||||
|
|
||||||
|
localDateTime = localDateTime.minusDays(5);
|
||||||
|
|
||||||
|
assertEquals(15, localDateTime.getDayOfMonth());
|
||||||
|
assertEquals(4, localDateTime.getMonthValue());
|
||||||
|
assertEquals(2022, localDateTime.getYear());
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
- [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception)
|
- [Java ArrayIndexOutOfBoundsException](https://www.baeldung.com/java-arrayindexoutofboundsexception)
|
||||||
- [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement)
|
- [Java Missing Return Statement](https://www.baeldung.com/java-missing-return-statement)
|
||||||
|
- [Convert long to int Type in Java](https://www.baeldung.com/java-convert-long-to-int)
|
||||||
|
|
|
@ -10,3 +10,4 @@ This module contains articles about core features in the Java language
|
||||||
- [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation)
|
- [Tiered Compilation in JVM](https://www.baeldung.com/jvm-tiered-compilation)
|
||||||
- [Fixing the “Declared package does not match the expected package” Error](https://www.baeldung.com/java-declared-expected-package-error)
|
- [Fixing the “Declared package does not match the expected package” Error](https://www.baeldung.com/java-declared-expected-package-error)
|
||||||
- [Chaining Constructors in Java](https://www.baeldung.com/java-chain-constructors)
|
- [Chaining Constructors in Java](https://www.baeldung.com/java-chain-constructors)
|
||||||
|
- [Difference Between POJO, JavaBeans, DTO and VO](https://www.baeldung.com/java-pojo-javabeans-dto-vo)
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.baeldung.employee;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class EmployeeBean implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -3760445487636086034L;
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
public EmployeeBean() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmployeeBean(String firstName, String lastName, LocalDate startDate) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(LocalDate startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.baeldung.employee;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class EmployeeDTO {
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(LocalDate startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.employee;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class EmployeePOJO {
|
||||||
|
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
public EmployeePOJO(String firstName, String lastName, LocalDate startDate) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return this.firstName + " " + this.lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStart() {
|
||||||
|
return this.startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStartDate(LocalDate startDate) {
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.baeldung.employee;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class EmployeeVO {
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private LocalDate startDate;
|
||||||
|
|
||||||
|
public EmployeeVO(String firstName, String lastName, LocalDate startDate) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.startDate = startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getStartDate() {
|
||||||
|
return startDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return Objects.equals(firstName, this.firstName)
|
||||||
|
&& Objects.equals(lastName, this.lastName)
|
||||||
|
&& Objects.equals(startDate, this.startDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(firstName, lastName, startDate);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,9 @@ package com.baeldung.split;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.MatchResult;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
@ -29,16 +30,11 @@ public class SplitStringEveryNthChar {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> usingPattern(String text, int n) {
|
public static List<String> usingPattern(String text, int n) {
|
||||||
List<String> results = new ArrayList<>();
|
return Pattern.compile(".{1," + n + "}")
|
||||||
|
.matcher(text)
|
||||||
Pattern pattern = Pattern.compile(".{1," + n + "}");
|
.results()
|
||||||
Matcher matcher = pattern.matcher(text);
|
.map(MatchResult::group)
|
||||||
while (matcher.find()) {
|
.collect(Collectors.toList());
|
||||||
String match = text.substring(matcher.start(), matcher.end());
|
|
||||||
results.add(match);
|
|
||||||
}
|
|
||||||
|
|
||||||
return results;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> usingGuava(String text, int n) {
|
public static List<String> usingGuava(String text, int n) {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Introduction to Jakarta EE MVC / Eclipse Krazo](https://www.baeldung.com/java-ee-mvc-eclipse-krazo)
|
|
@ -1,28 +1,13 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>mvc-2.0</artifactId>
|
<artifactId>jakarta-ee</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<name>jakarta-ee</name>
|
||||||
<packaging>war</packaging>
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<name>mvc-2.0</name>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<jakartaee-api.version>9.0.0</jakartaee-api.version>
|
|
||||||
<krazo.version>2.0.0</krazo.version>
|
|
||||||
<jakarta.mvc-api.version>2.0.0</jakarta.mvc-api.version>
|
|
||||||
<junit.jupiter.version>5.8.2</junit.jupiter.version>
|
|
||||||
<local.glassfish.home>C:/glassfish6</local.glassfish.home>
|
|
||||||
<local.glassfish.user>admin</local.glassfish.user>
|
|
||||||
<local.glassfish.domain>mvn-domain</local.glassfish.domain>
|
|
||||||
<mockito.version>1.10.19</mockito.version>
|
|
||||||
<local.glassfish.passfile>
|
|
||||||
${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords
|
|
||||||
</local.glassfish.passfile>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.platform</groupId>
|
<groupId>jakarta.platform</groupId>
|
||||||
|
@ -30,13 +15,11 @@
|
||||||
<version>${jakartaee-api.version}</version>
|
<version>${jakartaee-api.version}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>jakarta.mvc</groupId>
|
<groupId>jakarta.mvc</groupId>
|
||||||
<artifactId>jakarta.mvc-api</artifactId>
|
<artifactId>jakarta.mvc-api</artifactId>
|
||||||
<version>${jakarta.mvc-api.version}</version>
|
<version>${jakarta.mvc-api.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.krazo</groupId>
|
<groupId>org.eclipse.krazo</groupId>
|
||||||
<artifactId>krazo-jersey</artifactId>
|
<artifactId>krazo-jersey</artifactId>
|
||||||
|
@ -54,7 +37,6 @@
|
||||||
<version>${mockito.version}</version>
|
<version>${mockito.version}</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -108,4 +90,19 @@
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<jakartaee-api.version>9.0.0</jakartaee-api.version>
|
||||||
|
<krazo.version>2.0.0</krazo.version>
|
||||||
|
<jakarta.mvc-api.version>2.0.0</jakarta.mvc-api.version>
|
||||||
|
<junit.jupiter.version>5.8.2</junit.jupiter.version>
|
||||||
|
<local.glassfish.home>C:/glassfish6</local.glassfish.home>
|
||||||
|
<local.glassfish.user>admin</local.glassfish.user>
|
||||||
|
<local.glassfish.domain>mvn-domain</local.glassfish.domain>
|
||||||
|
<mockito.version>1.10.19</mockito.version>
|
||||||
|
<local.glassfish.passfile>
|
||||||
|
${local.glassfish.home}\\domains\\${local.glassfish.domain}\\config\\domain-passwords
|
||||||
|
</local.glassfish.passfile>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -4,3 +4,4 @@
|
||||||
- [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
|
- [Understanding the & 0xff Value in Java](https://www.baeldung.com/java-and-0xff)
|
||||||
- [Determine if an Integer’s Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)
|
- [Determine if an Integer’s Square Root Is an Integer in Java](https://www.baeldung.com/java-find-if-square-root-is-integer)
|
||||||
- [Guide to Java BigInteger](https://www.baeldung.com/java-biginteger)
|
- [Guide to Java BigInteger](https://www.baeldung.com/java-biginteger)
|
||||||
|
- [Automorphic Numbers in Java](https://www.baeldung.com/java-automorphic-numbers)
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.baeldung.automorphicnumber;
|
||||||
|
|
||||||
|
public class AutomorphicNumber {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(isAutomorphicUsingLoop(76));
|
||||||
|
System.out.println(isAutomorphicUsingMath(76));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAutomorphicUsingMath(int number) {
|
||||||
|
int square = number * number;
|
||||||
|
|
||||||
|
int numberOfDigits = (int) Math.floor(Math.log10(number) + 1);
|
||||||
|
int lastDigits = (int) (square % (Math.pow(10, numberOfDigits)));
|
||||||
|
|
||||||
|
return number == lastDigits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isAutomorphicUsingLoop(int number) {
|
||||||
|
int square = number * number;
|
||||||
|
|
||||||
|
while (number > 0) {
|
||||||
|
if (number % 10 != square % 10) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
number /= 10;
|
||||||
|
square /= 10;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.baeldung.automorphicnumber;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
public class AutomorphicNumberUnitTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenANumber_whenPassed_thenShouldDetermineAutomorphicOrNot() {
|
||||||
|
int number1 = 76; // automorphic
|
||||||
|
int number2 = 16; // not automorphic
|
||||||
|
assertTrue(AutomorphicNumber.isAutomorphicUsingLoop(number1));
|
||||||
|
assertFalse(AutomorphicNumber.isAutomorphicUsingLoop(number2));
|
||||||
|
assertTrue(AutomorphicNumber.isAutomorphicUsingMath(number1));
|
||||||
|
assertFalse(AutomorphicNumber.isAutomorphicUsingMath(number2));
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,16 +10,23 @@ import com.twitter.util.Future;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import scala.runtime.BoxedUnit;
|
import scala.runtime.BoxedUnit;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ServerSocket;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
public class FinagleIntegrationTest {
|
public class FinagleIntegrationTest {
|
||||||
|
|
||||||
|
private static final int DEFAULT_PORT = 8079;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void givenServerAndClient_whenRequestSent_thenClientShouldReceiveResponseFromServer() throws Exception {
|
public void givenServerAndClient_whenRequestSent_thenClientShouldReceiveResponseFromServer() throws Exception {
|
||||||
// given
|
// given
|
||||||
|
int port = randomPort();
|
||||||
Service serverService = new LogFilter().andThen(new GreetingService());
|
Service serverService = new LogFilter().andThen(new GreetingService());
|
||||||
Http.serve(":8080", serverService);
|
Http.serve(":" + port, serverService);
|
||||||
|
|
||||||
Service<Request, Response> clientService = new LogFilter().andThen(Http.newService(":8080"));
|
Service<Request, Response> clientService = new LogFilter().andThen(Http.newService(":" + port));
|
||||||
|
|
||||||
// when
|
// when
|
||||||
Request request = Request.apply(Method.Get(), "/?name=John");
|
Request request = Request.apply(Method.Get(), "/?name=John");
|
||||||
|
@ -37,4 +44,13 @@ public class FinagleIntegrationTest {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int randomPort() {
|
||||||
|
try (ServerSocket socket = new ServerSocket(0)) {
|
||||||
|
return socket.getLocalPort();
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
return DEFAULT_PORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baeldung</groupId>
|
|
||||||
<artifactId>copy-rename-maven-plugin</artifactId>
|
<artifactId>copy-rename-maven-plugin</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<name>copy-rename-maven-plugin</name>
|
<name>copy-rename-maven-plugin</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baeldung</groupId>
|
|
||||||
<artifactId>maven-antrun-plugin</artifactId>
|
<artifactId>maven-antrun-plugin</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<name>maven-antrun-plugin</name>
|
<name>maven-antrun-plugin</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -3,9 +3,7 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baeldung</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
|
||||||
<name>maven-resources-plugin</name>
|
<name>maven-resources-plugin</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.baeldung;
|
package com.baeldung;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
|
@ -4,13 +4,12 @@
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>maven-dependency</artifactId>
|
<artifactId>maven-dependency</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>maven-simple</artifactId>
|
<artifactId>maven-simple</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>1.0.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
|
|
|
@ -3,14 +3,24 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baeldung</groupId>
|
|
||||||
<artifactId>core</artifactId>
|
<artifactId>core</artifactId>
|
||||||
<name>core</name>
|
<name>core</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-project</artifactId>
|
<artifactId>parent-project</artifactId>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-core.version>4.3.30.RELEASE</spring-core.version>
|
||||||
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -4,6 +4,7 @@
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>parent-project</artifactId>
|
<artifactId>parent-project</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
<name>parent-project</name>
|
<name>parent-project</name>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
|
@ -19,4 +20,17 @@
|
||||||
<module>webapp</module>
|
<module>webapp</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
|
<dependencyManagement>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-core</artifactId>
|
||||||
|
<version>${spring-core.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</dependencyManagement>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<spring-core.version>5.3.16</spring-core.version>
|
||||||
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -3,14 +3,13 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baeldung</groupId>
|
|
||||||
<artifactId>service</artifactId>
|
<artifactId>service</artifactId>
|
||||||
<name>service</name>
|
<name>service</name>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-project</artifactId>
|
<artifactId>parent-project</artifactId>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -3,14 +3,31 @@
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>org.baeldung</groupId>
|
|
||||||
<artifactId>webapp</artifactId>
|
<artifactId>webapp</artifactId>
|
||||||
<name>webapp</name>
|
<name>webapp</name>
|
||||||
|
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>parent-project</artifactId>
|
<artifactId>parent-project</artifactId>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>${maven-war-plugin.version}</version>
|
||||||
|
<configuration>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
|
||||||
|
</properties>
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Using Nginx as a Forward Proxy](https://www.baeldung.com/nginx-forward-proxy)
|
|
@ -88,7 +88,7 @@
|
||||||
<rest-assured.version>3.3.0</rest-assured.version>
|
<rest-assured.version>3.3.0</rest-assured.version>
|
||||||
<!-- plugins -->
|
<!-- plugins -->
|
||||||
<thin.version>1.0.22.RELEASE</thin.version>
|
<thin.version>1.0.22.RELEASE</thin.version>
|
||||||
<spring-boot.version>2.6.3</spring-boot.version>
|
<spring-boot.version>2.6.4</spring-boot.version>
|
||||||
<aspectjweaver.version>1.9.1</aspectjweaver.version>
|
<aspectjweaver.version>1.9.1</aspectjweaver.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Building a web app Using Fauna and Spring for Your First web Agency Client](https://www.baeldung.com/faunadb-spring-web-app)
|
|
@ -1,21 +1,21 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>fauna</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>fauna</name>
|
||||||
|
<description>Blogging Service built with FaunaDB</description>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>2.6.2</version>
|
<version>2.6.2</version>
|
||||||
<relativePath /> <!-- lookup parent from repository -->
|
<relativePath /> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.baeldung</groupId>
|
|
||||||
<artifactId>fauna-blog</artifactId>
|
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
|
||||||
<name>fauna-blog</name>
|
|
||||||
<description>Blogging Service built with FaunaDB</description>
|
|
||||||
<properties>
|
|
||||||
<java.version>17</java.version>
|
|
||||||
</properties>
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -53,4 +53,8 @@
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<java.version>17</java.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -4,6 +4,7 @@ This module contains articles about use of Queries in Hibernate.
|
||||||
|
|
||||||
### Relevant articles:
|
### Relevant articles:
|
||||||
|
|
||||||
|
- [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries)
|
||||||
- [Criteria Queries Using JPA Metamodel](https://www.baeldung.com/hibernate-criteria-queries-metamodel)
|
- [Criteria Queries Using JPA Metamodel](https://www.baeldung.com/hibernate-criteria-queries-metamodel)
|
||||||
- [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all)
|
- [Get All Data from a Table with Hibernate](https://www.baeldung.com/hibernate-select-all)
|
||||||
- [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query)
|
- [Hibernate Named Query](https://www.baeldung.com/hibernate-named-query)
|
||||||
|
|
|
@ -14,6 +14,38 @@
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<!-- Spring -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-context</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-jpa</artifactId>
|
||||||
|
<version>${org.springframework.data.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tomcat</groupId>
|
||||||
|
<artifactId>tomcat-dbcp</artifactId>
|
||||||
|
<version>${tomcat-dbcp.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- validation -->
|
||||||
|
<!-- utils -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- test scoped -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-test</artifactId>
|
||||||
|
<version>${org.springframework.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.hibernate</groupId>
|
<groupId>org.hibernate</groupId>
|
||||||
<artifactId>hibernate-core</artifactId>
|
<artifactId>hibernate-core</artifactId>
|
||||||
|
@ -49,9 +81,13 @@
|
||||||
<artifactId>jmh-generator-annprocess</artifactId>
|
<artifactId>jmh-generator-annprocess</artifactId>
|
||||||
<version>${jmh-generator.version}</version>
|
<version>${jmh-generator.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>
|
||||||
|
<org.springframework.data.version>1.10.6.RELEASE</org.springframework.data.version>
|
||||||
|
<tomcat-dbcp.version>9.0.0.M26</tomcat-dbcp.version>
|
||||||
<mysql.version>6.0.6</mysql.version>
|
<mysql.version>6.0.6</mysql.version>
|
||||||
<mariaDB4j.version>2.2.3</mariaDB4j.version>
|
<mariaDB4j.version>2.2.3</mariaDB4j.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package com.baeldung.hibernate.criteria;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.PropertySource;
|
||||||
|
import org.springframework.core.env.Environment;
|
||||||
|
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
|
||||||
|
import org.springframework.orm.hibernate5.HibernateTransactionManager;
|
||||||
|
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
|
||||||
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableTransactionManagement
|
||||||
|
@PropertySource({ "classpath:persistence-h2.properties" })
|
||||||
|
@ComponentScan({ "com.baeldung.hibernate.criteria" })
|
||||||
|
public class PersistenceConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private Environment env;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LocalSessionFactoryBean sessionFactory() {
|
||||||
|
final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
|
||||||
|
sessionFactory.setDataSource(dataSource());
|
||||||
|
sessionFactory.setPackagesToScan(new String[] { "com.baeldung.hibernate.criteria" });
|
||||||
|
sessionFactory.setHibernateProperties(hibernateProperties());
|
||||||
|
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DataSource dataSource() {
|
||||||
|
final BasicDataSource dataSource = new BasicDataSource();
|
||||||
|
dataSource.setDriverClassName(Preconditions.checkNotNull(env.getProperty("jdbc.driverClassName")));
|
||||||
|
dataSource.setUrl(Preconditions.checkNotNull(env.getProperty("jdbc.url")));
|
||||||
|
dataSource.setUsername(Preconditions.checkNotNull(env.getProperty("jdbc.user")));
|
||||||
|
dataSource.setPassword(Preconditions.checkNotNull(env.getProperty("jdbc.pass")));
|
||||||
|
|
||||||
|
return dataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PlatformTransactionManager hibernateTransactionManager() {
|
||||||
|
final HibernateTransactionManager transactionManager = new HibernateTransactionManager();
|
||||||
|
transactionManager.setSessionFactory(sessionFactory().getObject());
|
||||||
|
return transactionManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
|
||||||
|
return new PersistenceExceptionTranslationPostProcessor();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Properties hibernateProperties() {
|
||||||
|
final Properties hibernateProperties = new Properties();
|
||||||
|
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
|
||||||
|
hibernateProperties.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
|
||||||
|
hibernateProperties.setProperty("hibernate.show_sql", "false");
|
||||||
|
|
||||||
|
return hibernateProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -7,6 +7,12 @@
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
|
<logger name="org.springframework" level="WARN" />
|
||||||
|
<logger name="org.springframework.transaction" level="WARN" />
|
||||||
|
|
||||||
|
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||||
|
<logger name="org.springframework.web.servlet.mvc" level="WARN" />
|
||||||
|
|
||||||
<root level="INFO">
|
<root level="INFO">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</root>
|
</root>
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# jdbc.X
|
||||||
|
jdbc.driverClassName=org.h2.Driver
|
||||||
|
jdbc.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
|
||||||
|
jdbc.eventGeneratedId=sa
|
||||||
|
jdbc.user=sa
|
||||||
|
jdbc.pass=
|
||||||
|
|
||||||
|
# hibernate.X
|
||||||
|
hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||||
|
hibernate.show_sql=false
|
||||||
|
hibernate.hbm2ddl.auto=create-drop
|
||||||
|
hibernate.cache.use_second_level_cache=true
|
||||||
|
hibernate.cache.use_query_cache=true
|
||||||
|
hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
|
||||||
|
|
||||||
|
# hibernate.search.X
|
||||||
|
hibernate.search.default.directory_provider = filesystem
|
||||||
|
hibernate.search.default.indexBase = /data/index/default
|
||||||
|
|
||||||
|
# envers.X
|
||||||
|
envers.audit_table_suffix=_audit_log
|
|
@ -0,0 +1,18 @@
|
||||||
|
package com.baeldung;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||||
|
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||||
|
|
||||||
|
import com.baeldung.hibernate.criteria.PersistenceConfig;
|
||||||
|
|
||||||
|
@RunWith(SpringJUnit4ClassRunner.class)
|
||||||
|
@ContextConfiguration(classes = { PersistenceConfig.class }, loader = AnnotationConfigContextLoader.class)
|
||||||
|
public class SpringContextTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,3 +14,7 @@ This module contains articles about MongoDB in Java.
|
||||||
- [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists)
|
- [How to Check Field Existence in MongoDB?](https://www.baeldung.com/mongodb-check-field-exists)
|
||||||
- [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id)
|
- [Get Last Inserted Document ID in MongoDB With Java Driver](https://www.baeldung.com/java-mongodb-last-inserted-id)
|
||||||
- [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields)
|
- [Update Multiple Fields in a MongoDB Document](https://www.baeldung.com/mongodb-update-multiple-fields)
|
||||||
|
- [Update Documents in MongoDB](https://www.baeldung.com/mongodb-update-documents)
|
||||||
|
- [Check Collection Existence in MongoDB](https://www.baeldung.com/java-check-collection-existence-mongodb)
|
||||||
|
- [Case Insensitive Sorting in MongoDB](https://www.baeldung.com/java-mongodb-case-insensitive-sorting)
|
||||||
|
- [Push and Set Operations in Same MongoDB Update](https://www.baeldung.com/java-mongodb-push-set)
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.baeldung.mongodb.dbref;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableMongoRepositories(basePackages = { "com.baeldung" })
|
||||||
|
public class DbRefApplication {
|
||||||
|
|
||||||
|
public static void main(String... args) {
|
||||||
|
SpringApplication.run(DbRefApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.baeldung.mongodb.dbref;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.ApplicationArguments;
|
||||||
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.baeldung.mongodb.dbref.repository.PersonRepository;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DbRefTester implements ApplicationRunner {
|
||||||
|
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(DbRefTester.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private PersonRepository personRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
|
logger.info("{}", personRepository.findAll());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.baeldung.mongodb.dbref.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.annotation.Id;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.DBRef;
|
||||||
|
import org.springframework.data.mongodb.core.mapping.Document;
|
||||||
|
|
||||||
|
@Document(collection = "Person")
|
||||||
|
public class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@DBRef
|
||||||
|
private List<Pet> pets;
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Pet> getPets() {
|
||||||
|
return pets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPets(List<Pet> pets) {
|
||||||
|
this.pets = pets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Person [id=" + id + ", name=" + name + ", pets=" + pets + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package com.baeldung.mongodb.dbref.model;
|
||||||
|
|
||||||
|
public class Pet {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(String id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Pet [id=" + id + ", name=" + name + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.baeldung.mongodb.dbref.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
|
||||||
|
import com.baeldung.mongodb.dbref.model.Person;
|
||||||
|
|
||||||
|
public interface PersonRepository extends MongoRepository<Person, String> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.baeldung.mongodb.dbref;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.mongodb.core.MongoTemplate;
|
||||||
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
|
import com.baeldung.mongodb.dbref.model.Person;
|
||||||
|
import com.baeldung.mongodb.dbref.model.Pet;
|
||||||
|
import com.baeldung.mongodb.dbref.repository.PersonRepository;
|
||||||
|
import com.mongodb.BasicDBObjectBuilder;
|
||||||
|
import com.mongodb.DBObject;
|
||||||
|
import com.mongodb.DBRef;
|
||||||
|
|
||||||
|
@RunWith(SpringRunner.class)
|
||||||
|
@SpringBootTest
|
||||||
|
@DirtiesContext
|
||||||
|
public class DbRefIntegrationTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
PersonRepository personRepository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MongoTemplate mongoTemplate;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void givenPetsAndPersonInDatabase_whenListPersons_thenReferenceIsFetched() {
|
||||||
|
// given
|
||||||
|
DBObject catInDatabase = BasicDBObjectBuilder.start()
|
||||||
|
.add("name", "Loki")
|
||||||
|
.get();
|
||||||
|
|
||||||
|
DBObject dogInDatabase = BasicDBObjectBuilder.start()
|
||||||
|
.add("name", "Max")
|
||||||
|
.get();
|
||||||
|
|
||||||
|
mongoTemplate.save(catInDatabase, "Cat");
|
||||||
|
mongoTemplate.save(dogInDatabase, "Dog");
|
||||||
|
|
||||||
|
List<DBRef> petsReference = new ArrayList<DBRef>();
|
||||||
|
petsReference.add(new DBRef("Cat", catInDatabase.get("_id")));
|
||||||
|
petsReference.add(new DBRef("Dog", dogInDatabase.get("_id")));
|
||||||
|
|
||||||
|
DBObject personInDatabase = BasicDBObjectBuilder.start()
|
||||||
|
.add("name", "Bob")
|
||||||
|
.add("pets", petsReference)
|
||||||
|
.get();
|
||||||
|
|
||||||
|
mongoTemplate.save(personInDatabase, "Person");
|
||||||
|
|
||||||
|
// when
|
||||||
|
List<Person> persons = personRepository.findAll();
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertThat(persons).hasSize(1);
|
||||||
|
Person person = persons.get(0);
|
||||||
|
assertEquals("Bob", person.getName());
|
||||||
|
|
||||||
|
List<Pet> pets = person.getPets();
|
||||||
|
assertThat(pets).hasSize(2);
|
||||||
|
assertThat(pets).anyMatch(pet -> "Loki".equals(pet.getName()));
|
||||||
|
assertThat(pets).anyMatch(pet -> "Max".equals(pet.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -67,7 +67,6 @@
|
||||||
<start-class>com.baeldung.boot.Application</start-class>
|
<start-class>com.baeldung.boot.Application</start-class>
|
||||||
<testcontainers.postgresql.version>1.10.6</testcontainers.postgresql.version>
|
<testcontainers.postgresql.version>1.10.6</testcontainers.postgresql.version>
|
||||||
<postgresql.version>42.2.5</postgresql.version>
|
<postgresql.version>42.2.5</postgresql.version>
|
||||||
<spring-boot.version>2.6.1</spring-boot.version> <!-- Temp downgrade due to spring-data-jpa issue. Fixing in JAVA-9857 -->
|
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -5,7 +5,6 @@ This module contains articles about Hibernate 5 with Spring.
|
||||||
### Relevant articles
|
### Relevant articles
|
||||||
|
|
||||||
- [Programmatic Transactions in the Spring TestContext Framework](https://www.baeldung.com/spring-test-programmatic-transactions)
|
- [Programmatic Transactions in the Spring TestContext Framework](https://www.baeldung.com/spring-test-programmatic-transactions)
|
||||||
- [JPA Criteria Queries](https://www.baeldung.com/hibernate-criteria-queries)
|
|
||||||
- [Introduction to Hibernate Search](https://www.baeldung.com/hibernate-search)
|
- [Introduction to Hibernate Search](https://www.baeldung.com/hibernate-search)
|
||||||
- [@DynamicUpdate with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-dynamicupdate)
|
- [@DynamicUpdate with Spring Data JPA](https://www.baeldung.com/spring-data-jpa-dynamicupdate)
|
||||||
- [Hibernate Second-Level Cache](http://www.baeldung.com/hibernate-second-level-cache)
|
- [Hibernate Second-Level Cache](http://www.baeldung.com/hibernate-second-level-cache)
|
||||||
|
|
2
pom.xml
2
pom.xml
|
@ -1460,7 +1460,7 @@
|
||||||
<assertj.version>3.21.0</assertj.version>
|
<assertj.version>3.21.0</assertj.version>
|
||||||
<hamcrest.version>2.2</hamcrest.version>
|
<hamcrest.version>2.2</hamcrest.version>
|
||||||
<hamcrest-all.version>1.3</hamcrest-all.version>
|
<hamcrest-all.version>1.3</hamcrest-all.version>
|
||||||
<mockito.version>4.1.0</mockito.version>
|
<mockito.version>4.4.0</mockito.version>
|
||||||
<byte-buddy.version>1.11.20</byte-buddy.version>
|
<byte-buddy.version>1.11.20</byte-buddy.version>
|
||||||
|
|
||||||
<!-- logging -->
|
<!-- logging -->
|
||||||
|
|
|
@ -10,9 +10,8 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-2</artifactId>
|
<artifactId>reactive-systems</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-boot-2</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -10,9 +10,8 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-2</artifactId>
|
<artifactId>reactive-systems</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-boot-2</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -10,8 +10,9 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-modules</artifactId>
|
<artifactId>parent-boot-2</artifactId>
|
||||||
<version>1.0.0-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../parent-boot-2</relativePath>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|
|
@ -10,9 +10,8 @@
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>com.baeldung</groupId>
|
<groupId>com.baeldung</groupId>
|
||||||
<artifactId>parent-boot-2</artifactId>
|
<artifactId>reactive-systems</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<relativePath>../../parent-boot-2</relativePath>
|
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -37,10 +37,6 @@
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.hibernate</groupId>
|
|
||||||
<artifactId>hibernate-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- SpringDoc -->
|
<!-- SpringDoc -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springdoc</groupId>
|
<groupId>org.springdoc</groupId>
|
||||||
|
@ -63,21 +59,6 @@
|
||||||
<artifactId>spring-restdocs-restassured</artifactId>
|
<artifactId>spring-restdocs-restassured</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!--kotlin dependencies -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springdoc</groupId>
|
|
||||||
<artifactId>springdoc-openapi-kotlin</artifactId>
|
|
||||||
<version>${springdoc.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-stdlib-jdk8</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-reflect</artifactId>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
@ -109,41 +90,6 @@
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
<!-- kotlin -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>kotlin-maven-plugin</artifactId>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
<configuration>
|
|
||||||
<compilerPlugins>
|
|
||||||
<plugin>spring</plugin>
|
|
||||||
</compilerPlugins>
|
|
||||||
<jvmTarget>${java.version}</jvmTarget>
|
|
||||||
</configuration>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>compile</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
<execution>
|
|
||||||
<id>test-compile</id>
|
|
||||||
<phase>test-compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>test-compile</goal>
|
|
||||||
</goals>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.jetbrains.kotlin</groupId>
|
|
||||||
<artifactId>kotlin-maven-allopen</artifactId>
|
|
||||||
<version>${kotlin.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
</plugins>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
|
@ -208,7 +154,6 @@
|
||||||
<properties>
|
<properties>
|
||||||
<springdoc.version>1.6.4</springdoc.version>
|
<springdoc.version>1.6.4</springdoc.version>
|
||||||
<asciidoctor-plugin.version>1.5.6</asciidoctor-plugin.version>
|
<asciidoctor-plugin.version>1.5.6</asciidoctor-plugin.version>
|
||||||
<kotlin.version>1.6.0</kotlin.version>
|
|
||||||
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
|
<snippetsDirectory>${project.build.directory}/generated-snippets</snippetsDirectory>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,8 @@ public class FooController {
|
||||||
public ResponseEntity<Foo> getFooById(@PathVariable("id") Long id) {
|
public ResponseEntity<Foo> getFooById(@PathVariable("id") Long id) {
|
||||||
|
|
||||||
Optional<Foo> foo = repository.findById(id);
|
Optional<Foo> foo = repository.findById(id);
|
||||||
return foo.isPresent() ? new ResponseEntity<>(foo.get(), HttpStatus.OK) : new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
return foo.map(value -> new ResponseEntity<>(value, HttpStatus.OK))
|
||||||
|
.orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PostMapping
|
@PostMapping
|
||||||
|
@ -70,7 +71,7 @@ public class FooController {
|
||||||
|
|
||||||
@PutMapping("/{id}")
|
@PutMapping("/{id}")
|
||||||
public ResponseEntity<Foo> updateFoo(@PathVariable("id") long id, @RequestBody Foo foo) {
|
public ResponseEntity<Foo> updateFoo(@PathVariable("id") long id, @RequestBody Foo foo) {
|
||||||
boolean isFooPresent = repository.existsById(Long.valueOf(id));
|
boolean isFooPresent = repository.existsById(id);
|
||||||
|
|
||||||
if (!isFooPresent) {
|
if (!isFooPresent) {
|
||||||
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
### Relevant Articles:
|
||||||
|
|
||||||
|
- [Set List of Objects in Swagger API Response](https://www.baeldung.com/java-swagger-set-list-response)
|
|
@ -7,10 +7,7 @@
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
|
||||||
<logger name="org.springframework" level="DEBUG" />
|
<root level="WARN">
|
||||||
<logger name="org.springframework.transaction" level="WARN" />
|
|
||||||
|
|
||||||
<root level="INFO">
|
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
</root>
|
</root>
|
||||||
</configuration>
|
</configuration>
|
|
@ -1,6 +1,32 @@
|
||||||
package com.baeldung.restdocopenapi.restdoc;
|
package com.baeldung.restdocopenapi.restdoc;
|
||||||
|
|
||||||
|
import com.baeldung.restdocopenapi.Foo;
|
||||||
|
import com.baeldung.restdocopenapi.FooController;
|
||||||
|
import com.baeldung.restdocopenapi.FooRepository;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.hateoas.MediaTypes;
|
||||||
|
import org.springframework.restdocs.RestDocumentationContextProvider;
|
||||||
|
import org.springframework.restdocs.RestDocumentationExtension;
|
||||||
|
import org.springframework.restdocs.constraints.ConstraintDescriptions;
|
||||||
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||||
|
import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static java.util.Collections.singletonList;
|
||||||
import static org.hamcrest.Matchers.containsString;
|
import static org.hamcrest.Matchers.containsString;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
|
||||||
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
|
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
|
||||||
|
@ -15,61 +41,47 @@ import static org.springframework.restdocs.payload.PayloadDocumentation.requestF
|
||||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||||
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
|
||||||
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
|
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||||
import static org.springframework.util.StringUtils.collectionToDelimitedString;
|
import static org.springframework.util.StringUtils.collectionToDelimitedString;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.hateoas.MediaTypes;
|
|
||||||
import org.springframework.restdocs.RestDocumentationContextProvider;
|
|
||||||
import org.springframework.restdocs.RestDocumentationExtension;
|
|
||||||
import org.springframework.restdocs.constraints.ConstraintDescriptions;
|
|
||||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
|
||||||
import org.springframework.test.web.servlet.MockMvc;
|
|
||||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
|
||||||
import org.springframework.web.context.WebApplicationContext;
|
|
||||||
|
|
||||||
import com.baeldung.restdocopenapi.Application;
|
|
||||||
import com.baeldung.restdocopenapi.Foo;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
@ExtendWith({ RestDocumentationExtension.class, SpringExtension.class })
|
@ExtendWith({ RestDocumentationExtension.class, SpringExtension.class })
|
||||||
@SpringBootTest(classes = Application.class)
|
@WebMvcTest(FooController.class)
|
||||||
public class SpringRestDocsUnitTest {
|
class SpringRestDocsUnitTest {
|
||||||
|
|
||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private FooRepository fooRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ObjectMapper objectMapper;
|
private ObjectMapper objectMapper;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setup(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
|
void setup(WebApplicationContext webApplicationContext, RestDocumentationContextProvider restDocumentation) {
|
||||||
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
|
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
|
||||||
.apply(documentationConfiguration(restDocumentation))
|
.apply(documentationConfiguration(restDocumentation))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenGetFoo_thenSuccessful() throws Exception {
|
void whenGetAllFoo_thenSuccessful() throws Exception {
|
||||||
|
when(fooRepository.findAll())
|
||||||
|
.thenReturn(singletonList(new Foo(1, "Foo 1", "Foo 1")));
|
||||||
|
|
||||||
this.mockMvc.perform(get("/foo"))
|
this.mockMvc.perform(get("/foo"))
|
||||||
.andDo(print())
|
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andExpect(content().string(containsString("Foo 1")))
|
.andExpect(content().string(containsString("Foo 1")))
|
||||||
.andDo(document("getAllFoos"));
|
.andDo(document("getAllFoos"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenGetFooById_thenSuccessful() throws Exception {
|
void whenGetFooById_thenSuccessful() throws Exception {
|
||||||
ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class);
|
ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class);
|
||||||
|
|
||||||
|
when(fooRepository.findById(1L))
|
||||||
|
.thenReturn(Optional.of(new Foo(1, "title", "body")));
|
||||||
|
|
||||||
this.mockMvc.perform(get("/foo/{id}", 1))
|
this.mockMvc.perform(get("/foo/{id}", 1))
|
||||||
.andExpect(status().isOk())
|
.andExpect(status().isOk())
|
||||||
.andDo(document("getAFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()),
|
.andDo(document("getAFoo", preprocessRequest(prettyPrint()), preprocessResponse(prettyPrint()),
|
||||||
|
@ -79,7 +91,7 @@ public class SpringRestDocsUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenPostFoo_thenSuccessful() throws Exception {
|
void whenPostFoo_thenSuccessful() throws Exception {
|
||||||
Map<String, Object> foo = new HashMap<>();
|
Map<String, Object> foo = new HashMap<>();
|
||||||
foo.put("id", 4L);
|
foo.put("id", 4L);
|
||||||
foo.put("title", "New Foo");
|
foo.put("title", "New Foo");
|
||||||
|
@ -93,14 +105,18 @@ public class SpringRestDocsUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenDeleteFoo_thenSuccessful() throws Exception {
|
void whenDeleteFoo_thenSuccessful() throws Exception {
|
||||||
this.mockMvc.perform(delete("/foo/{id}", 2))
|
this.mockMvc.perform(delete("/foo/{id}", 2))
|
||||||
.andExpect(status().isNoContent())
|
.andExpect(status().isNoContent())
|
||||||
.andDo(document("deleteFoo", pathParameters(parameterWithName("id").description("The id of the foo to delete"))));
|
.andDo(document("deleteFoo", pathParameters(parameterWithName("id").description("The id of the foo to delete"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenUpdateFoo_thenSuccessful() throws Exception {
|
void whenUpdateFoo_thenSuccessful() throws Exception {
|
||||||
|
|
||||||
|
when(fooRepository.existsById(3L)).thenReturn(true);
|
||||||
|
when(fooRepository.save(any(Foo.class)))
|
||||||
|
.thenReturn(new Foo(3, "Updated Foo", "Body of updated Foo"));
|
||||||
|
|
||||||
ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class);
|
ConstraintDescriptions desc = new ConstraintDescriptions(Foo.class);
|
||||||
|
|
||||||
|
@ -115,6 +131,4 @@ public class SpringRestDocsUnitTest {
|
||||||
responseFields(fieldWithPath("id").description("The id of the updated foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")),
|
responseFields(fieldWithPath("id").description("The id of the updated foo" + collectionToDelimitedString(desc.descriptionsForProperty("id"), ". ")),
|
||||||
fieldWithPath("title").description("The title of the updated foo"), fieldWithPath("body").description("The body of the updated foo"))));
|
fieldWithPath("title").description("The title of the updated foo"), fieldWithPath("body").description("The body of the updated foo"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
package com.baeldung.springdoc;
|
package com.baeldung.springdoc;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@ExtendWith(SpringExtension.class)
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class SpringContextTest {
|
class SpringContextTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue