View Javadoc
1   /*
2    * Copyright (c) 2022-2023. Roland T. Lichti, Kaiserpfalz EDV-Service.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU General Public License for more details.
13   *
14   * You should have received a copy of the GNU General Public License
15   * along with this program.  If not, see <https://www.gnu.org/licenses/>.
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   * Metadata -- common data for every resource of the system.
53   * <p>
54   * Default values for the lombok builder are set in {@link MetadataBuilder}.
55   *
56   * @author klenkes74 {@literal <rlichti@kaiserpfalz-edv.de>}
57   * @since 2.0.0  2021-05-24
58   * @version 2.0.2 2022-01-04
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      /** serial class version */
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      * Generates a metadata builder with the given identity.
187      *
188      * @param kind       the kind of resource.
189      * @param apiVersion the api version of the resource.
190      * @param nameSpace  the namespace of the resource.
191      * @param name       the name of the resource.
192      * @return A metadata builder for adding the other metadata.
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 }