diff --git a/bubble-server/pom.xml b/bubble-server/pom.xml index ec01b872..82c2eaf3 100644 --- a/bubble-server/pom.xml +++ b/bubble-server/pom.xml @@ -398,6 +398,7 @@ META-INF/*.RSA + META-INF/maven/** aj/org/objectweb/** com/ctc/wstx/dom/** @@ -423,8 +424,18 @@ com/ctc/wstx/shaded/msv_core/verifier/** com/ctc/wstx/shaded/msv_core/writer/** com/github/jmkgreen/** + + + + + + + com/google/common/graph/AbstractBaseGraph*.classcom/google/common/graph/AbstractBaseGraph.classcom/google/common/graph/AbstractDirectedNetworkConnections*.classcom/google/common/graph/AbstractDirectedNetworkConnections.classcom/google/common/graph/AbstractGraph.classcom/google/common/graph/AbstractGraphBuilder.classcom/google/common/graph/AbstractNetwork*.classcom/google/common/graph/AbstractNetwork.classcom/google/common/graph/AbstractUndirectedNetworkConnections.classcom/google/common/graph/AbstractValueGraph*.classcom/google/common/graph/AbstractValueGraph.classcom/google/common/graph/BaseGraph.classcom/google/common/graph/DirectedGraphConnections*.classcom/google/common/graph/DirectedGraphConnections.classcom/google/common/graph/DirectedMultiNetworkConnections*.classcom/google/common/graph/DirectedMultiNetworkConnections.classcom/google/common/graph/DirectedNetworkConnections.classcom/google/common/graph/EdgesConnecting.classcom/google/common/graph/ElementOrder*.classcom/google/common/graph/ElementOrder.classcom/google/common/graph/EndpointPair*.classcom/google/common/graph/EndpointPair.classcom/google/common/graph/EndpointPairIterator*.classcom/google/common/graph/EndpointPairIterator.classcom/google/common/graph/ForwardingGraph.classcom/google/common/graph/ForwardingNetwork.classcom/google/common/graph/ForwardingValueGraph.classcom/google/common/graph/Graph.classcom/google/common/graph/GraphBuilder.classcom/google/common/graph/GraphConnections.classcom/google/common/graph/GraphConstants*.classcom/google/common/graph/GraphConstants.classcom/google/common/graph/Graphs*.classcom/google/common/graph/Graphs.classcom/google/common/graph/ImmutableGraph*.classcom/google/common/graph/ImmutableGraph.classcom/google/common/graph/ImmutableNetwork*.classcom/google/common/graph/ImmutableNetwork.classcom/google/common/graph/ImmutableValueGraph*.classcom/google/common/graph/ImmutableValueGraph.classcom/google/common/graph/IncidentEdgeSet.classcom/google/common/graph/MapIteratorCache*.classcom/google/common/graph/MapIteratorCache.classcom/google/common/graph/MapRetrievalCache*.classcom/google/common/graph/MapRetrievalCache.classcom/google/common/graph/MultiEdgesConnecting*.classcom/google/common/graph/MultiEdgesConnecting.classcom/google/common/graph/MutableGraph.classcom/google/common/graph/MutableNetwork.classcom/google/common/graph/MutableValueGraph.classcom/google/common/graph/Network.classcom/google/common/graph/NetworkBuilder.classcom/google/common/graph/NetworkConnections.classcom/google/common/graph/PredecessorsFunction.classcom/google/common/graph/StandardMutableGraph.classcom/google/common/graph/StandardMutableNetwork.classcom/google/common/graph/StandardMutableValueGraph.classcom/google/common/graph/StandardNetwork.classcom/google/common/graph/StandardValueGraph*.classcom/google/common/graph/StandardValueGraph.classcom/google/common/graph/Traverser*.classcom/google/common/graph/Traverser.classcom/google/common/graph/UndirectedGraphConnections*.classcom/google/common/graph/UndirectedGraphConnections.classcom/google/common/graph/UndirectedMultiNetworkConnections*.classcom/google/common/graph/UndirectedMultiNetworkConnections.classcom/google/common/graph/UndirectedNetworkConnections.classcom/google/common/graph/ValueGraph.classcom/google/common/graph/ValueGraphBuilder.classcom/google/common/graph/package-info.class + + com/opencsv/** + com/sun/mail/imap/** com/twilio/rest/** io/jsonwebtoken/** javax/servlet/descriptor/** @@ -446,6 +457,8 @@ org/apache/fontbox/** org/apache/pdfbox/** + + META-INF/services/org.apache.xmlbeans** com/microsoft/schemas/** diff --git a/bubble-server/src/main/java/bubble/notify/NotificationHandler_hello_from_sage.java b/bubble-server/src/main/java/bubble/notify/NotificationHandler_hello_from_sage.java index a229d906..6432318d 100644 --- a/bubble-server/src/main/java/bubble/notify/NotificationHandler_hello_from_sage.java +++ b/bubble-server/src/main/java/bubble/notify/NotificationHandler_hello_from_sage.java @@ -18,6 +18,7 @@ import bubble.service.upgrade.AppUpgradeService; import bubble.service.boot.StandardSelfNodeService; import bubble.service.cloud.StandardNetworkService; import bubble.service.notify.NotificationService; +import bubble.service.upgrade.BubbleJarUpgradeService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -35,6 +36,7 @@ public class NotificationHandler_hello_from_sage extends ReceivedNotificationHan @Autowired private BubbleNetworkDAO networkDAO; @Autowired private StandardNetworkService networkService; @Autowired private StandardSelfNodeService selfNodeService; + @Autowired private BubbleJarUpgradeService jarUpgradeService; @Autowired private AppUpgradeService appUpgradeService; @Override public void handleNotification(ReceivedNotification n) { @@ -44,10 +46,13 @@ public class NotificationHandler_hello_from_sage extends ReceivedNotificationHan // First check to see if the sage reported a new jar version available if (payloadNode.hasSageVersion()) { log.info("handleNotification: payload node has sage version: "+payloadNode.getSageVersion()); - configuration.setSageVersion(payloadNode.getSageVersion()); - - // start the app upgrade service, if not running - if (!appUpgradeService.getIsAlive() && appUpgradeService.shouldRun()) appUpgradeService.start(); + if (configuration.setSageVersion(payloadNode.getSageVersion())) { + // run the jar upgrade service + if (!jarUpgradeService.getIsAlive() && jarUpgradeService.shouldRun()) jarUpgradeService.startOrInterrupt(); + } else { + // start the app upgrade service, if not running + if (!appUpgradeService.getIsAlive() && appUpgradeService.shouldRun()) appUpgradeService.startOrInterrupt(); + } } final BubbleNode thisNode = configuration.getThisNode(); diff --git a/bubble-server/src/main/java/bubble/server/BubbleConfiguration.java b/bubble-server/src/main/java/bubble/server/BubbleConfiguration.java index c7f7e297..58e6964e 100644 --- a/bubble-server/src/main/java/bubble/server/BubbleConfiguration.java +++ b/bubble-server/src/main/java/bubble/server/BubbleConfiguration.java @@ -293,7 +293,7 @@ public class BubbleConfiguration extends PgRestServerConfiguration // For a Bubble node with a sage, this will be set in the hello_from_sage notification handler // For a Bubble without a sage, this will be set in NodeInitializerListener @Getter private BubbleVersionInfo sageVersion; - public void setSageVersion(BubbleVersionInfo version) { + public boolean setSageVersion(BubbleVersionInfo version) { sageVersion = version; final boolean isNewer = version == null ? false : isNewerVersion(getVersionInfo().getVersion(), sageVersion.getVersion()); if (!jarUpgradeAvailable && isNewer) { @@ -302,9 +302,10 @@ public class BubbleConfiguration extends PgRestServerConfiguration jarUpgradeAvailable = false; } refreshPublicSystemConfigs(); + return jarUpgradeAvailable; } public boolean hasSageVersion () { return sageVersion != null; } - @Getter private Boolean jarUpgradeAvailable = false; + @Getter private volatile Boolean jarUpgradeAvailable = false; public boolean sameVersionAsSage () { return hasSageVersion() && getSageVersion().getVersion().equals(getVersionInfo().getVersion()); diff --git a/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java b/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java index f1bd15b6..c4794993 100644 --- a/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java +++ b/bubble-server/src/main/java/bubble/service/upgrade/AppUpgradeService.java @@ -49,6 +49,7 @@ public class AppUpgradeService extends SimpleDaemon { @Autowired private BubbleAppDAO appDAO; @Autowired private RuleDriverDAO driverDAO; @Autowired private StandardRuleEngineService ruleEngine; + @Autowired private BubbleJarUpgradeService jarUpgradeService; public boolean shouldRun () { final BubbleNetwork thisNetwork = configuration.getThisNetwork(); @@ -139,7 +140,13 @@ public class AppUpgradeService extends SimpleDaemon { return; } - handleAdminUpgrades(admin, sageNode); + Boolean enabled = null; + try { + enabled = jarUpgradeService.pause(); + handleAdminUpgrades(admin, sageNode); + } finally { + if (enabled != null) jarUpgradeService.restore(enabled); + } } private void handleAdminUpgrades(Account admin, BubbleNode sageNode) { diff --git a/bubble-server/src/main/java/bubble/service/upgrade/BubbleJarUpgradeService.java b/bubble-server/src/main/java/bubble/service/upgrade/BubbleJarUpgradeService.java index ccaf0112..48577c83 100644 --- a/bubble-server/src/main/java/bubble/service/upgrade/BubbleJarUpgradeService.java +++ b/bubble-server/src/main/java/bubble/service/upgrade/BubbleJarUpgradeService.java @@ -19,10 +19,12 @@ import lombok.extern.slf4j.Slf4j; import org.cobbzilla.util.daemon.SimpleDaemon; import org.cobbzilla.wizard.cache.redis.RedisService; import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.io.File; +import java.util.concurrent.atomic.AtomicBoolean; import static bubble.ApiConstants.HOME_DIR; import static java.util.concurrent.TimeUnit.MINUTES; @@ -48,6 +50,16 @@ public class BubbleJarUpgradeService extends SimpleDaemon { @Autowired private RedisService redis; @Autowired private StandardSelfNodeService selfNodeService; + private final AtomicBoolean enabled = new AtomicBoolean(true); + public void enable() { enabled.set(true); } + public void disable() { enabled.set(false); } + public boolean pause() { + boolean b = enabled.get(); + enabled.set(false); + return b; + } + public void restore(boolean b) { enabled.set(b); } + @Getter(lazy=true) private final RedisService nodeUpgradeRequests = redis.prefixNamespace(getClass().getName()); public String registerNodeUpgrade(String nodeUuid) { @@ -58,35 +70,71 @@ public class BubbleJarUpgradeService extends SimpleDaemon { public String getNodeForKey(String key) { return getNodeUpgradeRequests().get(key); } - @Getter private final long sleepTime = MINUTES.toMillis(59); + // For a node, when to run: + // - delayed start + // - sleep just less than one hour + // - only run during one hour of the day, as measured by the local time + + @Override protected long getStartupDelay() { return MINUTES.toMillis(1); } + @Override protected boolean canInterruptSleep() { return true; } + + @Getter private final long sleepTime = MINUTES.toMillis(2); // todo: make this configurable public static final int UPGRADE_HOUR_OF_DAY = 4; @Override protected void process() { - final DateTime dateTime = new DateTime(now()); - if (dateTime.hourOfDay().get() != UPGRADE_HOUR_OF_DAY) return; + log.info("process: starting upgrade check"); + if (!shouldRun()) return; + + log.info("process: checking/upgrading bubble jar..."); + try { + upgrade(); + } catch (Exception e) { + reportError("upgrade error: " + shortError(e), e); + log.error("process: upgrade error: " + shortError(e)); + } + } + + public boolean shouldRun() { + if (!enabled.get()) { + log.warn("shouldRun: upgrades not currently enabled, returning"); + return false; + } + + if (!configuration.getJarUpgradeAvailable()) { + log.warn("shouldRun: no upgrade available, returning"); + return false; + } + + // we shouldn't really need to adjust for the timezone here, because the Bubble + // should have set the operating system timezone to be the same during ansible setup. + // but just to be safe, use the bubble's time zone here. we have it handy. + final DateTimeZone dtz = DateTimeZone.forID(configuration.getThisNetwork().getTimezone()); + final DateTime dateTime = new DateTime(now(), dtz); + final int hour = dateTime.hourOfDay().get(); + if (hour != UPGRADE_HOUR_OF_DAY) { + log.warn("shouldRun: hour of day ("+hour+") != UPGRADE_HOUR_OF_DAY ("+UPGRADE_HOUR_OF_DAY+"), returning"); + return false; + } + + // OK, it's that special hour of the day. does the admin even want updates? final Account account = accountDAO.getFirstAdmin(); - if (account == null) return; - - if (account.getAutoUpdatePolicy().jarUpdates()) { - log.info("process: automatic-upgrading bubble jar..."); - try { - upgrade(); - } catch (Exception e) { - reportError("upgrade error: " + shortError(e), e); - log.error("process: upgrade error: " + shortError(e)); - } + if (account == null || !account.getAutoUpdatePolicy().jarUpdates()) { + log.warn("shouldRun: account is null or auto-update policy does not allow jar updates"); + return false; } + log.info("shouldRun: returning true"); + return true; } // set to 'false' for faster debugging of upgrade process private static final boolean BACKUP_BEFORE_UPGRADE = true; - public synchronized void upgrade() { + public synchronized boolean upgrade() { if (!configuration.getJarUpgradeAvailable()) { - log.warn("upgrade: No upgrade available, returning"); - return; + log.warn("upgrade: no upgrade available, returning"); + return false; } final BubbleVersionInfo sageVersion = configuration.getSageVersion(); @@ -104,17 +152,18 @@ public class BubbleJarUpgradeService extends SimpleDaemon { } if (bubbleBackup.getStatus() != BackupStatus.backup_completed) { log.warn("upgrade: timeout waiting for backup to complete, status=" + bubbleBackup.getStatus()); - return; + return false; } } final File upgradeJar = new File(HOME_DIR, "upgrade.jar"); if (upgradeJar.exists()) { log.error("upgrade: jar already exists, not upgrading: "+abs(upgradeJar)); - return; + return false; } final JarUpgradeMonitor jarUpgradeMonitor = selfNodeService.getJarUpgradeMonitorBean(); jarUpgradeMonitor.downloadJar(upgradeJar, sageVersion); + return true; } } diff --git a/bubble-server/src/main/resources/META-INF/bubble/bubble.properties b/bubble-server/src/main/resources/META-INF/bubble/bubble.properties index 5348d253..d54593c0 100644 --- a/bubble-server/src/main/resources/META-INF/bubble/bubble.properties +++ b/bubble-server/src/main/resources/META-INF/bubble/bubble.properties @@ -1 +1 @@ -bubble.version=Adventure 1.4.49 +bubble.version=Adventure 1.4.47 diff --git a/utils/cobbzilla-utils b/utils/cobbzilla-utils index 356e928d..d8cb733a 160000 --- a/utils/cobbzilla-utils +++ b/utils/cobbzilla-utils @@ -1 +1 @@ -Subproject commit 356e928d6c308e5819284d37d9eb0d613e0c70ee +Subproject commit d8cb733a4dbfe2d48881ecb6446b0ed4abbc8d04