You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@wookie.apache.org by sc...@apache.org on 2012/08/30 14:58:40 UTC

svn commit: r1378916 - in /incubator/wookie/trunk/src: org/apache/wookie/server/ContextListener.java org/apache/wookie/updates/AutomaticUpdater.java widgetserver.properties

Author: scottbw
Date: Thu Aug 30 12:58:39 2012
New Revision: 1378916

URL: http://svn.apache.org/viewvc?rev=1378916&view=rev
Log:
Support automatic updating of widgets according to the Widget Updates spec; see WOOKIE-103

Added:
    incubator/wookie/trunk/src/org/apache/wookie/updates/AutomaticUpdater.java
Modified:
    incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java
    incubator/wookie/trunk/src/widgetserver.properties

Modified: incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java?rev=1378916&r1=1378915&r2=1378916&view=diff
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java (original)
+++ incubator/wookie/trunk/src/org/apache/wookie/server/ContextListener.java Thu Aug 30 12:58:39 2012
@@ -34,6 +34,7 @@ import org.apache.wookie.beans.util.Pers
 import org.apache.wookie.feature.Features;
 import org.apache.wookie.helpers.WidgetFactory;
 import org.apache.wookie.helpers.WidgetRuntimeHelper;
+import org.apache.wookie.updates.AutomaticUpdater;
 import org.apache.wookie.util.NewWidgetBroadcaster;
 import org.apache.wookie.util.W3CWidgetFactoryUtils;
 import org.apache.wookie.util.WgtWatcher;
@@ -144,6 +145,14 @@ public class ContextListener implements 
             } else {
                 _logger.info(localizedMessages.getString("WidgetHotDeploy.0"));
             }
