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


Reply via email to