Skip to content

Commit 033eceb

Browse files
committed
move label and annotations under metadata node
1 parent a08176f commit 033eceb

File tree

4 files changed

+171
-16
lines changed

4 files changed

+171
-16
lines changed

cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsV3.java

Lines changed: 60 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,11 @@
3030
import java.util.Map;
3131
import java.util.Optional;
3232
import java.util.TreeMap;
33+
import java.util.HashMap;
3334
import java.util.regex.Pattern;
3435
import java.util.stream.Stream;
36+
37+
import org.cloudfoundry.client.v3.Metadata;
3538
import org.cloudfoundry.client.v3.processes.HealthCheckType;
3639
import org.cloudfoundry.client.v3.processes.ReadinessHealthCheckType;
3740
import org.yaml.snakeyaml.DumperOptions;
@@ -172,8 +175,13 @@ private static ManifestV3Application.Builder toApplicationManifest(
172175
variables,
173176
raw -> getSidecar((Map<String, Object>) raw, variables),
174177
builder::sidecar);
175-
as(application, "labels", variables, Map.class::cast, builder::labels);
176-
as(application, "annotations", variables, Map.class::cast, builder::annotations);
178+
179+
as(application,
180+
"metadata",
181+
variables,
182+
raw -> getMetadata((Map<String, Object>) raw, variables),
183+
builder::metadata);
184+
177185
asBoolean(application, "default-route", variables, builder::defaultRoute);
178186

179187
return builder;
@@ -253,6 +261,46 @@ private static ManifestV3Service getService(Object raw, Map<String, String> vari
253261
return builder.build();
254262
}
255263

264+
private static Metadata getMetadata(
265+
Map<String, Object> raw,
266+
Map<String, String> variables) {
267+
268+
if (raw == null) return null;
269+
270+
Map<String, String> labels = new HashMap<>();
271+
Map<String, String> annotations = new HashMap<>();
272+
273+
asMap(
274+
raw,
275+
"labels",
276+
variables,
277+
String.class::cast,
278+
labels::put
279+
);
280+
281+
asMap(
282+
raw,
283+
"annotations",
284+
variables,
285+
String.class::cast,
286+
annotations::put
287+
);
288+
289+
if (labels.isEmpty() && annotations.isEmpty()) {
290+
return null;
291+
}
292+
293+
Metadata.Builder builder = Metadata.builder();
294+
if (!labels.isEmpty()) {
295+
builder.labels(labels);
296+
}
297+
if (!annotations.isEmpty()) {
298+
builder.annotations(annotations);
299+
}
300+
return builder.build();
301+
}
302+
303+
256304
private static Map<String, Object> toYaml(ManifestV3 manifest) {
257305
Map<String, Object> yaml = new TreeMap<>();
258306
yaml.put("version", manifest.getVersion());
@@ -282,8 +330,8 @@ private static Map<String, Object> toApplicationYaml(ManifestV3Application appli
282330
"sidecars",
283331
convertCollection(
284332
application.getSidecars(), ApplicationManifestUtilsV3::toSidecarsYaml));
285-
putIfPresent(yaml, "labels", application.getLabels());
286-
putIfPresent(yaml, "annotations", application.getAnnotations());
333+
334+
putIfPresent(yaml, "metadata", toMetadataYaml(application.getMetadata()));
287335
return yaml;
288336
}
289337

@@ -337,4 +385,12 @@ private static Map<String, Object> toProcessYaml(ManifestV3Process process) {
337385
putIfPresent(yaml, "timeout", process.getTimeout());
338386
return yaml;
339387
}
388+
389+
private static Map<String, Object> toMetadataYaml(Metadata metadata) {
390+
if (metadata == null) return null;
391+
Map<String, Object> map = new HashMap<>();
392+
putIfPresent(map, "labels", metadata.getLabels());
393+
putIfPresent(map, "annotations", metadata.getAnnotations());
394+
return map.isEmpty() ? null : map;
395+
}
340396
}

cloudfoundry-operations/src/main/java/org/cloudfoundry/operations/applications/_ManifestV3Application.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616

1717
package org.cloudfoundry.operations.applications;
1818

19-
20-
import org.cloudfoundry.AllowNulls;
2119
import org.cloudfoundry.Nullable;
2220
import org.immutables.value.Value;
21+
import org.cloudfoundry.client.v3.Metadata;
2322

