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