+            
+            /*
+             * Schedule automatic updates
+             */
+            if (configuration.getBoolean("widget.updates.enabled", false)){
+            	new AutomaticUpdater(context, configuration.getBoolean("widget.updates.requirehttps", true), configuration.getString("widget.updates.frequency", "daily"));
+            }
+            
         } 
         catch (ConfigurationException ex) {
             _logger.error("ConfigurationException thrown: "+ ex.toString());

Added: incubator/wookie/trunk/src/org/apache/wookie/updates/AutomaticUpdater.java
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/org/apache/wookie/updates/AutomaticUpdater.java?rev=1378916&view=auto
==============================================================================
--- incubator/wookie/trunk/src/org/apache/wookie/updates/AutomaticUpdater.java (added)
+++ incubator/wookie/trunk/src/org/apache/wookie/updates/AutomaticUpdater.java Thu Aug 30 12:58:39 2012
@@ -0,0 +1,159 @@
+/*
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ */
+
+package org.apache.wookie.updates;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+import javax.servlet.ServletContext;
+
+import org.apache.log4j.Logger;
+import org.apache.wookie.beans.IWidget;
+import org.apache.wookie.beans.util.IPersistenceManager;
+import org.apache.wookie.beans.util.PersistenceManagerFactory;
+import org.apache.wookie.helpers.WidgetFactory;
+import org.apache.wookie.util.W3CWidgetFactoryUtils;
+import org.apache.wookie.w3c.W3CWidget;
+import org.apache.wookie.w3c.W3CWidgetFactory;
+import org.apache.wookie.w3c.updates.UpdateUtils;
+
+/** 
+ * Instances of this class check for new widget updates, and apply them automatically.
+ * There are two configurations - either a single-use updater, or a scheduled updater. In 
+ * each case the new AutomaticUpdater will asynchronously perform update actions in a
+ * new thread. In the case of a single-use updater, it will terminate when completed;
+ * for a scheduled updater, it will continue to check for updates according to the specified
+ * frequency (hourly, daily, weekly).
+ */
+public class AutomaticUpdater {
+
+	static Logger logger = Logger.getLogger(AutomaticUpdater.class.getName());
+
+	private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
+	
+
+	private ServletContext context;
+	private boolean onlyUseHttps = false;
+	
+
+	/**
+	 * Creates a single-use automatic updater, which executes immediately.
+	 * @param context
+	 * @param onlyUseHttps
+	 */
+	public AutomaticUpdater(ServletContext context, boolean onlyUseHttps){
+		logger.info("Automatic update scheduler starting up");
+		this.context = context;
+		this.onlyUseHttps = onlyUseHttps;
+		scheduler.execute(updater);
+	}
+
+	/**
+	 * Creates an automatic updater that executes every hour, day or week depending
+	 * on the value of the frequency parameter.
+	 * @param context
+	 * @param onlyUseHttps
+	 * @param frequency
+	 */
+	public AutomaticUpdater(ServletContext context, boolean onlyUseHttps, String frequency){
+		logger.info("Automatic update scheduler starting up");
+		this.context = context;
+		this.onlyUseHttps = onlyUseHttps;
+		
+		int interval = 1;
+		TimeUnit timeUnit = getTimeUnit(frequency);
+		if (frequency.equalsIgnoreCase("weekly")) interval = 7; 
+		scheduler.scheduleAtFixedRate(updater, 1, interval, timeUnit);
+	}
+
+	// FIXME localize messages
+	final Runnable updater = new Runnable() {
+		public void run() { 
+			try {
+				logger.info("Checking for updates");
+
+				//
+				// Check to see if we're requiring updates over HTTPS - if not output a warning
+				//
+				if (!onlyUseHttps) logger.warn("checking for updates using non-secure method");
+				
+				//
+				// Start transaction
+				//
+				IPersistenceManager persistenceManager = PersistenceManagerFactory.getPersistenceManager();
+				persistenceManager.begin();
+				
+				//
+				// Get all installed widgets
+				//
+				IWidget[] widgets = persistenceManager.findAll(IWidget.class);
+
+				//
+				// Create a W3CWidget factory for the current context
+				//
+				W3CWidgetFactory factory  = W3CWidgetFactoryUtils.createW3CWidgetFactory(context);
+
+				//
+				// Iterate over the widgets and attempt to install updates
+				//
+				for (IWidget widget: widgets){
+					try {						
+						W3CWidget updatedWidget = UpdateUtils.getUpdate(factory, widget.getIdentifier(), widget.getUpdateLocation(), widget.getVersion(), onlyUseHttps);
+						if (updatedWidget != null && persistenceManager.findById(IWidget.class, widget.getId()) != null){
+							WidgetFactory.update(updatedWidget, widget, false, null);
+							logger.info("Successfully updated "+widget.getIdentifier()+" to version "+updatedWidget.getVersion());
+						}
+						
+					} catch (Exception e) {
+						logger.warn(e.getMessage(), e);
+					}
+				}
+				
+				//
+				// Commit any changes
+				//
+				persistenceManager.commit();
+				
+			} catch (Exception e) {
+				//
+				// Log errors, as otherwise the thread will terminate silently
+				//
+				logger.error("Problem with automatic update", e);
+			} finally {
+				//
+                // close thread persistence manager
+				//
+                PersistenceManagerFactory.closePersistenceManager();	
+			}
+		}
+	};
+	
+	/*
+	 * Returns the time unit for the specified frequency; for "hourly" this
+	 * is hours; the default otherwise is days
+	 * @param name the frequency name
+	 * @return a TimeUnit applicable for the frequency
+	 */
+	private TimeUnit getTimeUnit(String name){
+		if (name.equalsIgnoreCase("hourly"))
+			return TimeUnit.HOURS;
+		return TimeUnit.DAYS;
+	}
+
+}

Modified: incubator/wookie/trunk/src/widgetserver.properties
URL: http://svn.apache.org/viewvc/incubator/wookie/trunk/src/widgetserver.properties?rev=1378916&r1=1378915&r2=1378916&view=diff
==============================================================================
--- incubator/wookie/trunk/src/widgetserver.properties (original)
+++ incubator/wookie/trunk/src/widgetserver.properties Thu Aug 30 12:58:39 2012
@@ -72,6 +72,21 @@ widget.enable.validator=false
 # The widget identifier is POSTed to the url defined in widget.import.broadcast.url
 widget.import.broadcast=false
 widget.import.broadcast.url=
+
+#######################################################################
+# Automatic updates
+#
+# To enable automatic updating of widgets, set the following to true
+widget.updates.enabled=false
+#
+# By default, updates require HTTPS for security; you can change
+# this by setting the following to false
+widget.updates.requirehttps=true
+#
+# How often updates are checked, the default is "daily" but
+# can also be set to "hourly" or "weekly".
+widget.updates.frequency=daily
+
 #######################################################################
 # Locked domains
 #
@@ -87,6 +102,7 @@ widget.import.broadcast.url=
 # *-locked.mywookie.com CNAME mywookie.com
 #
 widget.instance.lockeddomain.enabled=false
+
 #######################################################################
 # digital signature settings
 # Set this property to have Wookie check widget digital signatures when