Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-18407

Starting a job with params using REST Api doesn't return 201 http status code as stated in the documentation

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved (View Workflow)
    • Priority: Critical
    • Resolution: Fixed
    • Component/s: core
    • Labels:
    • Environment:
      Linux
    • Similar Issues:

      Description

      This bug is related to the new enhancement that was added in v1.519 for better tracking a queued job.
      When starting the job with parameters I expect to get 201 status code, but instead I'm getting 302 code which redirects me to the "Location" header url.
      See attached screenshot from the request and the response (taken by Fiddler)

        Attachments

          Activity

          amoss166 Amos Sonnenwirth created issue -
          Hide
          jmiller joe miller added a comment -

          I'm seeing strange behavior here as well. When starting a job with params via the UI, sometimes the result is a '201 CREATED' (and a blank/white page in the browser), and sometimes a 302 redirect back to the job page as in previous versions.

          Show
          jmiller joe miller added a comment - I'm seeing strange behavior here as well. When starting a job with params via the UI, sometimes the result is a '201 CREATED' (and a blank/white page in the browser), and sometimes a 302 redirect back to the job page as in previous versions.
          Hide
          kohsuke Kohsuke Kawaguchi added a comment -

          To explain what's going on, 201 gets returned when the item gets submitted in the queue, and 302 if the item was already in the queue.

          I realize that in both cases it probably makes sense to return 201, even though in the latter case, technically we haven't created any resources. Most often, the caller doesn't really care if the submission resulted in a new item in the queue or if it was already in the queue.

          Show
          kohsuke Kohsuke Kawaguchi added a comment - To explain what's going on, 201 gets returned when the item gets submitted in the queue, and 302 if the item was already in the queue. I realize that in both cases it probably makes sense to return 201, even though in the latter case, technically we haven't created any resources. Most often, the caller doesn't really care if the submission resulted in a new item in the queue or if it was already in the queue.
          kohsuke Kohsuke Kawaguchi made changes -
          Field Original Value New Value
          Assignee Kohsuke Kawaguchi [ kohsuke ]
          Hide
          scm_issue_link SCM/JIRA link daemon added a comment -

          Code changed in jenkins
          User: Kohsuke Kawaguchi
          Path:
          core/src/main/java/hudson/matrix/MatrixConfiguration.java
          core/src/main/java/hudson/matrix/listeners/MatrixBuildListener.java
          core/src/main/java/hudson/model/AbstractProject.java
          core/src/main/java/hudson/model/Queue.java
          core/src/main/java/hudson/model/queue/ScheduleResult.java
          test/src/test/groovy/hudson/model/AbstractProjectTest.groovy
          http://jenkins-ci.org/commit/jenkins/f719bd06a46b0c8f8249f5d4848db61947b920be
          Log:
          [FIXED JENKINS-18407]

          Added Queue.schedule2 to allow the caller to retrieve the existing item in the queue. AbstractProject.doBuild() changed the behavior a bit to reply 201 if the item was already found in the queue (instead of a new one created.)

          Compare: https://github.com/jenkinsci/jenkins/compare/bdfc3f715630...f719bd06a46b

          Show
          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Kohsuke Kawaguchi Path: core/src/main/java/hudson/matrix/MatrixConfiguration.java core/src/main/java/hudson/matrix/listeners/MatrixBuildListener.java core/src/main/java/hudson/model/AbstractProject.java core/src/main/java/hudson/model/Queue.java core/src/main/java/hudson/model/queue/ScheduleResult.java test/src/test/groovy/hudson/model/AbstractProjectTest.groovy http://jenkins-ci.org/commit/jenkins/f719bd06a46b0c8f8249f5d4848db61947b920be Log: [FIXED JENKINS-18407] Added Queue.schedule2 to allow the caller to retrieve the existing item in the queue. AbstractProject.doBuild() changed the behavior a bit to reply 201 if the item was already found in the queue (instead of a new one created.) Compare: https://github.com/jenkinsci/jenkins/compare/bdfc3f715630...f719bd06a46b
          scm_issue_link SCM/JIRA link daemon made changes -
          Resolution Fixed [ 1 ]
          Status Open [ 1 ] Resolved [ 5 ]
          Hide
          dogfood dogfood added a comment -

          Integrated in jenkins_main_trunk #2661

          Result = UNSTABLE

          Show
          dogfood dogfood added a comment - Integrated in jenkins_main_trunk #2661 Result = UNSTABLE
          Hide
          amoss166 Amos Sonnenwirth added a comment -

          I used the latest build (not official one) in order to test the fix, and this time I'm getting HTTP CODE 200

          I created a simple job with one string parameter and used the following code:

          import java.io.IOException;
          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          import java.util.Map.Entry;

          import org.codehaus.jackson.JsonFactory;
          import org.codehaus.jackson.JsonNode;
          import org.codehaus.jackson.JsonProcessingException;
          import org.codehaus.jackson.map.ObjectMapper;
          import org.springframework.beans.factory.InitializingBean;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.http.HttpEntity;
          import org.springframework.http.HttpHeaders;
          import org.springframework.http.HttpMethod;
          import org.springframework.http.HttpStatus;
          import org.springframework.http.MediaType;
          import org.springframework.http.ResponseEntity;
          import org.springframework.stereotype.Component;
          import org.springframework.util.LinkedMultiValueMap;
          import org.springframework.util.MultiValueMap;
          import org.springframework.web.client.RestTemplate;

          .
          .
          .
          HttpHeaders headers = new HttpHeaders();
          headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

          MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>();
          form.add("COUNT", "5");

          HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(form,headers);

          ResponseEntity<String> responce = restTemplate.exchange("http://192.168.1.126:8080/jenkins/job/test1/buildWithParameters", HttpMethod.POST, request, String.class);
          .
          .
          .

          The returned HTTP code is 200 instead of 201 (saw it on Fiddler)

          Additionally, I'm getting a json result which contains the "queueItem" section, together with other non-relevant info, I can use this "queueItem" info for tracking the job, BUT when starting few instances of the same job in parallel (each instance with different parameters), in each HTTP response I'm getting the same "queueItem" as the first one I got, although, when checking the queue the other new instance were created with different item id in the queue

          If this too complicated to understand, lets try to set a webex session or something similar (my mail: amos_son@malam.com)

          Show
          amoss166 Amos Sonnenwirth added a comment - I used the latest build (not official one) in order to test the fix, and this time I'm getting HTTP CODE 200 I created a simple job with one string parameter and used the following code: import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.codehaus.jackson.JsonFactory; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.JsonProcessingException; import org.codehaus.jackson.map.ObjectMapper; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; . . . HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>(); form.add("COUNT", "5"); HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(form,headers); ResponseEntity<String> responce = restTemplate.exchange("http://192.168.1.126:8080/jenkins/job/test1/buildWithParameters", HttpMethod.POST, request, String.class); . . . The returned HTTP code is 200 instead of 201 (saw it on Fiddler) Additionally, I'm getting a json result which contains the "queueItem" section, together with other non-relevant info, I can use this "queueItem" info for tracking the job, BUT when starting few instances of the same job in parallel (each instance with different parameters), in each HTTP response I'm getting the same "queueItem" as the first one I got, although, when checking the queue the other new instance were created with different item id in the queue If this too complicated to understand, lets try to set a webex session or something similar (my mail: amos_son@malam.com)
          amoss166 Amos Sonnenwirth made changes -
          Resolution Fixed [ 1 ]
          Status Resolved [ 5 ] Reopened [ 4 ]
          Hide
          barthelemy Barthélémy von Haller added a comment -

          I confirm that using the REST API, I get a 200 instead of a 201 when performing a build. The URL I call is :
          https://<hidden>/jenkins/job/<JOB>/buildWithParameters?module=amoreTST

          Show
          barthelemy Barthélémy von Haller added a comment - I confirm that using the REST API, I get a 200 instead of a 201 when performing a build. The URL I call is : https://<hidden>/jenkins/job/<JOB>/buildWithParameters?module=amoreTST
          Hide
          mariuszs Mariusz S added a comment - - edited

          More importantly, buildWithParameters returns 201 without Location to build queue.

          > the successful queueing will result in 201 status code with Location HTTP header pointing the URL of the item in the queue.

          Show
          mariuszs Mariusz S added a comment - - edited More importantly, buildWithParameters returns 201 without Location to build queue. > the successful queueing will result in 201 status code with Location HTTP header pointing the URL of the item in the queue.
          Hide
          jglick Jesse Glick added a comment -

          The current version of ParametersDefinitionProperty.buildWithParameters does seem to send either a 201 with redirect to a newly created or existing queue item, or a 200 with redirect to the job in case queue scheduling was refused. If you can reproduce different behavior please file a pull request with accompanying test.

          Remember that you need to either POST (with a valid crumb, if Jenkins is so configured), or (for historical compatibility) GET with a token (if one is defined), in order to schedule a build: for security reasons, GET requests may not initiate actions.

          Show
          jglick Jesse Glick added a comment - The current version of ParametersDefinitionProperty.buildWithParameters does seem to send either a 201 with redirect to a newly created or existing queue item, or a 200 with redirect to the job in case queue scheduling was refused. If you can reproduce different behavior please file a pull request with accompanying test. Remember that you need to either POST (with a valid crumb, if Jenkins is so configured), or (for historical compatibility) GET with a token (if one is defined), in order to schedule a build: for security reasons, GET requests may not initiate actions.
          jglick Jesse Glick made changes -
          Resolution Fixed [ 1 ]
          Status Reopened [ 4 ] Resolved [ 5 ]
          Hide
          scm_issue_link SCM/JIRA link daemon added a comment -

          Code changed in jenkins
          User: Jesse Glick
          Path:
          src/test/java/hudson/plugins/git/RevisionParameterActionTest.java
          http://jenkins-ci.org/commit/git-plugin/4fe33a1fa31459563b7d9e4c4c652b20bde6df4d
          Log:
          Commenting out assertions that fail in 1.521+ due to improved core behavior from JENKINS-18407.

          Show
          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Jesse Glick Path: src/test/java/hudson/plugins/git/RevisionParameterActionTest.java http://jenkins-ci.org/commit/git-plugin/4fe33a1fa31459563b7d9e4c4c652b20bde6df4d Log: Commenting out assertions that fail in 1.521+ due to improved core behavior from JENKINS-18407 .
          Hide
          scm_issue_link SCM/JIRA link daemon added a comment -

          Code changed in jenkins
          User: Craig Rodrigues
          Path:
          src/test/groovy/com/cloudbees/plugins/flow/ConcurrencyTest.groovy
          http://jenkins-ci.org/commit/build-flow-plugin/faeaa5cc2062f7c7b73073e201b12646e9538963
          Log:
          Delete test which no longer works in 1.521+ due to improved core behavior from JENKINS-18407

          Due to the improved core behavior, in JobInvocation.groovy's run()
          method, schedule2() no longer returns null when invoked from the test.

          Show
          scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Craig Rodrigues Path: src/test/groovy/com/cloudbees/plugins/flow/ConcurrencyTest.groovy http://jenkins-ci.org/commit/build-flow-plugin/faeaa5cc2062f7c7b73073e201b12646e9538963 Log: Delete test which no longer works in 1.521+ due to improved core behavior from JENKINS-18407 Due to the improved core behavior, in JobInvocation.groovy's run() method, schedule2() no longer returns null when invoked from the test.
          rtyler R. Tyler Croy made changes -
          Workflow JNJira [ 149714 ] JNJira + In-Review [ 193256 ]
          jnazander Jevgeni Nazander made changes -
          Assignee Kohsuke Kawaguchi [ kohsuke ] Jevgeni Nazander [ jnazander ]
          jnazander Jevgeni Nazander made changes -
          Assignee Jevgeni Nazander [ jnazander ]
          Hide
          jnazander Jevgeni Nazander added a comment -

          It seems that this bug is still present (version 2.138.1) - every time when a build is triggered using `POST /job/[JOB_NAME]/build` (either normally or via Curl), jenkins ALWAYS returns 302 instead of 201. This makes it impossible to trigger builds via a webhook, because the HTTP client sees that the response code is not 2xx and starts retrying it.

          Show
          jnazander Jevgeni Nazander added a comment - It seems that this bug is still present (version 2.138.1) - every time when a build is triggered using `POST /job/ [JOB_NAME] /build` (either normally or via Curl), jenkins ALWAYS returns 302 instead of 201. This makes it impossible to trigger builds via a webhook, because the HTTP client sees that the response code is not 2xx and starts retrying it.
          jnazander Jevgeni Nazander made changes -
          Resolution Fixed [ 1 ]
          Status Resolved [ 5 ] Reopened [ 4 ]
          jnazander Jevgeni Nazander made changes -
          Comment [ Still broken ]
          jglick Jesse Glick made changes -
          Assignee Kohsuke Kawaguchi [ kohsuke ]
          Hide
          jglick Jesse Glick added a comment -

          Jevgeni Nazander no you are just using the wrong endpoint (build vs. buildWithParameters). Please use the users’ list for assistance. If you believe you have encountered a bug please file a fresh report with complete steps to reproduce from scratch, linking to existing issues as appropriate.

          Show
          jglick Jesse Glick added a comment - Jevgeni Nazander no you are just using the wrong endpoint ( build vs. buildWithParameters ). Please use the users’ list for assistance. If you believe you have encountered a bug please file a fresh report with complete steps to reproduce from scratch, linking to existing issues as appropriate.
          jglick Jesse Glick made changes -
          Resolution Fixed [ 1 ]
          Status Reopened [ 4 ] Resolved [ 5 ]
          Hide
          jnazander Jevgeni Nazander added a comment -

          Jesse Glick But my job doesn't have parameters, and if I try calling the job using `/buildWithParameters`, it returns HTTP 500 – `IllegalStateException: This build is not parameterized!`

           

          In any case, Jenkins's API documentation says:

          `To programmatically schedule a new build, post to this URL (https://jenkins.***.net/job/accounts/build). If the build has parameters, post to this URL and provide the parameters as form data. Either way, the successful queueing will result in 201 status code`

          While in reality it returns 302. This looks like a bug to me, should I create a new ticket?

          Show
          jnazander Jevgeni Nazander added a comment - Jesse Glick But my job doesn't have parameters, and if I try calling the job using `/buildWithParameters`, it returns HTTP 500 – `IllegalStateException: This build is not parameterized!`   In any case, Jenkins's API documentation says: `To programmatically schedule a new build, post to this URL ( https://jenkins.***.net/job/accounts/build ). If the build has parameters, post to this URL and provide the parameters as form data. Either way, the successful queueing will result in 201 status code` While in reality it returns 302. This looks like a bug to me, should I create a new ticket?
          Hide
          jglick Jesse Glick added a comment -

          If your job has parameters, use buildWithParameters. If it does not, use build. Which is what the API documentation says. There is no bug I can see. Again please use the users’ list for assistance.

          Show
          jglick Jesse Glick added a comment - If your job has parameters, use buildWithParameters . If it does not, use build . Which is what the API documentation says. There is no bug I can see. Again please use the users’ list for assistance.

            People

            Assignee:
            kohsuke Kohsuke Kawaguchi
            Reporter:
            amoss166 Amos Sonnenwirth
            Votes:
            6 Vote for this issue
            Watchers:
            11 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: