Skip to content

Commit

Permalink
Missed Events Playback on re-connect
Browse files Browse the repository at this point in the history
The missed events playback manager is now able to:

- maintain a last known alive timestamp of events that were received by the
Gerrit Server connection.
- Upon re-connect, a request is made to the Gerrit Events-Log plugin installed on the Gerrit
 Server to determine which events may have been missed while the connection was down.
- The events are then added to the Gerrit Trigger event queue to be processed.

This feature is only enabled if:

- The REST api is configured.
- The Gerrit Events-log plugin is installed on the Gerrit Server
-- Please see https://gerrit.googlesource.com/plugins/events-log/

[JENKINS-23871]

Change-Id: I1cfacad309885b88d23f8925d164a6aa427af764
  • Loading branch information
Scott Hebert authored and scoheb committed May 11, 2015
1 parent a9de653 commit 13b4cc2
Show file tree
Hide file tree
Showing 16 changed files with 2,023 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -16,3 +16,4 @@ generated-sources
.idea
hostkey.ser
*.xml~
/eclipse-classes
6 changes: 6 additions & 0 deletions pom.xml
Expand Up @@ -150,6 +150,12 @@
<artifactId>guava</artifactId>
<version>11.0.1</version>
</dependency>
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock</artifactId>
<version>1.51</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
Expand Down
Expand Up @@ -111,6 +111,7 @@
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.UnreviewedPatchesListener;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.GerritTrigger;
import com.sonyericsson.hudson.plugins.gerrit.trigger.hudsontrigger.data.GerritSlave;
import com.sonyericsson.hudson.plugins.gerrit.trigger.playback.GerritMissedEventsPlaybackManager;
import com.sonyericsson.hudson.plugins.gerrit.trigger.version.GerritVersionChecker;

/**
Expand Down Expand Up @@ -152,13 +153,22 @@ public class GerritServer implements Describable<GerritServer>, Action {
private transient UnreviewedPatchesListener unreviewedPatchesListener;
private IGerritHudsonTriggerConfig config;
private transient GerritConnectionListener gerritConnectionListener;
private transient GerritMissedEventsPlaybackManager missedEventsPlaybackManager;

@Override
public DescriptorImpl getDescriptor() {
return Hudson.getInstance().getDescriptorByType(DescriptorImpl.class);
}

/**
* Returns the Missed Events playback manager.
* @return GerritMissedEventsPlaybackManager
*/
public GerritMissedEventsPlaybackManager getMissedEventsPlaybackManager() {
return missedEventsPlaybackManager;
}

/**
* Convenience method for jelly to get url of the server list's page relative to root.
* @link {@link GerritManagement#getUrlName()}.
*
Expand Down Expand Up @@ -391,6 +401,10 @@ public void start() {
config.setCategories(categories);
gerritEventManager = PluginImpl.getHandler_();

if (missedEventsPlaybackManager == null) {
missedEventsPlaybackManager = new GerritMissedEventsPlaybackManager(name);
}

initializeConnectionListener();

projectListUpdater = new GerritProjectListUpdater(name);
Expand All @@ -399,6 +413,10 @@ public void start() {
//Starts unreviewed patches listener
unreviewedPatchesListener = new UnreviewedPatchesListener(name);

if (missedEventsPlaybackManager.isSupported()) {
addListener((GerritEventListener)missedEventsPlaybackManager);
}

logger.info(name + " started");
started = true;
}
Expand Down Expand Up @@ -435,6 +453,10 @@ public void stop() {
unreviewedPatchesListener = null;
}

if (missedEventsPlaybackManager != null) {
missedEventsPlaybackManager.shutdown();
}

if (gerritConnection != null) {
gerritConnection.shutdown(false);
gerritConnection = null;
Expand Down Expand Up @@ -502,6 +524,10 @@ public synchronized void startConnection() {
gerritConnection.setHandler(gerritEventManager);
gerritConnection.addListener(gerritConnectionListener);
gerritConnection.addListener(projectListUpdater);
if (missedEventsPlaybackManager == null) {
missedEventsPlaybackManager = new GerritMissedEventsPlaybackManager(name);
}
gerritConnection.addListener(missedEventsPlaybackManager);
gerritConnection.start();
} else {
logger.warn("Already started!");
Expand All @@ -517,6 +543,7 @@ public synchronized void stopConnection() {
if (gerritConnection != null) {
gerritConnection.shutdown(true);
gerritConnection.removeListener(gerritConnectionListener);
gerritConnection.removeListener(missedEventsPlaybackManager);
gerritConnection = null;
gerritEventManager.setIgnoreEMail(name, null);
} else {
Expand Down Expand Up @@ -1069,6 +1096,19 @@ public boolean isGerritSnapshotVersion() {
return false;
}

/**
* If Gerrit Missed Events Playback is supported.
*
* @return true if so, false otherwise.
*/
@JavaScriptMethod
public boolean isGerritMissedEventsSupported() {
if (gerritConnectionListener.isConnected()) {
return missedEventsPlaybackManager.isSupported();
}
return false;
}

/**
* If server with features disabled due to old Gerrit version.
*
Expand Down
@@ -0,0 +1,81 @@
/*
* The MIT License
*
* Copyright (c) 2014 Ericsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/

package com.sonyericsson.hudson.plugins.gerrit.trigger.playback;

import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* This class holds events that were processed by the MissedEventPlaybackManager
* for the most recent timestamp.
*
* For example, if 3 events were received at t1, they would be present in the Event Slice.
* However, if another event is processed at t2, then the Event Slice would evict the previous
* events and only keep the new event at t2.
*
* Created by scott.hebert@ericsson.com on 12/12/14.
*/
public class EventTimeSlice {

private long timeSlice;
/**
* events to persist.
*/
protected List<GerritTriggeredEvent> events = Collections.synchronizedList(new ArrayList<GerritTriggeredEvent>());

/**
*
* @param ts Time slice in ms to hold events for.
*/
public EventTimeSlice(long ts) {
this.timeSlice = ts;
}

/**
* Get the time slice in ms.
* @return this time slice
*/
public long getTimeSlice() {
return timeSlice;
}
/**
* Add an event to the list.
* @param evt Event to be persisted.
*/
public void addEvent(GerritTriggeredEvent evt) {
events.add(evt);
}

/**
* get the events for this time slice.
* @return events that pertain to the time slice.
*/
public List<GerritTriggeredEvent> getEvents() {
return events;
}
}

0 comments on commit 13b4cc2

Please sign in to comment.