added create/delete job

This commit is contained in:
Adrian Cole 2012-04-24 21:07:19 -07:00
parent bf0b15aff0
commit d83ce9c154
15 changed files with 344 additions and 24 deletions

View File

@ -19,6 +19,7 @@
package org.jclouds.jenkins.v1; package org.jclouds.jenkins.v1;
import org.jclouds.jenkins.v1.features.ComputerAsyncClient; import org.jclouds.jenkins.v1.features.ComputerAsyncClient;
import org.jclouds.jenkins.v1.features.JobAsyncClient;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
/** /**
@ -31,11 +32,15 @@ import org.jclouds.rest.annotations.Delegate;
*/ */
public interface JenkinsAsyncClient { public interface JenkinsAsyncClient {
/** /**
* Provides asynchronous access to Computer features. * Provides asynchronous access to Computer features.
*/ */
@Delegate @Delegate
ComputerAsyncClient getComputerClient(); ComputerAsyncClient getComputerClient();
/**
* Provides asynchronous access to Job features.
*/
@Delegate
JobAsyncClient getJobClient();
} }

View File

@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout; import org.jclouds.concurrent.Timeout;
import org.jclouds.jenkins.v1.features.ComputerClient; import org.jclouds.jenkins.v1.features.ComputerClient;
import org.jclouds.jenkins.v1.features.JobClient;
import org.jclouds.rest.annotations.Delegate; import org.jclouds.rest.annotations.Delegate;
/** /**
@ -41,4 +42,9 @@ public interface JenkinsClient {
@Delegate @Delegate
ComputerClient getComputerClient(); ComputerClient getComputerClient();
/**
* Provides synchronous access to Job features.
*/
@Delegate
JobClient getJobClient();
} }

View File

@ -28,6 +28,8 @@ import org.jclouds.jenkins.v1.JenkinsAsyncClient;
import org.jclouds.jenkins.v1.JenkinsClient; import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.jenkins.v1.features.ComputerAsyncClient; import org.jclouds.jenkins.v1.features.ComputerAsyncClient;
import org.jclouds.jenkins.v1.features.ComputerClient; import org.jclouds.jenkins.v1.features.ComputerClient;
import org.jclouds.jenkins.v1.features.JobAsyncClient;
import org.jclouds.jenkins.v1.features.JobClient;
import org.jclouds.jenkins.v1.handlers.JenkinsErrorHandler; import org.jclouds.jenkins.v1.handlers.JenkinsErrorHandler;
import org.jclouds.rest.ConfiguresRestClient; import org.jclouds.rest.ConfiguresRestClient;
import org.jclouds.rest.config.RestClientModule; import org.jclouds.rest.config.RestClientModule;
@ -44,6 +46,7 @@ public class JenkinsRestClientModule extends RestClientModule<JenkinsClient, Jen
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder() public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>> builder()
.put(ComputerClient.class, ComputerAsyncClient.class) .put(ComputerClient.class, ComputerAsyncClient.class)
.put(JobClient.class, JobAsyncClient.class)
.build(); .build();
public JenkinsRestClientModule() { public JenkinsRestClientModule() {

View File

@ -46,19 +46,19 @@ import com.google.common.util.concurrent.ListenableFuture;
public interface ComputerAsyncClient { public interface ComputerAsyncClient {
/** /**
* @see ComputerClient#getComputerView * @see ComputerClient#getView
*/ */
@GET @GET
@Path("/computer/api/json") @Path("/computer/api/json")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
ListenableFuture<ComputerView> getComputerView(); ListenableFuture<ComputerView> getView();
/** /**
* @see ComputerClient#getComputer * @see ComputerClient#get
*/ */
@GET @GET
@Path("/computer/{displayName}/api/json") @Path("/computer/{displayName}/api/json")
@Consumes(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON)
@ExceptionParser(ReturnNullOnNotFoundOr404.class) @ExceptionParser(ReturnNullOnNotFoundOr404.class)
ListenableFuture<Computer> getComputer(@PathParam("displayName") String displayName); ListenableFuture<Computer> get(@PathParam("displayName") String displayName);
} }

View File

@ -37,12 +37,12 @@ public interface ComputerClient {
/** /**
* @return overview of all configured computers * @return overview of all configured computers
*/ */
ComputerView getComputerView(); ComputerView getView();
/** /**
* *
* @param displayName display name of the computer * @param displayName display name of the computer
* @return computer or null if not found * @return computer or null if not found
*/ */
Computer getComputer(String displayName); Computer get(String displayName);
} }

View File

@ -0,0 +1,63 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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 org.jclouds.jenkins.v1.features;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import org.jclouds.io.Payload;
import org.jclouds.jenkins.v1.filters.BasicAuthenticationUnlessAnonymous;
import org.jclouds.jenkins.v1.functions.ReturnVoidOn302Or404;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import com.google.common.util.concurrent.ListenableFuture;
/**
* Job Services
*
* @see JobClient
* @author Adrian Cole
* @see <a href="http://ci.jruby.org/computer/api/">api doc</a>
*/
@RequestFilters(BasicAuthenticationUnlessAnonymous.class)
public interface JobAsyncClient {
/**
* @see JobClient#createFromXML
*/
@POST
@Path("/createItem")
@Produces(MediaType.TEXT_XML)
ListenableFuture<Void> createFromXML(@QueryParam("name") String displayName, Payload xml);
/**
* @see JobClient#getJobView
*/
@POST
@Path("/job/{displayName}/doDelete")
@ExceptionParser(ReturnVoidOn302Or404.class)
ListenableFuture<Void> delete(@PathParam("displayName") String displayName);
}

View File

@ -0,0 +1,46 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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 org.jclouds.jenkins.v1.features;
import java.util.concurrent.TimeUnit;
import org.jclouds.concurrent.Timeout;
import org.jclouds.io.Payload;
/**
* Job Services
*
* @see JobAsyncClient
* @author Adrian Cole
* @see <a href= "http://ci.jruby.org/computer/api/" >api doc</a>
*/
@Timeout(duration = 180, timeUnit = TimeUnit.SECONDS)
public interface JobClient {
/**
* creates a job, given the payload
*
* @param displayName
* @param xml
*/
void createFromXML(String displayName, Payload xml);
void delete(String displayName);
}

View File

@ -0,0 +1,43 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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 org.jclouds.jenkins.v1.functions;
import static com.google.common.base.Predicates.equalTo;
import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;
import javax.inject.Singleton;
import com.google.common.base.Function;
import com.google.common.base.Predicates;
import com.google.common.base.Throwables;
/**
*
* @author Adrian Cole
*/
@Singleton
public class ReturnVoidOn302Or404 implements Function<Exception, Void> {
public Void apply(Exception from) {
Boolean returnVal = returnValueOnCodeOrNull(from, true, Predicates.<Integer>or(equalTo(302), equalTo(404)));
if (returnVal != null && returnVal)
return null;
throw Throwables.propagate(from);
}
}

View File

@ -53,7 +53,7 @@ public class ComputerClientExpectTest extends BaseJenkinsClientExpectTest {
JenkinsClient clientWhenServersExist = requestSendsResponse(getComputerView, getComputerViewResponse); JenkinsClient clientWhenServersExist = requestSendsResponse(getComputerView, getComputerViewResponse);
assertEquals(clientWhenServersExist.getComputerClient().getComputerView().toString(), assertEquals(clientWhenServersExist.getComputerClient().getView().toString(),
new ParseComputerViewTest().expected().toString()); new ParseComputerViewTest().expected().toString());
} }
@ -71,7 +71,7 @@ public class ComputerClientExpectTest extends BaseJenkinsClientExpectTest {
JenkinsClient clientWhenServersExist = requestSendsResponse(getComputer, getComputerResponse); JenkinsClient clientWhenServersExist = requestSendsResponse(getComputer, getComputerResponse);
assertEquals(clientWhenServersExist.getComputerClient().getComputer("Ruboto").toString(), assertEquals(clientWhenServersExist.getComputerClient().get("Ruboto").toString(),
new ParseComputerTest().expected().toString()); new ParseComputerTest().expected().toString());
} }
} }

