Skip to content
This repository was archived by the owner on May 14, 2025. It is now read-only.

Commit 3855ce4

Browse files
committed
Add AppBootVersion to 'app register' shell/client
- Introduces the AppBootVersion enum - Hooks into 'app register' shell command - Passes boot version into AppRegistryController See #5239
1 parent 2936c5c commit 3855ce4

File tree

8 files changed

+266
-15
lines changed

8 files changed

+266
-15
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.dataflow.core;
18+
19+
import java.util.Arrays;
20+
21+
/**
22+
* Defines the possible {@code "Boot"} versions available for registered applications.
23+
*
24+
* <p>Each value defines the supported Spring Boot version as well as other information that is variant across the
25+
* versions and required by the system to handle each version.
26+
*
27+
* @author Chris Bono
28+
*/
29+
public enum AppBootVersion {
30+
31+
BOOT2("Boot 2 Tasks/Jobs", "2", null, null),
32+
BOOT3("Boot 3 Tasks/Jobs", "3", "BOOT3_TASK_", "BOOT3_BATCH_");
33+
34+
private String description;
35+
36+
private String bootVersion;
37+
38+
private String taskPrefix;
39+
40+
private String batchPrefix;
41+
42+
AppBootVersion(String description, String bootVersion, String taskPrefix, String batchPrefix) {
43+
this.description = description;
44+
this.bootVersion = bootVersion;
45+
this.taskPrefix = taskPrefix;
46+
this.batchPrefix = batchPrefix;
47+
}
48+
49+
public static AppBootVersion fromBootVersion(String bootVersion) {
50+
return Arrays.stream(AppBootVersion.values())
51+
.filter((bv) -> bv.getBootVersion().equals(bootVersion))
52+
.findFirst().orElseThrow(() -> new IllegalArgumentException("Unsupported bootVersion: " + bootVersion));
53+
}
54+
55+
public String getDescription() {
56+
return this.description;
57+
}
58+
59+
public String getBootVersion() {
60+
return this.bootVersion;
61+
}
62+
63+
public String getTaskPrefix() {
64+
return this.taskPrefix;
65+
}
66+
67+
public String getBatchPrefix() {
68+
return this.batchPrefix;
69+
}
70+
71+
@Override
72+
public String toString() {
73+
return String.format("AppBootVersion{description='%s', bootVersion='%s', taskPrefix='%s', batchPrefix='%s'}",
74+
this.description, this.bootVersion, this.taskPrefix, this.batchPrefix);
75+
}
76+
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright 2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cloud.dataflow.core;
18+
19+
import org.junit.jupiter.api.Test;
20+
21+
import static org.assertj.core.api.Assertions.assertThat;
22+
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
23+
24+
/**
25+
* Unit tests for {@link AppBootVersion}.
26+
*
27+
* @author Chris Bono
28+
*/
29+
public class AppBootVersionTests {
30+
31+
@Test
32+
void bootVersion2() {
33+
assertThat(AppBootVersion.BOOT2.getBootVersion()).isEqualTo("2");
34+
assertThat(AppBootVersion.BOOT2.getDescription()).isEqualTo("Boot 2 Tasks/Jobs");
35+
assertThat(AppBootVersion.BOOT2.getTaskPrefix()).isNull();
36+
assertThat(AppBootVersion.BOOT2.getBatchPrefix()).isNull();
37+
assertThat(AppBootVersion.BOOT2.toString()).isEqualTo(
38+
"AppBootVersion{description='Boot 2 Tasks/Jobs', bootVersion='2', taskPrefix='null', batchPrefix='null'}");
39+
}
40+
41+
@Test
42+
void bootVersion3() {
43+
assertThat(AppBootVersion.BOOT3.getBootVersion()).isEqualTo("3");
44+
assertThat(AppBootVersion.BOOT3.getDescription()).isEqualTo("Boot 3 Tasks/Jobs");
45+
assertThat(AppBootVersion.BOOT3.getTaskPrefix()).isEqualTo("BOOT3_TASK_");
46+
assertThat(AppBootVersion.BOOT3.getBatchPrefix()).isEqualTo("BOOT3_BATCH_");
47+
assertThat(AppBootVersion.BOOT3.toString()).isEqualTo(
48+
"AppBootVersion{description='Boot 3 Tasks/Jobs', bootVersion='3', taskPrefix='BOOT3_TASK_', batchPrefix='BOOT3_BATCH_'}");
49+
50+
}
51+
52+
@Test
53+
void fromBootVersion() {
54+
assertThat(AppBootVersion.fromBootVersion("2")).isEqualTo(AppBootVersion.BOOT2);
55+
assertThat(AppBootVersion.fromBootVersion("3")).isEqualTo(AppBootVersion.BOOT3);
56+
assertThatIllegalArgumentException().isThrownBy(() -> AppBootVersion.fromBootVersion(null))
57+
.withMessage("Unsupported bootVersion: null");
58+
assertThatIllegalArgumentException().isThrownBy(() -> AppBootVersion.fromBootVersion("4"))
59+
.withMessage("Unsupported bootVersion: 4");
60+
}
61+
62+
}

spring-cloud-dataflow-rest-client/src/main/java/org/springframework/cloud/dataflow/rest/client/AppRegistryOperations.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2019 the original author or authors.
2+
* Copyright 2015-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.Properties;
2020

21+
import org.springframework.cloud.dataflow.core.AppBootVersion;
2122
import org.springframework.cloud.dataflow.core.ApplicationType;
2223
import org.springframework.cloud.dataflow.rest.resource.AppRegistrationResource;
2324
import org.springframework.cloud.dataflow.rest.resource.DetailedAppRegistrationResource;
@@ -32,6 +33,7 @@
3233
* @author Patrick Peralta
3334
* @author Mark Fisher
3435
* @author Chris Schaefer
36+
* @author Chris Bono
3537
*/
3638
public interface AppRegistryOperations {
3739

@@ -81,9 +83,24 @@ public interface AppRegistryOperations {
8183
* @param metadataUri URI for the application metadata artifact
8284
* @param force if {@code true}, overwrites a pre-existing registration
8385
* @return the new app registration
86+
* @deprecated in favor of {@link #register(String, ApplicationType, AppBootVersion, String, String, boolean)}
8487
*/
88+
@Deprecated
8589
AppRegistrationResource register(String name, ApplicationType type, String uri, String metadataUri, boolean force);
8690

91+
/**
92+
* Register an application name, type, and boot version with its Maven coordinates.
93+
*
94+
* @param name application name
95+
* @param type application type
96+
* @param bootVersion application boot version
97+
* @param uri URI for the application artifact
98+
* @param metadataUri URI for the application metadata artifact
99+
* @param force if {@code true}, overwrites a pre-existing registration
100+
* @return the new app registration
101+
*/
102+
AppRegistrationResource register(String name, ApplicationType type, AppBootVersion bootVersion, String uri, String metadataUri, boolean force);
103+
87104
/**
88105
* Register an application name, type and version with its Maven coordinates.
89106
*
@@ -94,10 +111,27 @@ public interface AppRegistryOperations {
94111
* @param metadataUri URI for the application metadata artifact
95112
* @param force if {@code true}, overwrites a pre-existing registration
96113
* @return the new app registration
114+
* @deprecated in favor of {@link #register(String, ApplicationType, AppBootVersion, String, String, String, boolean)}
97115
*/
116+
@Deprecated
98117
AppRegistrationResource register(String name, ApplicationType type, String version, String uri,
99118
String metadataUri, boolean force);
100119

120+
/**
121+
* Register an application name, type, boot version, and version with its Maven coordinates.
122+
*
123+
* @param name application name
124+
* @param type application type
125+
* @param bootVersion application boot version
126+
* @param version application version
127+
* @param uri URI for the application artifact
128+
* @param metadataUri URI for the application metadata artifact
129+
* @param force if {@code true}, overwrites a pre-existing registration
130+
* @return the new app registration
131+
*/
132+
AppRegistrationResource register(String name, ApplicationType type, AppBootVersion bootVersion, String version, String uri,
133+
String metadataUri, boolean force);
134+
101135
/**
102136
* Unregister an application name and type.
103137
*

spring-cloud-dataflow-rest-client/src/main/java/org/springframework/cloud/dataflow/rest/client/AppRegistryTemplate.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2019 the original author or authors.
2+
* Copyright 2015-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.Properties;
2020

21+
import org.springframework.cloud.dataflow.core.AppBootVersion;
2122
import org.springframework.cloud.dataflow.core.ApplicationType;
2223
import org.springframework.cloud.dataflow.rest.resource.AppRegistrationResource;
2324
import org.springframework.cloud.dataflow.rest.resource.DetailedAppRegistrationResource;
@@ -40,6 +41,7 @@
4041
* @author Patrick Peralta
4142
* @author Christian Tzolov
4243
* @author Chris Schaefer
44+
* @author Chris Bono
4345
*/
4446
public class AppRegistryTemplate implements AppRegistryOperations {
4547
/**
@@ -112,14 +114,20 @@ public DetailedAppRegistrationResource info(String name, ApplicationType type, S
112114
}
113115

114116
@Override
115-
public AppRegistrationResource register(String name, ApplicationType type, String uri, String metadataUri,
117+
public AppRegistrationResource register(String name, ApplicationType type, String uri, String metadataUri, boolean force) {
118+
return register(name, type, (AppBootVersion) null, uri, metadataUri, force);
119+
}
120+
121+
@Override
122+
public AppRegistrationResource register(String name, ApplicationType type, AppBootVersion bootVersion, String uri, String metadataUri,
116123
boolean force) {
117124
MultiValueMap<String, Object> values = new LinkedMultiValueMap<String, Object>();
118125
values.add("uri", uri);
119126
if (metadataUri != null) {
120127
values.add("metadata-uri", metadataUri);
121128
}
122129
values.add("force", Boolean.toString(force));
130+
values.add("bootVersion", bootVersion.getBootVersion());
123131

124132
return restTemplate.postForObject(appsLink.getHref() + "/{type}/{name}", values,
125133
AppRegistrationResource.class, type, name);
@@ -128,12 +136,19 @@ public AppRegistrationResource register(String name, ApplicationType type, Strin
128136
@Override
129137
public AppRegistrationResource register(String name, ApplicationType type, String version, String uri,
130138
String metadataUri, boolean force) {
139+
return this.register(name, type, AppBootVersion.BOOT2, version, uri, metadataUri, force);
140+
}
141+
142+
@Override
143+
public AppRegistrationResource register(String name, ApplicationType type, AppBootVersion bootVersion, String version, String uri,
144+
String metadataUri, boolean force) {
131145
MultiValueMap<String, Object> values = new LinkedMultiValueMap<>();
132146
values.add("uri", uri);
133147
if (metadataUri != null) {
134148
values.add("metadata-uri", metadataUri);
135149
}
136150
values.add("force", Boolean.toString(force));
151+
values.add("bootVersion", bootVersion);
137152

138153
return restTemplate.postForObject(appsLink.getHref() + "/{type}/{name}/{version}", values,
139154
AppRegistrationResource.class, type, name, version);

spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/config/web/WebConfiguration.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2022 the original author or authors.
2+
* Copyright 2015-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,12 +34,15 @@
3434
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
3535
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
3636
import org.springframework.boot.web.servlet.ServletContextInitializer;
37+
import org.springframework.cloud.dataflow.core.AppBootVersion;
3738
import org.springframework.cloud.dataflow.rest.support.jackson.ISO8601DateFormatWithMilliSeconds;
3839
import org.springframework.cloud.dataflow.rest.support.jackson.Jackson2DataflowModule;
3940
import org.springframework.context.ApplicationListener;
4041
import org.springframework.context.annotation.Bean;
4142
import org.springframework.context.annotation.Configuration;
4243
import org.springframework.context.event.ContextClosedEvent;
44+
import org.springframework.core.convert.converter.Converter;
45+
import org.springframework.format.FormatterRegistry;
4346
import org.springframework.hateoas.server.core.DefaultLinkRelationProvider;
4447
import org.springframework.http.converter.HttpMessageConverter;
4548
import org.springframework.http.converter.ResourceHttpMessageConverter;
@@ -58,6 +61,7 @@
5861
* @author Christian Tzolov
5962
* @author David Turanski
6063
* @author Michael Wirth
64+
* @author Chris Bono
6165
*/
6266
@Configuration(proxyBeanMethods = false)
6367
@ConditionalOnWebApplication
@@ -92,6 +96,11 @@ public WebMvcConfigurer configurer() {
9296
public void configurePathMatch(PathMatchConfigurer configurer) {
9397
configurer.setUseSuffixPatternMatch(false);
9498
}
99+
100+
@Override
101+
public void addFormatters(FormatterRegistry registry) {
102+
registry.addConverter(new AppBootVersionConverter());
103+
}
95104
};
96105
}
97106

@@ -133,4 +142,13 @@ public void onApplicationEvent(ContextClosedEvent event) {
133142
this.longTaskSample = null;
134143
}
135144
}
145+
146+
static class AppBootVersionConverter implements Converter<String, AppBootVersion> {
147+
148+
@Override
149+
public AppBootVersion convert(String value) {
150+
return AppBootVersion.fromBootVersion(value);
151+
}
152+
}
153+
136154
}

spring-cloud-dataflow-server-core/src/main/java/org/springframework/cloud/dataflow/server/controller/AppRegistryController.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
3737
import org.springframework.cloud.dataflow.configuration.metadata.ApplicationConfigurationMetadataResolver;
38+
import org.springframework.cloud.dataflow.core.AppBootVersion;
3839
import org.springframework.cloud.dataflow.core.AppRegistration;
3940
import org.springframework.cloud.dataflow.core.ApplicationType;
4041
import org.springframework.cloud.dataflow.core.StreamAppDefinition;
@@ -221,17 +222,21 @@ else if (entry.getKey().equals("outbound")) {
221222
* @param type module type
222223
* @param name module name
223224
* @param version module version
225+
* @param bootVersion module boot version or {@code null} to use the default
224226
* @param uri URI for the module artifact (e.g. {@literal maven://group:artifact:version})
225227
* @param metadataUri URI for the metadata artifact
226228
* @param force if {@code true}, overwrites a pre-existing registration
227229
*/
228230
@RequestMapping(value = "/{type}/{name}/{version:.+}", method = RequestMethod.POST)
229231
@ResponseStatus(HttpStatus.CREATED)
230-
public void register(@PathVariable("type") ApplicationType type, @PathVariable("name") String name,
232+
public void register(
233+
@PathVariable("type") ApplicationType type,
234+
@PathVariable("name") String name,
231235
@PathVariable("version") String version,
232-
@RequestParam("uri") String uri, @RequestParam(name = "metadata-uri", required = false) String metadataUri,
236+
@RequestParam(name = "bootVersion", required = false) AppBootVersion bootVersion,
237+
@RequestParam("uri") String uri,
238+
@RequestParam(name = "metadata-uri", required = false) String metadataUri,
233239
@RequestParam(value = "force", defaultValue = "false") boolean force) {
234-
235240
validateApplicationName(name);
236241
appRegistryService.validate(appRegistryService.getDefaultApp(name, type), uri, version);
237242
AppRegistration previous = appRegistryService.find(name, type, version);
@@ -251,11 +256,15 @@ public void register(@PathVariable("type") ApplicationType type, @PathVariable("
251256
@Deprecated
252257
@RequestMapping(value = "/{type}/{name}", method = RequestMethod.POST)
253258
@ResponseStatus(HttpStatus.CREATED)
254-
public void register(@PathVariable("type") ApplicationType type, @PathVariable("name") String name,
255-
@RequestParam("uri") String uri, @RequestParam(name = "metadata-uri", required = false) String metadataUri,
259+
public void register(
260+
@PathVariable("type") ApplicationType type,
261+
@PathVariable("name") String name,
262+
@RequestParam(name = "bootVersion", required = false) AppBootVersion bootVersion,
263+
@RequestParam("uri") String uri,
264+
@RequestParam(name = "metadata-uri", required = false) String metadataUri,
256265
@RequestParam(value = "force", defaultValue = "false") boolean force) {
257266
String version = this.appRegistryService.getResourceVersion(uri);
258-
this.register(type, name, version, uri, metadataUri, force);
267+
this.register(type, name, version, bootVersion, uri, metadataUri, force);
259268
}
260269

261270
/**

0 commit comments

Comments
 (0)