From 147d3b3d454b56a3931cccb9d1a101cdfaf8b739 Mon Sep 17 00:00:00 2001 From: Khai Do Date: Tue, 15 Jan 2013 17:09:03 -0800 Subject: [PATCH] setup gearman workers Added gearman executor and management workers. It's all plumbed thru and started from jenkins config page. Change-Id: I58a7a150e9ba4748bd61254ed9328a1b9f28c3b9 --- bsd.txt | 31 +++++++ .../plugins/gearman/AbstractWorkerThread.java | 1 + .../gearman/CustomGearmanFunctionFactory.java | 89 +++++++++++++++++++ .../hudson/plugins/gearman/GearmanPlugin.java | 14 ++- .../gearman/LabelAssignmentActionImpl.java | 59 ++++++++++++ .../gearman/ManagementWorkerThread.java | 8 +- .../plugins/gearman/StartJobWorker.java | 79 ++++++++++++++++ .../hudson/plugins/gearman/StopJobWorker.java | 53 +++++++++++ 8 files changed, 321 insertions(+), 13 deletions(-) create mode 100644 bsd.txt create mode 100644 src/main/java/hudson/plugins/gearman/CustomGearmanFunctionFactory.java create mode 100644 src/main/java/hudson/plugins/gearman/LabelAssignmentActionImpl.java create mode 100644 src/main/java/hudson/plugins/gearman/StartJobWorker.java create mode 100644 src/main/java/hudson/plugins/gearman/StopJobWorker.java diff --git a/bsd.txt b/bsd.txt new file mode 100644 index 0000000..ebbfd91 --- /dev/null +++ b/bsd.txt @@ -0,0 +1,31 @@ +Gearman Java library +Copyright (C) 2009 Eric Lambert +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + + * The names of its contributors may not be used to endorse or +promote products derived from this software without specific prior +written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java b/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java index d097c8d..3074b2e 100644 --- a/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java +++ b/src/main/java/hudson/plugins/gearman/AbstractWorkerThread.java @@ -44,6 +44,7 @@ public abstract class AbstractWorkerThread implements Runnable { private GearmanNIOJobServerConnection conn; private Thread thread; + public AbstractWorkerThread(String host, int port, String name) { this.name = name; this.host = host; diff --git a/src/main/java/hudson/plugins/gearman/CustomGearmanFunctionFactory.java b/src/main/java/hudson/plugins/gearman/CustomGearmanFunctionFactory.java new file mode 100644 index 0000000..e21f057 --- /dev/null +++ b/src/main/java/hudson/plugins/gearman/CustomGearmanFunctionFactory.java @@ -0,0 +1,89 @@ +/* + * + * Copyright 2013 Hewlett-Packard Development Company, L.P. + * + * 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. + * + */ + +/* + * This is adapted from gearman-java with the following license + * + * Copyright (C) 2009 by Eric Lambert + * Use and distribution licensed under the BSD license. See + * the bsd.txt file in the parent directory for full text. + */ + +package hudson.plugins.gearman; + +import hudson.model.Node; +import hudson.model.Project; + +import java.lang.reflect.Constructor; + +import jenkins.model.Jenkins; + +import org.gearman.common.Constants; +import org.gearman.worker.DefaultGearmanFunctionFactory; +import org.gearman.worker.GearmanFunction; +import org.slf4j.LoggerFactory; + +public class CustomGearmanFunctionFactory extends DefaultGearmanFunctionFactory { + + private final Project project; + private final Node node; + private final String theClass; + private final Jenkins jenkins; + + private static final org.slf4j.Logger LOG = LoggerFactory.getLogger( + Constants.GEARMAN_WORKER_LOGGER_NAME); + + public CustomGearmanFunctionFactory(String functionName, String className, + Project project, Node node) { + super(functionName, className); + this.theClass = className; + this.project = project; + this.node = node; + jenkins = Jenkins.getInstance(); + } + + + @Override + public GearmanFunction getFunction() { + return createFunctionInstance(theClass, project, node); + } + + + private static GearmanFunction createFunctionInstance(String className, Project project, Node node) { + + GearmanFunction f = null; + try { + + Class c = Class.forName(className); + Constructor con = c.getConstructor(new Class[]{Project.class, Node.class}); + Object o = con.newInstance(new Object[] {project, node}); + + if (o instanceof GearmanFunction) { + f = (GearmanFunction) o; + } else { + LOG.warn("Specified class " + className + + " is not a Gearman Function "); + } + } catch (Exception e) { + LOG.warn("Unable to create instance of " + + "Function: " + className, e); + } + return f; + } + +} diff --git a/src/main/java/hudson/plugins/gearman/GearmanPlugin.java b/src/main/java/hudson/plugins/gearman/GearmanPlugin.java index c103e6d..11da0d2 100644 --- a/src/main/java/hudson/plugins/gearman/GearmanPlugin.java +++ b/src/main/java/hudson/plugins/gearman/GearmanPlugin.java @@ -1,5 +1,5 @@ /* - * + * * Copyright 2013 Hewlett-Packard Development Company, L.P. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,7 +13,7 @@ * 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 hudson.plugins.gearman; @@ -91,12 +91,10 @@ public class GearmanPlugin extends Builder { private String host; // gearman server host private int port; // gearman server port private Jenkins jenkins; - public static Stack gewtHandles; // handles to - // executor - // workers - public static Stack gmwtHandles; // handles to - // management - // workers + + // handles to gearman workers + public static Stack gewtHandles; + public static Stack gmwtHandles; public DescriptorImpl() { logger.info("--- DescriptorImpl Constructor ---"); diff --git a/src/main/java/hudson/plugins/gearman/LabelAssignmentActionImpl.java b/src/main/java/hudson/plugins/gearman/LabelAssignmentActionImpl.java new file mode 100644 index 0000000..dc78e11 --- /dev/null +++ b/src/main/java/hudson/plugins/gearman/LabelAssignmentActionImpl.java @@ -0,0 +1,59 @@ +/* + * + * Copyright 2013 Hewlett-Packard Development Company, L.P. + * + * 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 hudson.plugins.gearman; + +import hudson.model.Label; +import hudson.model.labels.LabelAssignmentAction; +import hudson.model.labels.LabelAtom; +import hudson.model.queue.SubTask; + +public class LabelAssignmentActionImpl implements LabelAssignmentAction{ + + LabelAtom labelAtom; + + public LabelAssignmentActionImpl(String label){ + this.labelAtom = new LabelAtom(label); + } + + @Override + public String getIconFileName(){ + // TODO Auto-generated method stub + return null; + } + + @Override + public String getDisplayName(){ + // TODO Auto-generated method stub + return null; + } + + @Override + public String getUrlName(){ + // TODO Auto-generated method stub + return null; + } + + @Override + public Label getAssignedLabel(SubTask task){ + // TODO Auto-generated method stub + return labelAtom; + } + +} diff --git a/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java b/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java index 198f897..80b5417 100644 --- a/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java +++ b/src/main/java/hudson/plugins/gearman/ManagementWorkerThread.java @@ -18,7 +18,6 @@ package hudson.plugins.gearman; -import org.gearman.worker.DefaultGearmanFunctionFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,22 +26,21 @@ import org.slf4j.LoggerFactory; * This is used to abort/delete jenkins jobs. */ -public class ManagementWorkerThread extends AbstractWorkerThread { +public class ManagementWorkerThread extends AbstractWorkerThread{ private static final Logger logger = LoggerFactory .getLogger(AbstractWorkerThread.class); private Thread thread; - public ManagementWorkerThread(String host, int port, String name) { + public ManagementWorkerThread(String host, int port, String name){ super(host, port, name); } @Override - public void registerJobs() { + public void registerJobs(){ logger.info("----- Registering management jobs on " + name + " ----"); - } } diff --git a/src/main/java/hudson/plugins/gearman/StartJobWorker.java b/src/main/java/hudson/plugins/gearman/StartJobWorker.java new file mode 100644 index 0000000..5f1477c --- /dev/null +++ b/src/main/java/hudson/plugins/gearman/StartJobWorker.java @@ -0,0 +1,79 @@ +/* + * + * Copyright 2013 Hewlett-Packard Development Company, L.P. + * + * 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 hudson.plugins.gearman; + +import java.io.UnsupportedEncodingException; +import java.util.Map; + +import hudson.model.Cause; +import hudson.model.Node; +import hudson.model.Project; +import hudson.model.labels.LabelAssignmentAction; + +import org.gearman.client.GearmanJobResult; +import org.gearman.client.GearmanJobResultImpl; +import org.gearman.worker.AbstractGearmanFunction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +public class StartJobWorker extends AbstractGearmanFunction { + + private static final Logger logger = LoggerFactory + .getLogger(Constants.PLUGIN_EXECTUOR_LOGGER_NAME); + + Node node; + Project project; + + public StartJobWorker(Project project, Node node) { + this.project = project; + this.node = node; + } + + public GearmanJobResult executeFunction() { + logger.info("----- Registering management jobs on " + name + " ----"); + + // decode the data + String decoded = null; + try { + decoded = new String((byte[]) this.data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + Gson gson = new Gson(); + Map params = gson.fromJson(decoded, + new TypeToken>() { + }.getType()); + + // send build to node with parameters + LabelAssignmentAction laa = new LabelAssignmentActionImpl( + node.getNodeName()); + System.out.println("Sending " + getName() + " to " + node.getNodeName() + + " with build params " + params); + project.scheduleBuild2(0, new Cause.UserIdCause(), laa); + + GearmanJobResult gjr = new GearmanJobResultImpl(this.jobHandle, true, + decoded.toString().getBytes(), new byte[0], new byte[0], 0, 0); + return gjr; + } +} diff --git a/src/main/java/hudson/plugins/gearman/StopJobWorker.java b/src/main/java/hudson/plugins/gearman/StopJobWorker.java new file mode 100644 index 0000000..7c4ae62 --- /dev/null +++ b/src/main/java/hudson/plugins/gearman/StopJobWorker.java @@ -0,0 +1,53 @@ +/* + * + * Copyright 2013 Hewlett-Packard Development Company, L.P. + * + * 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 hudson.plugins.gearman; + +import java.io.UnsupportedEncodingException; + +import org.gearman.client.GearmanJobResult; +import org.gearman.client.GearmanJobResultImpl; +import org.gearman.worker.AbstractGearmanFunction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StopJobWorker extends AbstractGearmanFunction { + + private static final Logger logger = LoggerFactory + .getLogger(Constants.PLUGIN_EXECTUOR_LOGGER_NAME); + + public GearmanJobResult executeFunction() { + + String decoded = null; + + logger.info("---- Running executeFunction in " + this.getName() + + " -------"); + + try { + decoded = new String((byte[]) this.data, "UTF-8"); + } catch (UnsupportedEncodingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + GearmanJobResult gjr = new GearmanJobResultImpl(this.jobHandle, true, + decoded.toString().getBytes(), new byte[0], new byte[0], 0, 0); + return gjr; + } +}