implement build trigger
authorEugene Petrenko <eugene.petrenko@gmail.com>
Thu, 14 Jul 2011 11:58:23 +0000 (15:58 +0400)
committerEugene Petrenko <eugene.petrenko@gmail.com>
Thu, 14 Jul 2011 11:58:23 +0000 (15:58 +0400)
nuget-server/src/META-INF/build-server-plugin-nuget.xml
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/BuildStartReason.java [new file with mode: 0644]
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/NamedPackagesUpdateChecker.java [new file with mode: 0644]
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/NuGetSimpleTrigger.java
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreadedBuildTriggetFactory.java [new file with mode: 0644]
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreadedBuildTriggetFactoryImpl.java [new file with mode: 0644]
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreaedBuildTriggetPolicy.java [moved from nuget-server/src/jetbrains/buildServer/nuget/server/trigger/NuGetTriggerPolicy.java with 57% similarity]
nuget-server/src/jetbrains/buildServer/nuget/server/trigger/TriggerUpdateChecker.java [new file with mode: 0644]

index f39587144238152d40c0d867d4cd65b93922bff8..ee34dda9a755704121d26bb1d84f45dc45884751 100644 (file)
@@ -16,6 +16,9 @@
 \r
 \r
   <bean class="jetbrains.buildServer.nuget.server.exec.NuGetExecutorImpl"/>\r
+  <bean class="jetbrains.buildServer.nuget.server.exec.ListPackagesCommand"/>\r
 \r
+  <bean class="jetbrains.buildServer.nuget.server.trigger.ThreadedBuildTriggetFactoryImpl"/>\r
+  <bean class="jetbrains.buildServer.nuget.server.trigger.NamedPackagesUpdateChecker"/>\r
   <bean class="jetbrains.buildServer.nuget.server.trigger.NuGetSimpleTrigger"/>\r
 </beans>
\ No newline at end of file
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/BuildStartReason.java b/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/BuildStartReason.java
new file mode 100644 (file)
index 0000000..b63fb8f
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.trigger;\r
+\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+/**\r
+* Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+* Date: 14.07.11 15:57\r
+*/\r
+public class BuildStartReason {\r
+  private final String myReason;\r
+\r
+  public BuildStartReason(@NotNull final String reason) {\r
+    myReason = reason;\r
+  }\r
+\r
+  @NotNull\r
+  public String getReason() {\r
+    return myReason;\r
+  }\r
+}\r
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/NamedPackagesUpdateChecker.java b/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/NamedPackagesUpdateChecker.java
new file mode 100644 (file)
index 0000000..f80420b
--- /dev/null
@@ -0,0 +1,62 @@
+package jetbrains.buildServer.nuget.server.trigger;\r
+\r
+import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor;\r
+import jetbrains.buildServer.buildTriggers.BuildTriggerException;\r
+import jetbrains.buildServer.nuget.server.exec.ListPackagesCommand;\r
+import jetbrains.buildServer.nuget.server.exec.PackageInfo;\r
+import jetbrains.buildServer.serverSide.CustomDataStorage;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+import java.util.*;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 14.07.11 15:41\r
+ */\r
+public class NamedPackagesUpdateChecker implements TriggerUpdateChecker {\r
+  public static final String KEY = "hash";\r
+  private final ListPackagesCommand myCommand;\r
+\r
+  public NamedPackagesUpdateChecker(@NotNull final ListPackagesCommand command) {\r
+    myCommand = command;\r
+  }\r
+\r
+  public BuildStartReason checkChanges(@NotNull BuildTriggerDescriptor descriptor,\r
+                              @NotNull CustomDataStorage storage) throws BuildTriggerException {\r
+    final String pkgId = descriptor.getProperties().get(TriggerConstants.PACKAGE);\r
+    final String version = descriptor.getProperties().get(TriggerConstants.VERSION);\r
+    final String source = descriptor.getProperties().get(TriggerConstants.SOURCE);\r
+    Collection<PackageInfo> result = myCommand.checkForChanges(source, pkgId, version);\r
+    final String hash = serializeHashcode(result);\r
+\r
+    String oldHash = storage.getValue(KEY);\r
+    if (!hash.equals(oldHash)) {\r
+      storage.putValue(KEY, hash);\r
+      storage.flush();\r
+      return new BuildStartReason("NuGet Package " + pkgId + " updated");\r
+    }\r
+\r
+    return null;\r
+  }\r
+\r
+  private String serializeHashcode(@NotNull final Collection<PackageInfo> _packages) {\r
+    List<PackageInfo> sorted = new ArrayList<PackageInfo>(_packages);\r
+    Collections.sort(sorted, new Comparator<PackageInfo>() {\r
+      public int compare(PackageInfo o1, PackageInfo o2) {\r
+        int i;\r
+        if (0 != (i = o1.getSource().compareTo(o2.getSource()))) return i;\r
+        if (0 != (i = o1.getPackageId().compareTo(o2.getPackageId()))) return i;\r
+        if (0 != (i = o1.getVersion().compareTo(o2.getVersion()))) return i;\r
+        return 0;\r
+      }\r
+    });\r
+\r
+    StringBuilder sb = new StringBuilder();\r
+    for (PackageInfo info : sorted) {\r
+      sb.append("|s:").append(info.getSource());\r
+      sb.append("|p:").append(info.getPackageId());\r
+      sb.append("|v:").append(info.getVersion());\r
+    }\r
+    return sb.toString();\r
+  }\r
+}\r
index 8dc1568274c0040dfb527235b4f3cceaa0af035b..84a4dc941ced7bf6aa3d90e35c53541a04d18ebb 100644 (file)
@@ -1,6 +1,8 @@
 package jetbrains.buildServer.nuget.server.trigger;\r
 \r
