You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2018/09/14 12:36:59 UTC
svn commit: r1840917 - in /tomcat/trunk: java/org/apache/catalina/users/
webapps/docs/
Author: markt
Date: Fri Sep 14 12:36:58 2018
New Revision: 1840917
URL: http://svn.apache.org/viewvc?rev=1840917&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58590
Monitor the source for a MemoryUserdatabase (typically tomcat-users.xml) and re-load it it a change is detected.
Modified:
tomcat/trunk/java/org/apache/catalina/users/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java
tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabaseFactory.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/jndi-resources-howto.xml
Modified: tomcat/trunk/java/org/apache/catalina/users/LocalStrings.properties
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/users/LocalStrings.properties?rev=1840917&r1=1840916&r2=1840917&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/users/LocalStrings.properties [UTF-8] (original)
+++ tomcat/trunk/java/org/apache/catalina/users/LocalStrings.properties [UTF-8] Fri Sep 14 12:36:58 2018
@@ -20,6 +20,8 @@ memoryUserDatabase.nullGroup=Null or zer
memoryUserDatabase.nullRole=Null or zero length role name specified. The role will be ignored.
memoryUserDatabase.nullUser=Null or zero length user name specified. The user will be ignored.
memoryUserDatabase.readOnly=User database has been configured to be read only. Changes cannot be saved
+memoryUserDatabase.reload=Reloading memory user database [{0}] from updated source [{1}]
+memoryUserDatabase.reloadError=Error reloading memory user database [{0}] from updated source [{1}]
memoryUserDatabase.renameOld=Cannot rename original file to [{0}]
memoryUserDatabase.renameNew=Cannot rename new file to [{0}]
memoryUserDatabase.restoreOrig=Cannot restore [{0} to original file
Modified: tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java?rev=1840917&r1=1840916&r2=1840917&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java (original)
+++ tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabase.java Fri Sep 14 12:36:58 2018
@@ -22,6 +22,9 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
@@ -148,6 +151,9 @@ public class MemoryUserDatabase implemen
private final Lock readLock = dbLock.readLock();
private final Lock writeLock = dbLock.writeLock();
+ private volatile long lastModified = 0;
+ private boolean watchSource = true;
+
// ------------------------------------------------------------- Properties
@@ -165,6 +171,7 @@ public class MemoryUserDatabase implemen
}
+
/**
* @return the unique global identifier of this user database.
*/
@@ -212,6 +219,17 @@ public class MemoryUserDatabase implemen
}
+ public boolean getWatchSource() {
+ return watchSource;
+ }
+
+
+
+ public void setWatchSource(boolean watchSource) {
+ this.watchSource = watchSource;
+ }
+
+
/**
* @return the set of {@link Role}s defined in this user database.
*/
@@ -406,7 +424,13 @@ public class MemoryUserDatabase implemen
roles.clear();
String pathName = getPathname();
- try (InputStream is = ConfigFileLoader.getInputStream(getPathname())) {
+ URI uri = ConfigFileLoader.getURI(pathName);
+ URL url = uri.toURL();
+ URLConnection uConn = url.openConnection();
+
+ try (InputStream is = uConn.getInputStream()) {
+ this.lastModified = uConn.getLastModified();
+
// Construct a digester to read the XML input file
Digester digester = new Digester();
try {
@@ -538,21 +562,21 @@ public class MemoryUserDatabase implemen
fileNew = new File(System.getProperty(Globals.CATALINA_BASE_PROP), pathnameNew);
}
- try (FileOutputStream fos = new FileOutputStream(fileNew);
- OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
- PrintWriter writer = new PrintWriter(osw)) {
-
- // Print the file prolog
- writer.println("<?xml version='1.0' encoding='utf-8'?>");
- writer.println("<tomcat-users xmlns=\"http://tomcat.apache.org/xml\"");
- writer.print(" ");
- writer.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
- writer.print(" ");
- writer.println("xsi:schemaLocation=\"http://tomcat.apache.org/xml tomcat-users.xsd\"");
- writer.println(" version=\"1.0\">");
+ writeLock.lock();
+ try {
+ try (FileOutputStream fos = new FileOutputStream(fileNew);
+ OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
+ PrintWriter writer = new PrintWriter(osw)) {
+
+ // Print the file prolog
+ writer.println("<?xml version='1.0' encoding='utf-8'?>");
+ writer.println("<tomcat-users xmlns=\"http://tomcat.apache.org/xml\"");
+ writer.print(" ");
+ writer.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
+ writer.print(" ");
+ writer.println("xsi:schemaLocation=\"http://tomcat.apache.org/xml tomcat-users.xsd\"");
+ writer.println(" version=\"1.0\">");
- writeLock.lock();
- try {
// Print entries for each defined role, group, and user
Iterator<?> values = null;
values = getRoles();
@@ -570,23 +594,24 @@ public class MemoryUserDatabase implemen
writer.print(" ");
writer.println(((MemoryUser) values.next()).toXml());
}
- } finally {
- writeLock.unlock();
- }
- // Print the file epilog
- writer.println("</tomcat-users>");
+ // Print the file epilog
+ writer.println("</tomcat-users>");
- // Check for errors that occurred while printing
- if (writer.checkError()) {
- throw new IOException(sm.getString("memoryUserDatabase.writeException",
- fileNew.getAbsolutePath()));
- }
- } catch (IOException e) {
- if (fileNew.exists() && !fileNew.delete()) {
- log.warn(sm.getString("memoryUserDatabase.fileDelete", fileNew));
+ // Check for errors that occurred while printing
+ if (writer.checkError()) {
+ throw new IOException(sm.getString("memoryUserDatabase.writeException",
+ fileNew.getAbsolutePath()));
+ }
+ } catch (IOException e) {
+ if (fileNew.exists() && !fileNew.delete()) {
+ log.warn(sm.getString("memoryUserDatabase.fileDelete", fileNew));
+ }
+ throw e;
}
- throw e;
+ this.lastModified = fileNew.lastModified();
+ } finally {
+ writeLock.unlock();
}
// Perform the required renames to permanently save this file
@@ -621,6 +646,34 @@ public class MemoryUserDatabase implemen
}
}
+
+ @Override
+ public void backgroundProcess() {
+ if (!watchSource) {
+ return;
+ }
+
+ URI uri = ConfigFileLoader.getURI(getPathname());
+ try {
+ URL url = uri.toURL();
+ URLConnection uConn = url.openConnection();
+
+ if (this.lastModified != uConn.getLastModified()) {
+ writeLock.lock();
+ try {
+ if (this.lastModified != uConn.getLastModified()) {
+ log.info(sm.getString("memoryUserDatabase.reload", id, uri));
+ open();
+ }
+ } finally {
+ writeLock.unlock();
+ }
+ }
+ } catch (Exception ioe) {
+ log.error(sm.getString("memoryUserDatabase.reloadError", id, uri), ioe);
+ }
+ }
+
/**
* Return a String representation of this UserDatabase.
Modified: tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabaseFactory.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabaseFactory.java?rev=1840917&r1=1840916&r2=1840917&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabaseFactory.java (original)
+++ tomcat/trunk/java/org/apache/catalina/users/MemoryUserDatabaseFactory.java Fri Sep 14 12:36:58 2018
@@ -98,6 +98,11 @@ public class MemoryUserDatabaseFactory i
database.setReadonly(Boolean.parseBoolean(ra.getContent().toString()));
}
+ ra = ref.get("watchSource");
+ if (ra != null) {
+ database.setWatchSource(Boolean.parseBoolean(ra.getContent().toString()));
+ }
+
// Return the configured database instance
database.open();
// Don't try something we know won't work
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1840917&r1=1840916&r2=1840917&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Fri Sep 14 12:36:58 2018
@@ -48,6 +48,13 @@
<subsection name="Catalina">
<changelog>
<add>
+ <bug>58590</bug>: Add the ability for a UserDatabase to monitor the
+ backing XML file for changes and reload the source file if a change in
+ the last modified time is detected. This is enabled by default meaning
+ that changes to <code>$CATALINA_BASE/conf/tomcat-users.xml</code> will
+ now take effect a short time after the file is saved. (markt)
+ </add>
+ <add>
<bug>61692</bug>: Add the ability to control which HTTP methods are
handled by the CGI Servlet via a new initialization parameter
<code>cgiMethods</code>. (markt)
Modified: tomcat/trunk/webapps/docs/jndi-resources-howto.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/jndi-resources-howto.xml?rev=1840917&r1=1840916&r2=1840917&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/jndi-resources-howto.xml (original)
+++ tomcat/trunk/webapps/docs/jndi-resources-howto.xml Fri Sep 14 12:36:58 2018
@@ -482,6 +482,12 @@ public class MyBean2 {
is running as. Ensure that these are appropriate to maintain the security
of your installation.</p>
+ <p>If referenced in a Realm, the UserDatabse will, by default, monitor
+ <code>pathname</code> for changes and reload the file if a change in the
+ last modified time is observed. This can be disabled by setting the
+ <code>watchSource</code> attribute to <code>false</code>.
+ </p>
+
<h5>3. Configure the Realm</h5>
<p>Configure a UserDatabase Realm to use this resource as described in the
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org