Skip to content

Commit

Permalink
Merge pull request #18 from martinda/feature/build-integer-response
Browse files Browse the repository at this point in the history
Feature/build integer response
  • Loading branch information
cdancy authored May 14, 2018
2 parents 7ea4645 + 615f80f commit 961fa27
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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 com.cdancy.jenkins.rest.domain.common;

import java.util.List;

import org.jclouds.javax.annotation.Nullable;
import org.jclouds.json.SerializedNames;

import com.cdancy.jenkins.rest.JenkinsUtils;
import com.google.auto.value.AutoValue;

/**
* Integer response to be returned when an endpoint returns
* an integer.
*
* <p>When the HTTP response code is valid the `value` parameter will
* be set to the integer value while a non-valid response has the `value` set to
* null along with any potential `error` objects returned from Jenkins.
*/
@AutoValue
public abstract class IntegerResponse implements Value<Integer>, ErrorsHolder {

@SerializedNames({ "value", "errors" })
public static IntegerResponse create(@Nullable final Integer value,
final List<Error> errors) {

return new AutoValue_IntegerResponse(value,
JenkinsUtils.nullToEmpty(errors));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import static org.jclouds.http.HttpUtils.returnValueOnCodeOrNull;

import com.cdancy.jenkins.rest.domain.common.IntegerResponse;
import com.cdancy.jenkins.rest.domain.common.RequestStatus;
import com.cdancy.jenkins.rest.domain.common.Error;
import com.cdancy.jenkins.rest.domain.crumb.Crumb;
Expand Down Expand Up @@ -62,6 +63,20 @@ public Object createOrPropagate(final Throwable throwable) throws Exception {
}
}

public static final class IntegerResponseOnError implements Fallback<Object> {
@Override
public Object createOrPropagate(final Throwable throwable) throws Exception {
if (checkNotNull(throwable, "throwable") != null) {
try {
return IntegerResponse.create(null, getErrors(throwable));
} catch (JsonSyntaxException e) {
return IntegerResponse.create(null, getErrors(e));
}
}
throw propagate(throwable);
}
}

public static final class CrumbOnError implements Fallback<Object> {
@Override
public Object createOrPropagate(final Throwable throwable) throws Exception {
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/com/cdancy/jenkins/rest/features/JobsApi.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.jclouds.rest.annotations.ResponseParser;

import com.cdancy.jenkins.rest.binders.BindMapToForm;
import com.cdancy.jenkins.rest.domain.common.IntegerResponse;
import com.cdancy.jenkins.rest.domain.common.RequestStatus;
import com.cdancy.jenkins.rest.domain.job.BuildInfo;
import com.cdancy.jenkins.rest.domain.job.JobInfo;
Expand Down Expand Up @@ -137,19 +138,19 @@ boolean description(@PathParam("name") String jobName,

@Named("jobs:build")
@Path("/job/{name}/build")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Fallback(JenkinsFallbacks.IntegerResponseOnError.class)
@ResponseParser(LocationToQueueId.class)
@Consumes("application/unknown")
@POST
Integer build(@PathParam("name") String jobName);
IntegerResponse build(@PathParam("name") String jobName);

@Named("jobs:build-with-params")
@Path("/job/{name}/buildWithParameters")
@Fallback(Fallbacks.NullOnNotFoundOr404.class)
@Fallback(JenkinsFallbacks.IntegerResponseOnError.class)
@ResponseParser(LocationToQueueId.class)
@Consumes("application/unknown")
@POST
Integer buildWithParameters(@PathParam("name") String jobName,
IntegerResponse buildWithParameters(@PathParam("name") String jobName,
@BinderParam(BindMapToForm.class) Map<String, List<String>> properties);

@Named("jobs:last-build-number")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.cdancy.jenkins.rest.parsers;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -25,25 +26,31 @@
import org.jclouds.http.HttpResponse;

import com.google.common.base.Function;
import com.google.common.collect.Lists;

import com.cdancy.jenkins.rest.domain.common.Error;
import com.cdancy.jenkins.rest.domain.common.IntegerResponse;

/**
* Created by dancc on 3/11/16.
*/
@Singleton
public class LocationToQueueId implements Function<HttpResponse, Integer> {
public class LocationToQueueId implements Function<HttpResponse, IntegerResponse> {

private static final Pattern pattern = Pattern.compile("^.*/queue/item/(\\d+)/$");

public Integer apply(HttpResponse response) {
public IntegerResponse apply(HttpResponse response) {

String url = response.getFirstHeaderOrNull("Location");
if (url != null) {
Matcher matcher = pattern.matcher(url);
if (matcher.find() && matcher.groupCount() == 1) {
return Integer.valueOf(matcher.group(1));
return IntegerResponse.create(Integer.valueOf(matcher.group(1)), null);
}
}

return 0;
final Error error = Error.create(null,
"No queue item Location header could be found despite getting a valid HTTP response.",
NumberFormatException.class.getCanonicalName());
return IntegerResponse.create(null, Lists.newArrayList(error));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.testng.annotations.Test;

import com.cdancy.jenkins.rest.BaseJenkinsApiLiveTest;
import com.cdancy.jenkins.rest.domain.common.IntegerResponse;
import com.cdancy.jenkins.rest.domain.common.RequestStatus;
import com.cdancy.jenkins.rest.domain.job.BuildInfo;
import com.cdancy.jenkins.rest.domain.job.JobInfo;
Expand All @@ -38,7 +39,7 @@
@Test(groups = "live", testName = "SystemApiLiveTest", singleThreaded = true)
public class JobsApiLiveTest extends BaseJenkinsApiLiveTest {

private Integer queueId;
private IntegerResponse queueId;
private Integer buildNumber;

@Test
Expand Down Expand Up @@ -74,7 +75,8 @@ public void testLastBuildTimestampOnJobWithNoBuilds() {
public void testBuildJob() {
queueId = api().build("DevTest");
assertNotNull(queueId);
assertTrue(queueId > 0);
assertTrue(queueId.value() > 0);
assertTrue(queueId.errors().size() == 0);
}

@Test(dependsOnMethods = "testBuildJob")
Expand Down Expand Up @@ -108,7 +110,7 @@ public void testGetBuildInfo() {
BuildInfo output = api().buildInfo("DevTest", buildNumber);
assertNotNull(output);
assertTrue(output.fullDisplayName().equals("DevTest #" + buildNumber));
assertTrue(output.queueId() == queueId);
assertTrue(output.queueId() == queueId.value());
}

@Test(dependsOnMethods = "testGetBuildInfo")
Expand Down Expand Up @@ -147,9 +149,10 @@ public void testUpdateConfig() {
public void testBuildJobWithParameters() {
Map<String, List<String>> params = new HashMap<>();
params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue"));
Integer output = api().buildWithParameters("DevTest", params);
IntegerResponse output = api().buildWithParameters("DevTest", params);
assertNotNull(output);
assertTrue(output > 0);
assertTrue(output.value() > 0);
assertTrue(output.errors().size() == 0);
}

@Test(dependsOnMethods = "testBuildJobWithParameters")
Expand Down Expand Up @@ -216,8 +219,13 @@ public void testGetDescriptionNonExistentJob() {

@Test
public void testBuildNonExistentJob() {
Integer output = api().build(randomString());
assertNull(output);
IntegerResponse output = api().build(randomString());
assertNotNull(output);
assertNull(output.value());
assertTrue(output.errors().size() > 0);
assertNotNull(output.errors().get(0).context());
assertNotNull(output.errors().get(0).message());
assertTrue(output.errors().get(0).exceptionName().equals("org.jclouds.rest.ResourceNotFoundException"));
}

@Test
Expand All @@ -230,8 +238,13 @@ public void testGetBuildInfoNonExistentJob() {
public void testBuildNonExistentJobWithParams() {
Map<String, List<String>> params = new HashMap<>();
params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue"));
Integer output = api().buildWithParameters(randomString(), params);
assertNull(output);
IntegerResponse output = api().buildWithParameters(randomString(), params);
assertNotNull(output);
assertNull(output.value());
assertTrue(output.errors().size() > 0);
assertNotNull(output.errors().get(0).context());
assertNotNull(output.errors().get(0).message());
assertTrue(output.errors().get(0).exceptionName().equals("org.jclouds.rest.ResourceNotFoundException"));
}

private JobsApi api() {
Expand Down
37 changes: 27 additions & 10 deletions src/test/java/com/cdancy/jenkins/rest/features/JobsApiMockTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import com.cdancy.jenkins.rest.domain.job.JobInfo;
import com.cdancy.jenkins.rest.domain.job.ProgressiveText;
import com.cdancy.jenkins.rest.BaseJenkinsMockTest;
import com.cdancy.jenkins.rest.domain.common.IntegerResponse;
import com.cdancy.jenkins.rest.domain.common.RequestStatus;

import com.google.common.collect.Lists;
Expand Down Expand Up @@ -399,9 +400,10 @@ public void testBuildJob() throws Exception {
JenkinsApi jenkinsApi = api(server.getUrl("/"));
JobsApi api = jenkinsApi.jobsApi();
try {
Integer output = api.build("DevTest");
IntegerResponse output = api.build("DevTest");
assertNotNull(output);
assertTrue(output == 1);
assertTrue(output.value() == 1);
assertTrue(output.errors().size() == 0);
assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown");
} finally {
jenkinsApi.close();
Expand All @@ -417,9 +419,13 @@ public void testBuildJobWithNoLocationReturned() throws Exception {
JenkinsApi jenkinsApi = api(server.getUrl("/"));
JobsApi api = jenkinsApi.jobsApi();
try {
Integer output = api.build("DevTest");
IntegerResponse output = api.build("DevTest");
assertNotNull(output);
assertTrue(output == 0);
assertNull(output.value());
assertTrue(output.errors().size() == 1);
assertNull(output.errors().get(0).context());
assertTrue(output.errors().get(0).message().equals("No queue item Location header could be found despite getting a valid HTTP response."));
assertTrue(output.errors().get(0).exceptionName().equals(NumberFormatException.class.getCanonicalName()));
assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown");
} finally {
jenkinsApi.close();
Expand All @@ -434,8 +440,13 @@ public void testBuildJobNonExistentJob() throws Exception {
JenkinsApi jenkinsApi = api(server.getUrl("/"));
JobsApi api = jenkinsApi.jobsApi();
try {
Integer output = api.build("DevTest");
assertNull(output);
IntegerResponse output = api.build("DevTest");
assertNotNull(output);
assertNull(output.value());
assertTrue(output.errors().size() == 1);
assertTrue(output.errors().get(0).message().equals(""));
assertTrue(output.errors().get(0).exceptionName().equals("org.jclouds.rest.ResourceNotFoundException"));
assertNotNull(output.errors().get(0).context());
assertSentAccept(server, "POST", "/job/DevTest/build", "application/unknown");
} finally {
jenkinsApi.close();
Expand All @@ -453,9 +464,10 @@ public void testBuildJobWithParams() throws Exception {
try {
Map<String, List<String>> params = new HashMap<>();
params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue"));
Integer output = api.buildWithParameters("DevTest", params);
IntegerResponse output = api.buildWithParameters("DevTest", params);
assertNotNull(output);
assertTrue(output == 1);
assertTrue(output.value() == 1);
assertTrue(output.errors().size() == 0);
assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown");
} finally {
jenkinsApi.close();
Expand All @@ -472,8 +484,13 @@ public void testBuildJobWithParamsNonExistentJob() throws Exception {
try {
Map<String, List<String>> params = new HashMap<>();
params.put("SomeKey", Lists.newArrayList("SomeVeryNewValue"));
Integer output = api.buildWithParameters("DevTest", params);
assertNull(output);
IntegerResponse output = api.buildWithParameters("DevTest", params);
assertNotNull(output);
assertNull(output.value());
assertTrue(output.errors().size() == 1);
assertTrue(output.errors().get(0).message().equals(""));
assertTrue(output.errors().get(0).exceptionName().equals("org.jclouds.rest.ResourceNotFoundException"));
assertNotNull(output.errors().get(0).context());
assertSentAccept(server, "POST", "/job/DevTest/buildWithParameters", "application/unknown");
} finally {
jenkinsApi.close();
Expand Down
Loading

0 comments on commit 961fa27

Please sign in to comment.