Skip to content

Commit

Permalink
Add an internal upstream pipelines listing API
Browse files Browse the repository at this point in the history
* This API is required on the pipeline config SPA to provide
  auto suggestions for upstream pipelines while fetching
  artifacts
  • Loading branch information
GaneshSPatil committed Mar 3, 2020
1 parent 52cb509 commit bb97610
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Expand Up @@ -517,3 +517,7 @@ api/api-compare-v2/out/
api/api-compare-v2/target/
api/api-compare-v2/logs/
api/api-compare-v2/config/
api/api-internal-dependency-pipelines-v1/out/
api/api-internal-dependency-pipelines-v1/target/
api/api-internal-dependency-pipelines-v1/logs/
api/api-internal-dependency-pipelines-v1/config/
27 changes: 27 additions & 0 deletions api/api-internal-dependency-pipelines-v1/build.gradle
@@ -0,0 +1,27 @@
/*
* Copyright 2020 ThoughtWorks, 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.
*/

apply plugin: 'jacoco'
apply plugin: 'groovy'

dependencies {
compile project(':api:api-base')

testCompile project(path: ':api:api-base', configuration: 'testOutput')

testImplementation group: 'org.junit.jupiter', name: 'junit-jupiter-api', version: project.versions.junit5
testRuntimeOnly group: 'org.junit.jupiter', name: 'junit-jupiter-engine', version: project.versions.junit5
}
@@ -0,0 +1,87 @@
/*
* Copyright 2020 ThoughtWorks, 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.thoughtworks.go.apiv1.internaldependencypipelines;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.thoughtworks.go.api.ApiController;
import com.thoughtworks.go.api.ApiVersion;
import com.thoughtworks.go.api.spring.ApiAuthenticationHelper;
import com.thoughtworks.go.config.CaseInsensitiveString;
import com.thoughtworks.go.config.CruiseConfig;
import com.thoughtworks.go.server.presentation.FetchArtifactViewHelper;
import com.thoughtworks.go.server.service.GoConfigService;
import com.thoughtworks.go.spark.Routes;
import com.thoughtworks.go.spark.spring.SparkSpringController;
import com.thoughtworks.go.util.SystemEnvironment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import spark.Request;
import spark.Response;

import static spark.Spark.*;

@Component
public class InternalDependencyPipelinesControllerV1 extends ApiController implements SparkSpringController {

private final ApiAuthenticationHelper apiAuthenticationHelper;
private SystemEnvironment systemEnvironment;
private GoConfigService goConfigService;
private Gson gson = new GsonBuilder().setPrettyPrinting().serializeNulls().create();

@Autowired
public InternalDependencyPipelinesControllerV1(ApiAuthenticationHelper apiAuthenticationHelper,
SystemEnvironment systemEnvironment,
GoConfigService goConfigService) {
super(ApiVersion.v1);
this.apiAuthenticationHelper = apiAuthenticationHelper;
this.systemEnvironment = systemEnvironment;
this.goConfigService = goConfigService;
}

@Override
public String controllerBasePath() {
return Routes.InternalDependencyPipelines.BASE;
}

@Override
public void setupRoutes() {
path(controllerBasePath(), () -> {
before("", mimeType, this::setContentType);
before("/*", mimeType, this::setContentType);

before("", mimeType, this::verifyContentType);
before("/*", mimeType, this::verifyContentType);

before("", mimeType, apiAuthenticationHelper::checkUserAnd403);

get("", mimeType, this::index);
});
}

public String index(Request request, Response response) {
String pipelineName = request.params("pipeline_name");
String stageName = request.params("stage_name");

CruiseConfig config = goConfigService.getMergedConfigForEditing();
FetchArtifactViewHelper helper = new FetchArtifactViewHelper(systemEnvironment, config, new CaseInsensitiveString(pipelineName), new CaseInsensitiveString(stageName), false);

response.type("application/json");
return gson.toJson(helper.autosuggestMap());
}

}
@@ -0,0 +1,90 @@
/*
* Copyright 2020 ThoughtWorks, 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.thoughtworks.go.apiv1.internaldependencypipelines

import com.thoughtworks.go.api.SecurityTestTrait
import com.thoughtworks.go.api.spring.ApiAuthenticationHelper
import com.thoughtworks.go.config.BasicCruiseConfig
import com.thoughtworks.go.helper.PipelineConfigMother
import com.thoughtworks.go.server.service.GoConfigService
import com.thoughtworks.go.spark.ControllerTrait
import com.thoughtworks.go.spark.NormalUserSecurity
import com.thoughtworks.go.spark.SecurityServiceTrait
import com.thoughtworks.go.util.SystemEnvironment
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Nested
import org.junit.jupiter.api.Test
import org.mockito.Mock

import static org.mockito.Mockito.when
import static org.mockito.MockitoAnnotations.initMocks

class InternalDependencyPipelinesControllerV1Test implements SecurityServiceTrait, ControllerTrait<InternalDependencyPipelinesControllerV1> {
@Mock
GoConfigService goConfigService

@BeforeEach
void setUp() {
initMocks(this)
}

@Override
InternalDependencyPipelinesControllerV1 createControllerInstance() {
new InternalDependencyPipelinesControllerV1(new ApiAuthenticationHelper(securityService, goConfigService), new SystemEnvironment(), goConfigService)
}

@Nested
class Index {
@Nested
class Security implements SecurityTestTrait, NormalUserSecurity {

@Override
String getControllerMethodUnderTest() {
return "index"
}

@Override
void makeHttpCall() {
getWithApiHeader(path('pipeline', 'stage'))
}
}
}

@Test
void 'should return pipeline auto suggestions'() {
def config = new BasicCruiseConfig()
config.addPipeline("first", PipelineConfigMother.pipelineConfig("pipeline1"))
when(goConfigService.getMergedConfigForEditing()).thenReturn(config)

getWithApiHeader(path('pipeline1', 'stage'))

assertThatResponse()
.isOk()
.hasJsonBody('{' +
' "pipeline1": {' +
' "mingle": {}' +
' },' +
' "": {' +
' "mingle": {}' +
' }' +
'}')
}

String path(String name, String stageName) {
return controller.controllerBasePath().replaceAll(":pipeline_name", name).replaceAll(':stage_name', stageName)
}
}
1 change: 1 addition & 0 deletions server/src/main/resources/applicationContext-global.xml
Expand Up @@ -25,6 +25,7 @@

<context:annotation-config/>

<context:component-scan base-package="com.thoughtworks.go.apiv1.internaldependencypipelines"/>
<context:component-scan base-package="com.thoughtworks.go.apiv2.compare"/>
<context:component-scan base-package="com.thoughtworks.go.apiv2.apiinfo"/>
<context:component-scan base-package="com.thoughtworks.go.apiv1.permissions"/>
Expand Down
6 changes: 6 additions & 0 deletions server/src/main/webapp/WEB-INF/urlrewrite.xml
Expand Up @@ -23,6 +23,12 @@
-->

<urlrewrite>
<rule>
<name>Internal Dependency Pipelines API</name>
<from>^/api/internal/pipelines/([^/]+)/([^/]+)/upstream(/?)$</from>
<to last="true">/spark/api/internal/pipelines/${escape:$1}/${escape:$2}/upstream</to>
</rule>

<rule>
<name>Clicky pipeline config SPA</name>
<from>^/admin/pipelines/([^/]+)/edit(/?)$</from>
Expand Down
1 change: 1 addition & 0 deletions settings.gradle
Expand Up @@ -58,6 +58,7 @@ include ':api:api-export-v1'
include ':api:api-feature-toggles-v1'
include ':api:api-feeds-api-v1'
include ':api:api-internal-command-snippets-v1'
include ':api:api-internal-dependency-pipelines-v1'
include ':api:api-internal-environments-v1'
include ':api:api-internal-material-test-v1'
include ':api:api-internal-pipeline-structure-v1'
Expand Down
Expand Up @@ -889,4 +889,8 @@ public static class Permissions {
public static final String BASE = "/api/auth/permissions";
public static final String DOC = apiDocsUrl("permissions");
}

public class InternalDependencyPipelines {
public static final String BASE = "/api/internal/pipelines/:pipeline_name/:stage_name/upstream";
}
}

0 comments on commit bb97610

Please sign in to comment.