-import jetbrains.buildServer.buildTriggers.*;\r
+import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor;\r
+import jetbrains.buildServer.buildTriggers.BuildTriggerService;\r
+import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy;\r
 import jetbrains.buildServer.serverSide.InvalidProperty;\r
 import jetbrains.buildServer.serverSide.PropertiesProcessor;\r
 import jetbrains.buildServer.util.StringUtil;\r
@@ -17,9 +19,13 @@ import java.util.Map;
  */\r
 public class NuGetSimpleTrigger extends BuildTriggerService {\r
   private final PluginDescriptor myDescriptor;\r
+  private BuildTriggeringPolicy myPolicy;\r
 \r
-  public NuGetSimpleTrigger(@NotNull final PluginDescriptor descriptor) {\r
+  public NuGetSimpleTrigger(@NotNull final PluginDescriptor descriptor,\r
+                            @NotNull final ThreadedBuildTriggetFactory factory,\r
+                            @NotNull final NamedPackagesUpdateChecker checker) {\r
     myDescriptor = descriptor;\r
+    myPolicy = factory.createTrigger(checker);\r
   }\r
 \r
   @NotNull\r
@@ -54,11 +60,7 @@ public class NuGetSimpleTrigger extends BuildTriggerService {
   @NotNull\r
   @Override\r
   public BuildTriggeringPolicy getBuildTriggeringPolicy() {\r
-    return new PolledBuildTrigger() {\r
-      @Override\r
-      public void triggerBuild(@NotNull final PolledTriggerContext context) throws BuildTriggerException {\r
-      }\r
-    };\r
+    return myPolicy;\r
   }\r
 \r
   @Override\r
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreadedBuildTriggetFactory.java b/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreadedBuildTriggetFactory.java
new file mode 100644 (file)
index 0000000..cf4db6d
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.trigger;\r
+\r
+import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+/**\r
+ * Factory for thread-based build triggers\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 14.07.11 15:25\r
+ */\r
+public interface ThreadedBuildTriggetFactory {\r
+\r
+  /**\r
+   * Creates background thread powered BuildTriggerPolicy implamentation\r
+   * for a given TriggerUpdateChecker.\r
+   * @param updateChecker checker that would be called from background thread\r
+   * @return build triggering policy\r
+   */\r
+  public BuildTriggeringPolicy createTrigger(@NotNull TriggerUpdateChecker updateChecker);\r
+\r
+}\r
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreadedBuildTriggetFactoryImpl.java b/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreadedBuildTriggetFactoryImpl.java
new file mode 100644 (file)
index 0000000..c91aa5b
--- /dev/null
@@ -0,0 +1,37 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.trigger;\r
+\r
+import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy;\r
+import jetbrains.buildServer.serverSide.executors.ExecutorServices;\r
+import org.jetbrains.annotations.NotNull;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 14.07.11 15:31\r
+ */\r
+public class ThreadedBuildTriggetFactoryImpl implements ThreadedBuildTriggetFactory{\r
+  private final ExecutorServices myExecutors;\r
+\r
+  public ThreadedBuildTriggetFactoryImpl(@NotNull final ExecutorServices executors) {\r
+    myExecutors = executors;\r
+  }\r
+\r
+  public BuildTriggeringPolicy createTrigger(@NotNull TriggerUpdateChecker updateChecker) {\r
+    return new ThreaedBuildTriggetPolicy(myExecutors.getLowPriorityExecutorService(), updateChecker);\r
+  }\r
+}\r
similarity index 57%
rename from nuget-server/src/jetbrains/buildServer/nuget/server/trigger/NuGetTriggerPolicy.java
rename to nuget-server/src/jetbrains/buildServer/nuget/server/trigger/ThreaedBuildTriggetPolicy.java
index 414796fdf591be68b5611144489fbf6d9fdf41c5..4ea20d07ce0a6b1f26a28cce5c484b65dd6387a8 100644 (file)
@@ -21,53 +21,58 @@ import jetbrains.buildServer.buildTriggers.PolledBuildTrigger;
 import jetbrains.buildServer.buildTriggers.PolledTriggerContext;\r
 import org.jetbrains.annotations.NotNull;\r
 \r
-import java.util.concurrent.*;\r
+import java.util.concurrent.Callable;\r
+import java.util.concurrent.ExecutionException;\r
+import java.util.concurrent.ExecutorService;\r
+import java.util.concurrent.Future;\r
 \r
 /**\r
  * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
  * Date: 12.07.11 23:29\r
  */\r
-public class NuGetTriggerPolicy extends PolledBuildTrigger{\r
+public class ThreaedBuildTriggetPolicy extends PolledBuildTrigger {\r
   private final ExecutorService myExecutor;\r
-  private Future<Boolean> myUpdateRequired;\r
+  private final TriggerUpdateChecker myUpdater;\r
+  private Future<BuildStartReason> myUpdateRequired;\r
 \r
-  public NuGetTriggerPolicy(@NotNull final ExecutorService executor) {\r
+  public ThreaedBuildTriggetPolicy(@NotNull final ExecutorService executor,\r
+                                   @NotNull final TriggerUpdateChecker updater) {\r
     myExecutor = executor;\r
+    myUpdater = updater;\r
   }\r
 \r
   @Override\r
   public synchronized void triggerBuild(@NotNull PolledTriggerContext context) throws BuildTriggerException {\r
     if (myUpdateRequired == null) {\r
-      myUpdateRequired = myExecutor.submit(createUpdateTask());\r
+      myUpdateRequired = myExecutor.submit(createUpdateTask(context));\r
     }\r
 \r
     if (!myUpdateRequired.isDone()) return;\r
 \r
-    Boolean result;\r
+    BuildStartReason result;\r
     try {\r
       result = myUpdateRequired.get();\r
     } catch (InterruptedException e) {\r
       return;\r
     } catch (ExecutionException e) {\r
       Throwable cause = e.getCause();\r
+      if (cause instanceof BuildTriggerException) throw (BuildTriggerException)cause;\r
       throw new BuildTriggerException(cause.getMessage(), cause);\r
     } finally {\r
       myUpdateRequired = null;\r
     }\r
 \r
-    if (Boolean.TRUE.equals(result)) {\r
-      String packageName = context.getTriggerDescriptor().getProperties().get(TriggerConstants.PACKAGE);\r
-      context.getBuildType().addToQueue("NuGet Package " + packageName + " updated");\r
+    if (result != null) {\r
+      context.getBuildType().addToQueue(result.getReason());\r
     }\r
   }\r
 \r
-  private Callable<Boolean> createUpdateTask() {\r
-    return new Callable<Boolean>() {\r
-      public Boolean call() throws Exception {\r
-        return null;\r
+  @NotNull\r
+  private Callable<BuildStartReason> createUpdateTask(@NotNull final PolledTriggerContext storage) {\r
+    return new Callable<BuildStartReason>() {\r
+      public BuildStartReason call() throws Exception {\r
+        return myUpdater.checkChanges(storage.getTriggerDescriptor(), storage.getCustomDataStorage());\r
       }\r
     };\r
   }\r
-\r
-\r
 }\r
diff --git a/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/TriggerUpdateChecker.java b/nuget-server/src/jetbrains/buildServer/nuget/server/trigger/TriggerUpdateChecker.java
new file mode 100644 (file)
index 0000000..2059d3a
--- /dev/null
@@ -0,0 +1,42 @@
+/*\r
+ * Copyright 2000-2011 JetBrains s.r.o.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+package jetbrains.buildServer.nuget.server.trigger;\r
+\r
+import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor;\r
+import jetbrains.buildServer.buildTriggers.BuildTriggerException;\r
+import jetbrains.buildServer.serverSide.CustomDataStorage;\r
+import org.jetbrains.annotations.NotNull;\r
+import org.jetbrains.annotations.Nullable;\r
+\r
+/**\r
+ * Created by Eugene Petrenko (eugene.petrenko@gmail.com)\r
+ * Date: 14.07.11 15:34\r
+ */\r
+public interface TriggerUpdateChecker {\r
+  /**\r
+   * Called from background thread to check for updates\r
+   *\r
+   * @param descriptor build trigger desciptor to check for parameters\r
+   * @param storage    trigger state\r
+   * @return null or StartReason instance to start a build\r
+   * @throws jetbrains.buildServer.buildTriggers.BuildTriggerException\r
+   *          on error\r
+   */\r
+  @Nullable\r
+  BuildStartReason checkChanges(@NotNull BuildTriggerDescriptor descriptor,\r
+                           @NotNull CustomDataStorage storage) throws BuildTriggerException;\r
+}\r