View File

@ -34,13 +34,13 @@ import org.testng.annotations.Test;
public class ComputerClientLiveTest extends BaseJenkinsClientLiveTest { public class ComputerClientLiveTest extends BaseJenkinsClientLiveTest {
public void testGetComputerView(){ public void testGetComputerView(){
ComputerView view = getClient().getComputerView(); ComputerView view = getClient().getView();
assertNotNull(view); assertNotNull(view);
assertNotNull(view.getDisplayName()); assertNotNull(view.getDisplayName());
for (Computer computerFromView : view.getComputers()) { for (Computer computerFromView : view.getComputers()) {
assertNotNull(computerFromView.getDisplayName()); assertNotNull(computerFromView.getDisplayName());
if (!"master".equals(computerFromView.getDisplayName())) { if (!"master".equals(computerFromView.getDisplayName())) {
Computer computerFromGetRequest = getClient().getComputer(computerFromView.getDisplayName()); Computer computerFromGetRequest = getClient().get(computerFromView.getDisplayName());
assertEquals(computerFromGetRequest, computerFromView); assertEquals(computerFromGetRequest, computerFromView);
} }
} }

View File

@ -0,0 +1,83 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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 org.jclouds.jenkins.v1.features;
import java.net.URI;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.jenkins.v1.internal.BaseJenkinsClientExpectTest;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableMultimap;
/**
*
* @author Adrian Cole
*/
@Test(groups = "unit", testName = "JobClientExpectTest")
public class JobClientExpectTest extends BaseJenkinsClientExpectTest {
public void testCreateJobWhenResponseIs2xx() {
HttpRequest createJob = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("http://localhost:8080/createItem?name=blagoo"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
.payload(payloadFromResourceWithContentType("/sample_job.xml", "text/xml"))
.build();
HttpResponse createJobResponse = HttpResponse.builder().statusCode(200).build();
JenkinsClient createJobWhenCreated = requestSendsResponse(createJob, createJobResponse);
createJobWhenCreated.getJobClient().createFromXML("blagoo", payloadFromResource("/sample_job.xml"));
}
public void testDeleteJobWhenResponseIs2xx() {
HttpRequest deleteJob = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("http://localhost:8080/job/blagoo/doDelete"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
.build();
HttpResponse deleteJobResponse = HttpResponse.builder().statusCode(200).build();
JenkinsClient deleteJobWhenDeleted = requestSendsResponse(deleteJob, deleteJobResponse);
deleteJobWhenDeleted.getJobClient().delete("blagoo");
}
public void testDeleteJobWhenResponseIs404() {
HttpRequest deleteJob = HttpRequest.builder()
.method("POST")
.endpoint(URI.create("http://localhost:8080/job/blagoo/doDelete"))
.headers(ImmutableMultimap.<String, String> builder()
.put("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build())
.build();
HttpResponse deleteJobResponse = HttpResponse.builder().statusCode(404).build();
JenkinsClient deleteJobWhenDeleted = requestSendsResponse(deleteJob, deleteJobResponse);
deleteJobWhenDeleted.getJobClient().delete("blagoo");
}
}

View File

@ -0,0 +1,57 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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 org.jclouds.jenkins.v1.features;
import java.io.IOException;
import org.jclouds.io.Payloads;
import org.jclouds.jenkins.v1.internal.BaseJenkinsClientLiveTest;
import org.jclouds.util.Strings2;
import org.testng.annotations.AfterClass;
import org.testng.annotations.Test;
/**
*
* @author Adrian Cole
*/
@Test(groups = "live", testName = "JobClientLiveTest")
public class JobClientLiveTest extends BaseJenkinsClientLiveTest {
public void testCreateJob() throws IOException {
getClient().delete("blagoo");
getClient().createFromXML("blagoo",
Payloads.newPayload(Strings2.toStringAndClose(getClass().getResourceAsStream("/sample_job.xml"))));
}
@Test(dependsOnMethods = "testCreateJob")
public void testDeleteJob() {
getClient().delete("blagoo");
}
@AfterClass(groups = { "integration", "live" })
@Override
protected void tearDownContext() {
getClient().delete("blagoo");
super.tearDownContext();
}
private JobClient getClient() {
return context.getApi().getJobClient();
}
}

View File

@ -56,7 +56,7 @@ public class BasicAuthenticationUnlessAnonymousExpectTest extends BaseJenkinsCli
JenkinsClient clientWhenServersExist = requestSendsResponse(getComputerView, getComputerViewResponse); JenkinsClient clientWhenServersExist = requestSendsResponse(getComputerView, getComputerViewResponse);
assertEquals(clientWhenServersExist.getComputerClient().getComputerView().toString(), assertEquals(clientWhenServersExist.getComputerClient().getView().toString(),
new ParseComputerViewTest().expected().toString()); new ParseComputerViewTest().expected().toString());
} }
} }

View File

@ -23,8 +23,7 @@ import org.jclouds.jenkins.v1.JenkinsApiMetadata;
import org.jclouds.jenkins.v1.JenkinsAsyncClient; import org.jclouds.jenkins.v1.JenkinsAsyncClient;
import org.jclouds.jenkins.v1.JenkinsClient; import org.jclouds.jenkins.v1.JenkinsClient;
import org.jclouds.rest.RestContext; import org.jclouds.rest.RestContext;
import org.testng.annotations.AfterGroups; import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
@ -43,19 +42,13 @@ public class BaseJenkinsClientLiveTest extends BaseContextLiveTest<RestContext<J
protected RestContext<JenkinsClient, JenkinsAsyncClient> jenkinsContext; protected RestContext<JenkinsClient, JenkinsAsyncClient> jenkinsContext;
@BeforeGroups(groups = { "integration", "live" }) @BeforeClass(groups = { "integration", "live" })
@Override @Override
public void setupContext() { public void setupContext() {
super.setupContext(); super.setupContext();
jenkinsContext = context; jenkinsContext = context;
} }
@AfterGroups(groups = "live")
protected void tearDown() {
if (jenkinsContext != null)
jenkinsContext.close();
}
@Override @Override
protected TypeToken<RestContext<JenkinsClient, JenkinsAsyncClient>> contextType() { protected TypeToken<RestContext<JenkinsClient, JenkinsAsyncClient>> contextType() {
return JenkinsApiMetadata.CONTEXT_TOKEN; return JenkinsApiMetadata.CONTEXT_TOKEN;

View File

@ -0,0 +1,21 @@
<?xml version='1.0' encoding='UTF-8'?>
<project>
<actions/>
<description></description>
<keepDependencies>false</keepDependencies>
<properties/>
<scm class="hudson.scm.NullSCM"/>
<canRoam>true</canRoam>
<disabled>false</disabled>
<blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
<blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
<triggers class="vector"/>
<concurrentBuild>false</concurrentBuild>
<builders>
<hudson.tasks.Shell>
<command>echo hello</command>
</hudson.tasks.Shell>
</builders>
<publishers/>
<buildWrappers/>
</project>