Skip to content

Commit

Permalink
Update igor endpoints to support job names at end of URLs. Job names …
Browse files Browse the repository at this point in the history
…with the folder plugin can contain slashes
  • Loading branch information
AMeng committed Dec 3, 2015
1 parent b111375 commit 75fbaba
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 12 deletions.
2 changes: 2 additions & 0 deletions gate-web/gate-web.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ dependencies {
compile('org.springframework.session:spring-session-data-redis:1.0.1.RELEASE')
compile('org.opensaml:opensaml:2.6.4')

testCompile 'com.squareup.okhttp:mockwebserver:2.1.0'

//this brings in the jetty GzipFilter which boot will autoconfigure
runtime 'org.eclipse.jetty:jetty-servlets:9.2.11.v20150529'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ package com.netflix.spinnaker.gate.controllers

import com.netflix.spinnaker.gate.services.BuildService
import groovy.transform.CompileStatic
import javax.servlet.http.HttpServletRequest
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.servlet.HandlerMapping

@CompileStatic
@RequestMapping("/builds")
Expand All @@ -46,18 +48,21 @@ class BuildController {
buildService.getJobsForBuildMaster(buildMaster)
}

@RequestMapping(value = "/{buildMaster}/jobs/{job:.+}", method = RequestMethod.GET)
Map getJobConfig(@PathVariable("buildMaster") String buildMaster, @PathVariable("job") String job) {
@RequestMapping(value = "/{buildMaster}/jobs/**", method = RequestMethod.GET)
Map getJobConfig(@PathVariable("buildMaster") String buildMaster, HttpServletRequest request) {
def job = request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE).toString().split('/').drop(4).join('/')
buildService.getJobConfig(buildMaster, job)
}

@RequestMapping(value = "/{buildMaster}/builds/{job:.+}", method = RequestMethod.GET)
List getBuilds(@PathVariable("buildMaster") String buildMaster, @PathVariable("job") String job) {
@RequestMapping(value = "/{buildMaster}/builds/**", method = RequestMethod.GET)
List getBuilds(@PathVariable("buildMaster") String buildMaster, HttpServletRequest request) {
def job = request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)toString().split('/').drop(4).join('/')
buildService.getBuilds(buildMaster, job)
}

@RequestMapping(value = "/{buildMaster}/build/{number}/{job:.+}", method = RequestMethod.GET)
Map getBuilds(@PathVariable("buildMaster") String buildMaster, @PathVariable("job") String job, @PathVariable("number") String number) {
@RequestMapping(value = "/{buildMaster}/build/{number}/**", method = RequestMethod.GET)
Map getBuild(@PathVariable("buildMaster") String buildMaster, @PathVariable("number") String number, HttpServletRequest request) {
def job = request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE)toString().split('/').drop(5).join('/')
buildService.getBuild(buildMaster, job, number)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.netflix.spinnaker.gate.services.internal

import retrofit.http.EncodedPath
import retrofit.http.GET
import retrofit.http.Path

Expand All @@ -32,12 +33,12 @@ interface IgorService {
@GET('/jobs/{buildMaster}')
List<String> getJobsForBuildMaster(@Path("buildMaster") String buildMaster)

@GET('/jobs/{buildMaster}/{job:.+}')
Map getJobConfig(@Path("buildMaster") String buildMaster, @Path("job") String job)
@GET('/jobs/{buildMaster}/{job}')
Map getJobConfig(@Path("buildMaster") String buildMaster, @EncodedPath("job") String job)

@GET('/jobs/{buildMaster}/builds/{job:.+}')
List<Map> getBuilds(@Path("buildMaster") String buildMaster, @Path("job") String job)
@GET('/builds/all/{buildMaster}/{job}')
List<Map> getBuilds(@Path("buildMaster") String buildMaster, @EncodedPath("job") String job)

@GET('/jobs/{buildMaster}/build/{number}/{job:.+}')
Map getBuild(@Path("buildMaster") String buildMaster, @Path("job") String job, @Path("number") String number)
@GET('/builds/status/{number}/{buildMaster}/{job}')
Map getBuild(@Path("buildMaster") String buildMaster, @EncodedPath("job") String job, @Path("number") String number)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* Copyright 2015 Netflix, Inc.
*
* 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 com.netflix.spinnaker.gate.controllers

import com.netflix.spinnaker.gate.services.BuildService
import com.netflix.spinnaker.gate.services.internal.IgorService
import com.squareup.okhttp.mockwebserver.MockWebServer
import org.springframework.http.MediaType
import org.springframework.mock.web.MockHttpServletResponse
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.setup.MockMvcBuilders
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get
import spock.lang.Shared
import spock.lang.Specification

class BuildControllerSpec extends Specification {

MockMvc mockMvc
BuildService buildService
IgorService igorService

@Shared
MockWebServer server

final MASTER = 'MASTER'
final BUILD_NUMBER = 123
final JOB_NAME = "name/with/slashes"

void cleanup() {
server.shutdown()
}

void setup() {
igorService = Mock(IgorService)
buildService = new BuildService(igorService: igorService)
server = new MockWebServer()
mockMvc = MockMvcBuilders.standaloneSetup(new BuildController(buildService: buildService)).build()
}

void 'should get a list of masters'() {
given:
1 * igorService.getBuildMasters() >> [MASTER, "master2"]

when:
MockHttpServletResponse response = mockMvc.perform(get("/builds")
.accept(MediaType.APPLICATION_JSON)).andReturn().response

then:
response.contentAsString == "[\"${MASTER}\",\"master2\"]"
}

void 'should get a list of jobs for a master'() {
given:
1 * igorService.getJobsForBuildMaster(MASTER) >> [JOB_NAME, "another_job"]

when:
MockHttpServletResponse response = mockMvc.perform(get("/builds/${MASTER}/jobs")
.accept(MediaType.APPLICATION_JSON)).andReturn().response

then:
response.contentAsString == "[\"${JOB_NAME}\",\"another_job\"]"
}

void 'should get a list of builds for a job'() {
given:
1 * igorService.getBuilds(MASTER, JOB_NAME) >> [["building":false, "number":111], ["building":false, "number":222]]

when:
MockHttpServletResponse response = mockMvc.perform(get("/builds/${MASTER}/builds/${JOB_NAME}")
.accept(MediaType.APPLICATION_JSON)).andReturn().response

then:
response.contentAsString == "[{\"building\":false,\"number\":111},{\"building\":false,\"number\":222}]"
}

void 'should get a job config'() {
given:
1 * igorService.getJobConfig(MASTER, JOB_NAME) >> ['name': JOB_NAME, 'url': "http://test.com/job/${JOB_NAME}".toString()]

when:
MockHttpServletResponse response = mockMvc.perform(get("/builds/${MASTER}/jobs/${JOB_NAME}")
.accept(MediaType.APPLICATION_JSON)).andReturn().response

then:
response.contentAsString == "{\"name\":\"${JOB_NAME}\",\"url\":\"http://test.com/job/${JOB_NAME}\"}"
}

void 'should get a build'() {
given:
1 * igorService.getBuild(MASTER, JOB_NAME, BUILD_NUMBER.toString()) >> ["building":false, "number":BUILD_NUMBER]

when:
MockHttpServletResponse response = mockMvc.perform(get("/builds/${MASTER}/build/${BUILD_NUMBER}/${JOB_NAME}")
.accept(MediaType.APPLICATION_JSON)).andReturn().response

then:
response.contentAsString == "{\"building\":false,\"number\":${BUILD_NUMBER}}"
}
}

0 comments on commit 75fbaba

Please sign in to comment.