Added reactor setup

This commit is contained in:
Marcin Grzejszczak
2020-01-07 16:21:19 +01:00
parent 7e5d225a7e
commit 36a8acc591
7 changed files with 327 additions and 1 deletions

View File

@@ -17,6 +17,7 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<cloudfoundry-client.version>4.3.0.RELEASE</cloudfoundry-client.version>
</properties>
<dependencies>
@@ -25,6 +26,16 @@
<artifactId>releaser-spring</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.cloudfoundry</groupId>
<artifactId>cloudfoundry-client-reactor</artifactId>
<version>${cloudfoundry-client.version}</version>
</dependency>
<dependency>
<groupId>org.cloudfoundry</groupId>
<artifactId>cloudfoundry-operations</artifactId>
<version>${cloudfoundry-client.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>

View File

@@ -0,0 +1,101 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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 releaser.reactor;
import org.cloudfoundry.client.CloudFoundryClient;
import org.cloudfoundry.doppler.DopplerClient;
import org.cloudfoundry.operations.CloudFoundryOperations;
import org.cloudfoundry.operations.DefaultCloudFoundryOperations;
import org.cloudfoundry.reactor.ConnectionContext;
import org.cloudfoundry.reactor.DefaultConnectionContext;
import org.cloudfoundry.reactor.TokenProvider;
import org.cloudfoundry.reactor.client.ReactorCloudFoundryClient;
import org.cloudfoundry.reactor.doppler.ReactorDopplerClient;
import org.cloudfoundry.reactor.tokenprovider.PasswordGrantTokenProvider;
import org.cloudfoundry.reactor.uaa.ReactorUaaClient;
import org.cloudfoundry.uaa.UaaClient;
import releaser.internal.Releaser;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
class ReactorConfiguration {
@Bean
@ConditionalOnMissingBean
CfClient cfClient(CloudFoundryOperations cloudFoundryOperations) {
return new CfClient(cloudFoundryOperations);
}
@Bean
RestartSiteProjectPostReleaseTask restartSiteProjectPostReleaseTask(Releaser releaser,
CfClient cfClient, @Value("${cf.reactorAppName}") String reactorAppName) {
return new RestartSiteProjectPostReleaseTask(releaser, cfClient, reactorAppName);
}
}
@Configuration
class CfConfiguration {
@Bean
DefaultConnectionContext connectionContext(@Value("${cf.apiHost}") String apiHost) {
return DefaultConnectionContext.builder().apiHost(apiHost).build();
}
@Bean
PasswordGrantTokenProvider tokenProvider(@Value("${cf.username}") String username,
@Value("${cf.password}") String password) {
return PasswordGrantTokenProvider.builder().password(password).username(username)
.build();
}
@Bean
ReactorCloudFoundryClient cloudFoundryClient(ConnectionContext connectionContext,
TokenProvider tokenProvider) {
return ReactorCloudFoundryClient.builder().connectionContext(connectionContext)
.tokenProvider(tokenProvider).build();
}
@Bean
ReactorDopplerClient dopplerClient(ConnectionContext connectionContext,
TokenProvider tokenProvider) {
return ReactorDopplerClient.builder().connectionContext(connectionContext)
.tokenProvider(tokenProvider).build();
}
@Bean
ReactorUaaClient uaaClient(ConnectionContext connectionContext,
TokenProvider tokenProvider) {
return ReactorUaaClient.builder().connectionContext(connectionContext)
.tokenProvider(tokenProvider).build();
}
@Bean
DefaultCloudFoundryOperations defaultCloudFoundryOperations(
CloudFoundryClient cloudFoundryClient, DopplerClient dopplerClient,
UaaClient uaaClient, @Value("${cf.organization}") String organizationId,
@Value("${cf.space}") String spaceId) {
return DefaultCloudFoundryOperations.builder()
.cloudFoundryClient(cloudFoundryClient).dopplerClient(dopplerClient)
.uaaClient(uaaClient).organization(organizationId).space(spaceId).build();
}
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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 releaser.reactor;
import org.cloudfoundry.operations.CloudFoundryOperations;
import org.cloudfoundry.operations.applications.RestartApplicationRequest;
import releaser.internal.Releaser;
import releaser.internal.spring.Arguments;
import releaser.internal.spring.ExecutionResult;
import releaser.internal.tasks.DryRunReleaseReleaserTask;
import releaser.internal.tasks.release.PublishDocsReleaseTask;
public class RestartSiteProjectPostReleaseTask extends PublishDocsReleaseTask
implements DryRunReleaseReleaserTask {
private static final String REACTOR_CORE_PROJECT_NAME = "reactor-core";
private final CfClient cfClient;
private final String reactorAppName;
public RestartSiteProjectPostReleaseTask(Releaser releaser, CfClient cfClient,
String reactorAppName) {
super(releaser);
this.cfClient = cfClient;
this.reactorAppName = reactorAppName;
}
@Override
public ExecutionResult runTask(Arguments args) {
if (!REACTOR_CORE_PROJECT_NAME.equals(args.projectToRun.name())) {
return ExecutionResult.success();
}
this.cfClient.restartApp(this.reactorAppName);
return ExecutionResult.success();
}
}
class CfClient {
private final CloudFoundryOperations cloudFoundryOperations;
CfClient(CloudFoundryOperations cloudFoundryOperations) {
this.cloudFoundryOperations = cloudFoundryOperations;
}
void restartApp(String name) {
this.cloudFoundryOperations.applications()
.restart(RestartApplicationRequest.builder().name(name).build());
}
}

View File

@@ -14,4 +14,9 @@ releaser:
release-train-project-name: reactor
release-train-dependency-names:
- reactor
git-org-url: https://github.com/reactor
git-org-url: https://github.com/reactor
cf:
organization: FrameworksAndRuntimes
space: Reactor
reactorAppName: projectreactor
apiHost: api.run.pivotal.io

View File

@@ -16,26 +16,49 @@
package releaser;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import releaser.internal.options.Parser;
import releaser.internal.spring.ExecutionResultHandler;
import releaser.internal.spring.SpringReleaser;
import releaser.internal.tasks.DryRunReleaseReleaserTask;
import releaser.internal.tasks.ReleaserTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.test.context.ActiveProfiles;
@SpringBootTest(
classes = { ReleaserApplicationTests.Config.class, ReleaserApplication.class },
properties = { "releaser.sagan.update-sagan=false" })
@ActiveProfiles("test")
class ReleaserApplicationTests {
@Autowired
ApplicationContext context;
@Test
void contextLoads() {
}
@Test
void should_load_reactor_version_of_publish_docs() {
Map<String, DryRunReleaseReleaserTask> beans = context
.getBeansOfType(DryRunReleaseReleaserTask.class);
List<ReleaserTask> inOrder = new LinkedList<>(beans.values());
inOrder.sort(AnnotationAwareOrderComparator.INSTANCE);
System.out.println(inOrder);
}
@Configuration
static class Config {

View File

@@ -0,0 +1,116 @@
/*
* Copyright 2013-2019 the original author or authors.
*
* 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
*
* https://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 releaser.reactor;
import org.assertj.core.api.BDDAssertions;
import org.cloudfoundry.operations.CloudFoundryOperations;
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import releaser.internal.Releaser;
import releaser.internal.ReleaserProperties;
import releaser.internal.options.Options;
import releaser.internal.project.ProjectVersion;
import releaser.internal.project.Projects;
import releaser.internal.spring.Arguments;
import releaser.internal.spring.ExecutionResult;
import releaser.internal.spring.ProjectToRun;
import releaser.internal.spring.ProjectsFromBom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ActiveProfiles;
@SpringBootTest(classes = RestartSiteProjectPostReleaseTaskTests.Config.class)
@ActiveProfiles("test")
class RestartSiteProjectPostReleaseTaskTests {
@Autowired
RestartSiteProjectPostReleaseTask task;
@Autowired
CfClient cfClient;
@Test
void should_update_the_website() {
Arguments arguments = Arguments.forProject(reactorCoreProject());
ExecutionResult result = task.runTask(arguments);
BDDAssertions.then(result.isSuccess()).isTrue();
BDDMockito.then(this.cfClient).should()
.restartApp(BDDMockito.eq("projectreactor"));
}
@Test
void should_not_update_the_website_if_project_not_reactor_core() {
Arguments arguments = Arguments.forProject(nonReactorCoreProject());
ExecutionResult result = task.runTask(arguments);
BDDAssertions.then(result.isSuccess()).isTrue();
BDDMockito.then(this.cfClient).shouldHaveNoInteractions();
}
private ProjectToRun reactorCoreProject() {
return new ProjectToRun(null,
new ProjectsFromBom(new Projects(), new ProjectVersion("foo", "1.0.0")),
new ProjectVersion("foo", "1.0.0"), new ReleaserProperties(),
BDDMockito.mock(Options.class)) {
@Override
public String name() {
return "reactor-core";
}
};
}
private ProjectToRun nonReactorCoreProject() {
return new ProjectToRun(null,
new ProjectsFromBom(new Projects(), new ProjectVersion("foo", "1.0.0")),
new ProjectVersion("foo", "1.0.0"), new ReleaserProperties(),
BDDMockito.mock(Options.class)) {
@Override
public String name() {
return "whatever";
}
};
}
@Configuration
@EnableAutoConfiguration
static class Config extends ReactorConfiguration {
@Bean
Releaser mockReleaser() {
return BDDMockito.mock(Releaser.class);
}
@Bean
CloudFoundryOperations mockCloudFoundryOperations() {
return BDDMockito.mock(CloudFoundryOperations.class);
}
@Override
CfClient cfClient(CloudFoundryOperations cloudFoundryOperations) {
return BDDMockito.mock(CfClient.class);
}
}
}

View File

@@ -0,0 +1,3 @@
cf:
username: foo
password: bar