1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package de.kaiserpfalzedv.commons.core.resources;
19
20 import java.time.OffsetDateTime;
21 import java.time.ZoneOffset;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.Optional;
25 import java.util.UUID;
26
27 import org.eclipse.microprofile.openapi.annotations.media.Schema;
28
29 import com.fasterxml.jackson.annotation.JsonIgnore;
30 import com.fasterxml.jackson.annotation.JsonInclude;
31 import com.fasterxml.jackson.annotation.JsonPropertyOrder;
32
33 import de.kaiserpfalzedv.commons.api.resources.HasTimestamps;
34 import de.kaiserpfalzedv.commons.api.resources.Metadata;
35 import de.kaiserpfalzedv.commons.api.resources.Pointer;
36 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
37 import jakarta.annotation.Nullable;
38 import jakarta.validation.constraints.Max;
39 import jakarta.validation.constraints.Min;
40 import jakarta.validation.constraints.NotNull;
41 import jakarta.validation.constraints.Pattern;
42 import jakarta.validation.constraints.Size;
43 import lombok.AllArgsConstructor;
44 import lombok.Builder;
45 import lombok.EqualsAndHashCode;
46 import lombok.Getter;
47 import lombok.NoArgsConstructor;
48 import lombok.ToString;
49 import lombok.extern.jackson.Jacksonized;
50
51
52
53
54
55
56
57
58
59
60 @SuppressFBWarnings(value = "EI_EXPOSE_REF2", justification = "Use of lombok provided builder.")
61 @Jacksonized
62 @Builder(toBuilder = true)
63 @AllArgsConstructor
64 @NoArgsConstructor
65 @Getter
66 @ToString(onlyExplicitlyIncluded = true)
67 @EqualsAndHashCode(onlyExplicitlyIncluded = true)
68 @JsonInclude(JsonInclude.Include.NON_ABSENT)
69 @JsonPropertyOrder({"identity,uid,generation,owner,created,deleted,annotations,labels,selfLink"})
70 @Schema(
71 name = "ResourceMetadata",
72 description = "The metadata of a resource."
73 )
74 public class MetadataImpl implements Metadata {
75
76 @SuppressWarnings("unused")
77 private static final long serialVersionUID = 0L;
78
79 @Schema(
80 name = "identity",
81 description = "This is the identity of the resource.",
82 implementation = Pointer.class
83 )
84 @ToString.Include
85 @EqualsAndHashCode.Include
86 @NotNull
87 private de.kaiserpfalzedv.commons.core.resources.PointerImpl identity;
88
89 @ToString.Include
90 @EqualsAndHashCode.Include
91 @Builder.Default
92 @NotNull
93 private final UUID uid = UUID.randomUUID();
94
95 @Schema(
96 name = "generation",
97 description = "The generation of this object. Every change adds 1.",
98 required = true,
99 defaultValue = "0",
100 minimum = "0",
101 maxItems = Integer.MAX_VALUE
102 )
103 @ToString.Include
104 @Builder.Default
105 @NotNull
106 @Min(value = 0, message = "The generation must be at least 0.")
107 @Max(value = Integer.MAX_VALUE, message = "The generation must not be bigger than " + Integer.MAX_VALUE + ".")
108 private final Integer generation = 0;
109
110 @Schema(
111 name = "owner",
112 description = "The owning resource. This is a sub-resource or managed resource of the given address.",
113 required = false,
114 nullable = true,
115 implementation = Pointer.class
116 )
117 @Nullable
118 @Builder.Default
119 private final PointerImpl owner = null;
120
121 @Builder.Default
122 @NotNull
123 @Size(min = HasTimestamps.VALID_LENGTH, max = HasTimestamps.VALID_LENGTH, message = HasTimestamps.VALID_LENGTH_MSG)
124 @Pattern(regexp = HasTimestamps.VALID_PATTERN, message = HasTimestamps.VALID_PATTERN_MSG)
125 protected OffsetDateTime created = OffsetDateTime.now(ZoneOffset.UTC);
126
127 @Builder.Default
128 @NotNull
129 @Size(min = HasTimestamps.VALID_LENGTH, max = HasTimestamps.VALID_LENGTH, message = HasTimestamps.VALID_LENGTH_MSG)
130 @Pattern(regexp = HasTimestamps.VALID_PATTERN, message = HasTimestamps.VALID_PATTERN_MSG)
131 protected OffsetDateTime modified = OffsetDateTime.now(ZoneOffset.UTC);
132
133 @Builder.Default
134 @Nullable
135 private final OffsetDateTime deleted = null;
136
137 @Schema(
138 name = "annotations",
139 description = "A set of annotations to this resource.",
140 nullable = true,
141 minItems = 0,
142 maxItems = 256
143 )
144 @Builder.Default
145 @Nullable
146 @SuppressFBWarnings(value = {"EI_EXPOSE_REP","EI_EXPOSE_REP2"}, justification = "lombok provided @Getter are created")
147 private final Map<String, String> annotations = new HashMap<>();
148
149 @Schema(
150 name = "labels",
151 description = "A set of labels to this resource.",
152 nullable = true,
153 minItems = 0,
154 maxItems = 256
155 )
156 @Builder.Default
157 @Nullable
158 @SuppressFBWarnings(value = {"EI_EXPOSE_REP","EI_EXPOSE_REP2"}, justification = "lombok provided @Getter are created")
159 private final Map<String, String> labels = new HashMap<>();
160
161
162 @Override
163 @JsonIgnore
164 @NotNull
165 public Optional<OffsetDateTime> getDeletionTimestamp() {
166 return Optional.ofNullable(this.deleted);
167 }
168
169 @Override
170 @JsonIgnore
171 @NotNull
172 public Optional<de.kaiserpfalzedv.commons.api.resources.Pointer> getOwningResource() {
173 return Optional.ofNullable(this.owner);
174 }
175
176 @Override
177 @NotNull
178 public MetadataImpl increaseGeneration() {
179 return this.toBuilder()
180 .generation(this.generation + 1)
181 .build();
182 }
183
184
185
186
187
188
189
190
191
192
193
194 @NotNull
195 public static MetadataImplBuilder of(
196 final String kind,
197 final String apiVersion,
198 final String nameSpace,
199 final String name
200 ) {
201 return MetadataImpl.builder()
202 .identity(
203 de.kaiserpfalzedv.commons.core.resources.PointerImpl.builder()
204 .kind(kind)
205 .apiVersion(apiVersion)
206 .nameSpace(nameSpace)
207 .name(name)
208 .build()
209 );
210 }
211
212
213 @SuppressWarnings({"MethodDoesntCallSuperMethod","java:S1182","java:S2975"})
214 @SuppressFBWarnings(value = "CN_IDIOM_NO_SUPER_CALL", justification = "Using the lombok builder.")
215 @Override
216 public MetadataImpl clone() {
217 return this.toBuilder().build();
218 }
219 }