-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding build trigger for new machine added to octopus
- Loading branch information
1 parent
16a3a38
commit 4376c5e
Showing
38 changed files
with
1,806 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
30 changes: 30 additions & 0 deletions
30
...ger-server/src/main/java/com/mjrichardson/teamCity/buildTriggers/ApiMachinesResponse.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.mjrichardson.teamCity.buildTriggers; | ||
|
||
import com.mjrichardson.teamCity.buildTriggers.MachineAdded.Machine; | ||
import com.mjrichardson.teamCity.buildTriggers.MachineAdded.Machines; | ||
import org.json.simple.parser.JSONParser; | ||
import org.json.simple.parser.ParseException; | ||
|
||
import java.util.List; | ||
import java.util.Map; | ||
|
||
public class ApiMachinesResponse { | ||
public Machines machines; | ||
public String nextLink; | ||
|
||
public ApiMachinesResponse(String machinesResponse) throws ParseException { | ||
JSONParser parser = new JSONParser(); | ||
Map response = (Map) parser.parse(machinesResponse); | ||
|
||
machines = new Machines(); | ||
|
||
List items = (List) response.get("Items"); | ||
for (Object item : items) { | ||
machines.add(Machine.Parse((Map) item)); | ||
} | ||
|
||
Object nextPage = ((Map) response.get("Links")).get("Page.Next"); | ||
if (nextPage != null) | ||
nextLink = nextPage.toString(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
...er-server/src/main/java/com/mjrichardson/teamCity/buildTriggers/MachineAdded/Machine.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
package com.mjrichardson.teamCity.buildTriggers.MachineAdded; | ||
|
||
import java.util.Map; | ||
|
||
public class Machine implements Comparable<Machine> { | ||
public final String id; | ||
public final String name; | ||
|
||
public Machine(String MachineId, String version) { | ||
this.id = MachineId; | ||
this.name = version; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return id + ";" + name; | ||
} | ||
|
||
public static Machine Parse(Map item) { | ||
String id = item.get("Id").toString(); | ||
String name = item.get("Name").toString(); | ||
|
||
return new Machine(id, name); | ||
} | ||
|
||
public static Machine Parse(String pair) { | ||
if (pair == null || pair == "") { | ||
return new NullMachine(); | ||
} | ||
final Integer DONT_REMOVE_EMPTY_VALUES = -1; | ||
final String[] split = pair.split(";", DONT_REMOVE_EMPTY_VALUES); | ||
final String MachineId = split[0]; | ||
final String version = split[1]; | ||
|
||
Machine result = new Machine(MachineId, version); | ||
if (result.equals(new NullMachine())) | ||
return new NullMachine(); | ||
return result; | ||
} | ||
|
||
@Override | ||
public int compareTo(Machine o) { | ||
Integer thisId = Integer.parseInt(id.split("-")[1]); | ||
Integer otherId = Integer.parseInt(o.id.split("-")[1]); | ||
return thisId.compareTo(otherId); | ||
} | ||
|
||
@Override | ||
public boolean equals(Object obj) { | ||
if (obj == null) | ||
return false; | ||
if (obj.getClass() != Machine.class && obj.getClass() != NullMachine.class) | ||
return false; | ||
return toString().equals(obj.toString()); | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
...a/com/mjrichardson/teamCity/buildTriggers/MachineAdded/MachineAddedAsyncBuildTrigger.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.mjrichardson.teamCity.buildTriggers.MachineAdded; | ||
|
||
import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; | ||
import jetbrains.buildServer.buildTriggers.BuildTriggerException; | ||
import jetbrains.buildServer.buildTriggers.async.*; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Map; | ||
|
||
import static com.mjrichardson.teamCity.buildTriggers.OctopusBuildTriggerUtil.OCTOPUS_URL; | ||
|
||
class MachineAddedAsyncBuildTrigger implements AsyncBuildTrigger<MachineAddedSpec> { | ||
private final String displayName; | ||
private final int pollIntervalInSeconds; | ||
|
||
public MachineAddedAsyncBuildTrigger(String displayName, int pollIntervalInSeconds) { | ||
this.displayName = displayName; | ||
this.pollIntervalInSeconds = pollIntervalInSeconds; | ||
} | ||
|
||
@NotNull | ||
public BuildTriggerException makeTriggerException(@NotNull Throwable throwable) { | ||
throw new BuildTriggerException(displayName + " failed with error: " + throwable.getMessage(), throwable); | ||
} | ||
|
||
@NotNull | ||
public String getRequestorString(@NotNull MachineAddedSpec machineAddedSpec) { | ||
return machineAddedSpec.getRequestorString(); | ||
} | ||
|
||
public int getPollInterval(@NotNull AsyncTriggerParameters parameters) { | ||
return pollIntervalInSeconds; | ||
} | ||
|
||
@NotNull | ||
public CheckJob<MachineAddedSpec> createJob(@NotNull final AsyncTriggerParameters asyncTriggerParameters) throws CheckJobCreationException { | ||
return new MachineAddedCheckJob(displayName, | ||
asyncTriggerParameters.getBuildType().toString(), | ||
asyncTriggerParameters.getCustomDataStorage(), | ||
asyncTriggerParameters.getTriggerDescriptor().getProperties()); | ||
} | ||
|
||
@NotNull | ||
public CheckResult<MachineAddedSpec> createCrashOnSubmitResult(@NotNull Throwable throwable) { | ||
return MachineAddedSpecCheckResult.createThrowableResult(throwable); | ||
} | ||
|
||
public String describeTrigger(BuildTriggerDescriptor buildTriggerDescriptor) { | ||
Map<String, String> properties = buildTriggerDescriptor.getProperties(); | ||
return String.format("Wait for a new machine to be added to server %s.", | ||
properties.get(OCTOPUS_URL)); | ||
} | ||
} |
81 changes: 81 additions & 0 deletions
81
...com/mjrichardson/teamCity/buildTriggers/MachineAdded/MachineAddedBuildTriggerService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package com.mjrichardson.teamCity.buildTriggers.MachineAdded; | ||
|
||
import com.intellij.openapi.diagnostic.Logger; | ||
import com.mjrichardson.teamCity.buildTriggers.OctopusBuildTriggerUtil; | ||
import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; | ||
import jetbrains.buildServer.buildTriggers.BuildTriggerService; | ||
import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy; | ||
import jetbrains.buildServer.buildTriggers.async.AsyncBuildTrigger; | ||
import jetbrains.buildServer.buildTriggers.async.AsyncBuildTriggerFactory; | ||
import jetbrains.buildServer.serverSide.PropertiesProcessor; | ||
import jetbrains.buildServer.web.openapi.PluginDescriptor; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
public final class MachineAddedBuildTriggerService extends BuildTriggerService { | ||
@NotNull | ||
private static final Logger LOG = Logger.getInstance(MachineAddedBuildTriggerService.class.getName()); | ||
@NotNull | ||
private final PluginDescriptor myPluginDescriptor; | ||
@NotNull | ||
private final BuildTriggeringPolicy myPolicy; | ||
|
||
public MachineAddedBuildTriggerService(@NotNull final PluginDescriptor pluginDescriptor, | ||
@NotNull final AsyncBuildTriggerFactory triggerFactory) { | ||
myPluginDescriptor = pluginDescriptor; | ||
myPolicy = triggerFactory.createBuildTrigger(MachineAddedSpec.class, getAsyncBuildTrigger(), LOG, getPollInterval()); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public String getName() { | ||
return "octopusMachineAddedTrigger"; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public String getDisplayName() { | ||
return "Octopus Machine Added Trigger"; | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public String describeTrigger(@NotNull BuildTriggerDescriptor buildTriggerDescriptor) { | ||
return getBuildTrigger().describeTrigger(buildTriggerDescriptor); | ||
} | ||
|
||
@NotNull | ||
@Override | ||
public BuildTriggeringPolicy getBuildTriggeringPolicy() { | ||
return myPolicy; | ||
} | ||
|
||
@Override | ||
public PropertiesProcessor getTriggerPropertiesProcessor() { | ||
return new MachineAddedTriggerPropertiesProcessor(); | ||
} | ||
|
||
@Override | ||
public String getEditParametersUrl() { | ||
return myPluginDescriptor.getPluginResourcesPath("editOctopusMachineAddedTrigger.jsp"); | ||
} | ||
|
||
@Override | ||
public boolean isMultipleTriggersPerBuildTypeAllowed() { | ||
return true; | ||
} | ||
|
||
@NotNull | ||
private AsyncBuildTrigger<MachineAddedSpec> getAsyncBuildTrigger() { | ||
return getBuildTrigger(); | ||
} | ||
|
||
@NotNull | ||
private int getPollInterval() { | ||
return OctopusBuildTriggerUtil.getPollInterval(); | ||
} | ||
|
||
@NotNull | ||
private MachineAddedAsyncBuildTrigger getBuildTrigger() { | ||
return new MachineAddedAsyncBuildTrigger(getDisplayName(), getPollInterval()); | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
.../main/java/com/mjrichardson/teamCity/buildTriggers/MachineAdded/MachineAddedCheckJob.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package com.mjrichardson.teamCity.buildTriggers.MachineAdded; | ||
|
||
import com.intellij.openapi.diagnostic.Logger; | ||
import com.mjrichardson.teamCity.buildTriggers.OctopusBuildTriggerUtil; | ||
import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; | ||
import jetbrains.buildServer.buildTriggers.async.CheckJob; | ||
import jetbrains.buildServer.buildTriggers.async.CheckResult; | ||
import jetbrains.buildServer.serverSide.CustomDataStorage; | ||
import jetbrains.buildServer.util.StringUtil; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
import java.util.Map; | ||
|
||
import static com.mjrichardson.teamCity.buildTriggers.OctopusBuildTriggerUtil.*; | ||
|
||
class MachineAddedCheckJob implements CheckJob<MachineAddedSpec> { | ||
@NotNull | ||
private static final Logger LOG = Logger.getInstance(MachineAddedCheckJob.class.getName()); | ||
|
||
private final MachinesProviderFactory MachinesProviderFactory; | ||
private final String displayName; | ||
private final String buildType; | ||
private final CustomDataStorage dataStorage; | ||
private final Map<String, String> props; | ||
|
||
public MachineAddedCheckJob(String displayName, String buildType, CustomDataStorage dataStorage, Map<String, String> properties) { | ||
this(new MachinesProviderFactory(), displayName, buildType, dataStorage, properties); | ||
} | ||
|
||
public MachineAddedCheckJob(MachinesProviderFactory MachinesProviderFactory, String displayName, String buildType, CustomDataStorage dataStorage, Map<String, String> properties) { | ||
this.MachinesProviderFactory = MachinesProviderFactory; | ||
this.displayName = displayName; | ||
this.buildType = buildType; | ||
this.dataStorage = dataStorage; | ||
this.props = properties; | ||
} | ||
|
||
@NotNull | ||
CheckResult<MachineAddedSpec> getCheckResult(String octopusUrl, String octopusApiKey, CustomDataStorage dataStorage) { | ||
LOG.debug("Checking for new machines for on server " + octopusUrl); | ||
final String dataStorageKey = (displayName + "|" + octopusUrl).toLowerCase(); | ||
|
||
try { | ||
String oldStoredData = dataStorage.getValue(dataStorageKey); | ||
final Machines oldMachines = new Machines(oldStoredData); | ||
final Integer connectionTimeoutInMilliseconds = OctopusBuildTriggerUtil.getConnectionTimeoutInMilliseconds(); | ||
|
||
MachinesProvider provider = MachinesProviderFactory.getProvider(octopusUrl, octopusApiKey, connectionTimeoutInMilliseconds); | ||
final Machines newMachines = provider.getMachines(); | ||
|
||
//only store that one machine was added here, not multiple. | ||
//otherwise, we could inadvertently miss new machines | ||
//todo: move inside Machines class | ||
final Machine newMachine = newMachines.getNextMachine(oldMachines); | ||
final Machines trimmedMachines = new Machines(oldStoredData); | ||
trimmedMachines.add(newMachine); | ||
final String newStoredData = trimmedMachines.toString(); | ||
|
||
if (!newStoredData.equals(oldStoredData)) { | ||
dataStorage.putValue(dataStorageKey, newStoredData); | ||
|
||
//todo: see if its possible to to check the property on the context that says whether its new? | ||
//http://javadoc.jetbrains.net/teamcity/openapi/current/jetbrains/buildServer/buildTriggers/PolledTriggerContext.html#getPreviousCallTime() | ||
//do not trigger build after first adding trigger (oldMachines == null) | ||
if (oldStoredData == null) { | ||
LOG.debug("No previously known machines known for server " + octopusUrl + ": null" + " -> " + newStoredData); | ||
return MachineAddedSpecCheckResult.createEmptyResult(); | ||
} | ||
|
||
LOG.info("New Machine " + newMachine.name + " created on " + octopusUrl + ": " + oldStoredData + " -> " + newStoredData); | ||
final MachineAddedSpec MachineAddedSpec = new MachineAddedSpec(octopusUrl, newMachine.name); | ||
//todo: investigate passing multiple bits to createUpdatedResult() | ||
return MachineAddedSpecCheckResult.createUpdatedResult(MachineAddedSpec); | ||
} | ||
|
||
LOG.info("No new machines on " + octopusUrl + ": " + oldStoredData + " -> " + newStoredData); | ||
return MachineAddedSpecCheckResult.createEmptyResult(); | ||
|
||
} catch (Exception e) { | ||
return MachineAddedSpecCheckResult.createThrowableResult(e); | ||
} | ||
} | ||
|
||
@NotNull | ||
public CheckResult<MachineAddedSpec> perform() { | ||
|
||
final String octopusUrl = props.get(OCTOPUS_URL); | ||
if (StringUtil.isEmptyOrSpaces(octopusUrl)) { | ||
return MachineAddedSpecCheckResult.createErrorResult(String.format("%s settings are invalid (empty url) in build configuration %s", | ||
displayName, buildType)); | ||
} | ||
|
||
final String octopusApiKey = props.get(OCTOPUS_APIKEY); | ||
if (StringUtil.isEmptyOrSpaces(octopusApiKey)) { | ||
return MachineAddedSpecCheckResult.createErrorResult(String.format("%s settings are invalid (empty api key) in build configuration %s", | ||
displayName, buildType)); | ||
} | ||
|
||
return getCheckResult(octopusUrl, octopusApiKey, dataStorage); | ||
} | ||
|
||
public boolean allowSchedule(@NotNull BuildTriggerDescriptor buildTriggerDescriptor) { | ||
return false; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
.../src/main/java/com/mjrichardson/teamCity/buildTriggers/MachineAdded/MachineAddedSpec.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.mjrichardson.teamCity.buildTriggers.MachineAdded; | ||
|
||
import org.jetbrains.annotations.NotNull; | ||
import org.jetbrains.annotations.Nullable; | ||
|
||
class MachineAddedSpec { | ||
@NotNull | ||
private final String url; | ||
@Nullable | ||
private final String name; | ||
|
||
// MachineAddedSpec(@NotNull String url) { | ||
// this(url, null); | ||
// } | ||
|
||
MachineAddedSpec(@NotNull String url, @Nullable String name) { | ||
this.url = url; | ||
this.name = name; | ||
} | ||
|
||
public String getRequestorString() { | ||
// if (name == null) | ||
// return String.format("Machine %s added to %s", name, url); | ||
return String.format("Machine %s added to %s", name, url); | ||
} | ||
} |
Oops, something went wrong.