2423
import java.util.List;
2524
import java.util.Map;
@@ -31,25 +30,17 @@
3130
@Value.Immutable
3231
abstract class _ManifestV3Application extends _ApplicationManifestCommon {
3332

34-
/**
35-
* The annotations configured for this application
36-
*/
37-
@AllowNulls
38-
@Nullable
39-
abstract Map<String, String> getAnnotations();
40-
4133
/**
4234
* Generate a default route based on the application name
4335
*/
4436
@Nullable
4537
abstract Boolean getDefaultRoute();
4638

4739
/**
48-
* The labels configured for this application
40+
* The metadta for this application
4941
*/
50-
@AllowNulls
5142
@Nullable
52-
abstract Map<String, String> getLabels();
43+
abstract Metadata getMetadata();
5344

5445
/**
5546
* The collection of processes configured for this application

cloudfoundry-operations/src/test/java/org/cloudfoundry/operations/applications/ApplicationManifestUtilsV3Test.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
import java.io.IOException;
66
import java.nio.file.Files;
77
import java.nio.file.Path;
8+
89
import org.cloudfoundry.client.v3.processes.ReadinessHealthCheckType;
10+
import org.cloudfoundry.client.v3.Metadata;
911
import org.junit.jupiter.api.Test;
1012

1113
class ApplicationManifestUtilsV3Test {
@@ -60,6 +62,52 @@ void testWithDockerApp() throws IOException {
6062
assertSerializeDeserialize(manifest);
6163
}
6264

65+
@Test
66+
void testWithMetadata() throws IOException {
67+
ManifestV3 manifest =
68+
ManifestV3.builder()
69+
.application(
70+
ManifestV3Application.builder()
71+
.name("test-app")
72+
.metadata(
73+
Metadata.builder()
74+
.label("test-label", "test-label-value")
75+
.annotation("test-annotation", "test-annotation-value")
76+
.build())
77+
.build())
78+
.build();
79+
80+
assertSerializeDeserialize(manifest);
81+
}
82+
83+
@Test
84+
void testWithMetadataOnlyLabel() throws IOException {
85+
ManifestV3 manifest =
86+
ManifestV3.builder()
87+
.application(
88+
ManifestV3Application.builder()
89+
.name("test-app")
90+
.metadata(Metadata.builder().label("test-label", "test-label-value").build())
91+
.build())
92+
.build();
93+
94+
assertSerializeDeserialize(manifest);
95+
}
96+
97+
@Test
98+
void testWithMetadataOnlyAnnotation() throws IOException {
99+
ManifestV3 manifest =
100+
ManifestV3.builder()
101+
.application(
102+
ManifestV3Application.builder()
103+
.name("test-app")
104+
.metadata(Metadata.builder().annotation("test-annotation", "test-annotation-value").build())
105+
.build())
106+
.build();
107+
108+
assertSerializeDeserialize(manifest);
109+
}
110+
63111
private void assertSerializeDeserialize(ManifestV3 manifest) throws IOException {
64112
Path file = Files.createTempFile("test-manifest-", ".yml");
65113
ApplicationManifestUtilsV3.write(file, manifest);

integration-test/src/test/java/org/cloudfoundry/operations/ApplicationsTest.java

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public final class ApplicationsTest extends AbstractIntegrationTest {
100100
private static final String DEFAULT_ROUTER_GROUP = "default-tcp";
101101

102102
@Autowired private CloudFoundryOperations cloudFoundryOperations;
103+
@Autowired private org.cloudfoundry.client.CloudFoundryClient cloudFoundryClient;
103104

104105
@Autowired private String organizationName;
105106

@@ -789,6 +790,65 @@ public void pushManifestV3() throws IOException {
789790
.verify(Duration.ofMinutes(5));
790791
}
791792

793+
@Test
794+
@IfCloudFoundryVersion(greaterThanOrEqualTo = CloudFoundryVersion.PCF_4_v2)
795+
public void pushManifestV3WithMetadata() throws IOException {
796+
String applicationName = this.nameFactory.getApplicationName();
797+
798+
ManifestV3 manifest =
799+
ManifestV3.builder()
800+
.application(
801+
ManifestV3Application.builder()
802+
.buildpack("staticfile_buildpack")
803+
.disk(512)
804+
.healthCheckType(ApplicationHealthCheck.PORT)
805+
.memory(64)
806+
.name(applicationName)
807+
.metadata(
808+
org.cloudfoundry.client.v3.Metadata.builder()
809+
.label("test-label", "test-label-value")
810+
.annotation("test-annotation", "test-annotation-value")
811+
.build()
812+
)
813+
.path(
814+
new ClassPathResource("test-application.zip")
815+
.getFile()
816+
.toPath())
817+
.build())
818+
.build();
819+
820+
this.cloudFoundryOperations
821+
.applications()
822+
.pushManifestV3(PushManifestV3Request.builder().manifest(manifest).build())
823+
.then(
824+
// fetch application id via operations API
825+
this.cloudFoundryOperations
826+
.applications()
827+
.get(
828+
org.cloudfoundry.operations.applications.GetApplicationRequest
829+
.builder()
830+
.name(applicationName)
831+
.build())
832+
.map(org.cloudfoundry.operations.applications.ApplicationDetail::getId))
833+
.flatMap(
834+
appId ->
835+
this.cloudFoundryClient
836+
.applicationsV3()
837+
.get(
838+
org.cloudfoundry.client.v3.applications
839+
.GetApplicationRequest
840+
.builder()
841+
.applicationId(appId)
842+
.build()))
843+
.map(
844+
response ->
845+
response.getMetadata().getLabels().get("test-label"))
846+
.as(StepVerifier::create)
847+
.expectNext("test-value")
848+
.expectComplete()
849+
.verify(Duration.ofMinutes(5));
850+
}
851+
792852
@Test
793853
@IfCloudFoundryVersion(
794854
greaterThanOrEqualTo =

0 commit comments

Comments
 (0)