1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.linecorp.centraldogma.server.metadata;
18
19 import static com.google.common.collect.ImmutableMap.toImmutableMap;
20 import static java.util.Objects.requireNonNull;
21
22 import java.util.Map;
23 import java.util.Map.Entry;
24 import java.util.Objects;
25
26 import org.jspecify.annotations.Nullable;
27
28 import com.fasterxml.jackson.annotation.JsonCreator;
29 import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
30 import com.fasterxml.jackson.annotation.JsonInclude;
31 import com.fasterxml.jackson.annotation.JsonInclude.Include;
32 import com.fasterxml.jackson.annotation.JsonProperty;
33 import com.google.common.base.MoreObjects;
34 import com.google.common.collect.ImmutableMap;
35
36 import com.linecorp.centraldogma.common.RepositoryNotFoundException;
37 import com.linecorp.centraldogma.server.storage.project.Project;
38 import com.linecorp.centraldogma.server.storage.repository.HasWeight;
39
40
41
42
43 @JsonIgnoreProperties(ignoreUnknown = true)
44 @JsonInclude(Include.NON_NULL)
45 public class ProjectMetadata implements Identifiable, HasWeight {
46
47 public static final ProjectMetadata DOGMA_PROJECT_METADATA =
48 new ProjectMetadata("dogma",
49 ImmutableMap.of(),
50 ImmutableMap.of(),
51 null,
52 ImmutableMap.of(),
53 new UserAndTimestamp(User.SYSTEM.id()),
54 null);
55
56
57
58
59 private final String name;
60
61
62
63
64 private final Map<String, RepositoryMetadata> repos;
65
66
67
68
69 private final Map<String, Member> members;
70
71
72
73
74 private final Map<String, AppIdentityRegistration> appIds;
75
76
77
78
79 private final UserAndTimestamp creation;
80
81
82
83
84 @Nullable
85 private final UserAndTimestamp removal;
86
87
88
89
90 @JsonCreator
91 public ProjectMetadata(@JsonProperty("name") String name,
92 @JsonProperty("repos") Map<String, RepositoryMetadata> repos,
93 @JsonProperty("members") Map<String, Member> members,
94 @JsonProperty("tokens") @Nullable Map<String, AppIdentityRegistration> tokens,
95 @JsonProperty("appIds") @Nullable Map<String, AppIdentityRegistration> appIds,
96 @JsonProperty("creation") UserAndTimestamp creation,
97 @JsonProperty("removal") @Nullable UserAndTimestamp removal) {
98 this.name = requireNonNull(name, "name");
99 this.repos = ImmutableMap.copyOf(requireNonNull(repos, "repos"));
100 this.members = ImmutableMap.copyOf(requireNonNull(members, "members"));
101 if (tokens == null && appIds == null) {
102 throw new IllegalArgumentException("tokens or appIds are required");
103 }
104
105 if (appIds != null) {
106 this.appIds = ImmutableMap.copyOf(appIds);
107 } else {
108 this.appIds = ImmutableMap.copyOf(tokens);
109 }
110
111 this.creation = requireNonNull(creation, "creation");
112 this.removal = removal;
113 }
114
115 @Override
116 public String id() {
117 return name;
118 }
119
120
121
122
123 @JsonProperty
124 public String name() {
125 return name;
126 }
127
128
129
130
131 @JsonProperty
132 public Map<String, RepositoryMetadata> repos() {
133 return repos;
134 }
135
136
137
138
139 @JsonProperty
140 public Map<String, Member> members() {
141 return members;
142 }
143
144
145
146
147 @JsonProperty
148 public Map<String, AppIdentityRegistration> appIds() {
149 return appIds;
150 }
151
152
153
154
155 @JsonProperty
156 public UserAndTimestamp creation() {
157 return creation;
158 }
159
160
161
162
163 @Nullable
164 @JsonProperty
165 public UserAndTimestamp removal() {
166 return removal;
167 }
168
169
170
171
172 public RepositoryMetadata repo(String repoName) {
173 final RepositoryMetadata repositoryMetadata =
174 repos.get(requireNonNull(repoName, "repoName"));
175 if (repositoryMetadata != null) {
176 return repositoryMetadata;
177 }
178 throw RepositoryNotFoundException.of(name, repoName);
179 }
180
181
182
183
184 public Member member(String memberId) {
185 final Member member = memberOrDefault(memberId, null);
186 if (member != null) {
187 return member;
188 }
189 throw new MemberNotFoundException(memberId, name());
190 }
191
192
193
194
195
196 @Nullable
197 public Member memberOrDefault(String memberId, @Nullable Member defaultMember) {
198 final Member member = members.get(requireNonNull(memberId, "memberId"));
199 if (member != null) {
200 return member;
201 }
202 return defaultMember;
203 }
204
205
206
207
208 @Nullable
209 public AppIdentityRegistration appIdentityOrDefault(String appId,
210 @Nullable AppIdentityRegistration defaultAppIdentity) {
211 final AppIdentityRegistration appIdentityRegistration = appIds.get(requireNonNull(appId, "appId"));
212 if (appIdentityRegistration != null) {
213 return appIdentityRegistration;
214 }
215 return defaultAppIdentity;
216 }
217
218 @Override
219 public int weight() {
220 int weight = name().length();
221 for (RepositoryMetadata repo : repos.values()) {
222 weight += repo.weight();
223 }
224 for (Member member : members.values()) {
225 weight += member.weight();
226 }
227 for (AppIdentityRegistration appIdentityRegistration : appIds.values()) {
228 weight += appIdentityRegistration.weight();
229 }
230
231 return weight;
232 }
233
234 @Override
235 public boolean equals(Object o) {
236 if (this == o) {
237 return true;
238 }
239 if (!(o instanceof ProjectMetadata)) {
240 return false;
241 }
242 final ProjectMetadata that = (ProjectMetadata) o;
243 return name.equals(that.name) &&
244 repos.equals(that.repos) &&
245 members.equals(that.members) &&
246 appIds.equals(that.appIds) &&
247 creation.equals(that.creation) &&
248 Objects.equals(removal, that.removal);
249 }
250
251 @Override
252 public int hashCode() {
253 return Objects.hash(name, repos, members, appIds, creation, removal);
254 }
255
256 @Override
257 public String toString() {
258 return MoreObjects.toStringHelper(this)
259 .add("name", name())
260 .add("repos", repos())
261 .add("members", members())
262 .add("appIds", appIds())
263 .add("creation", creation())
264 .add("removal", removal())
265 .toString();
266 }
267
268
269
270
271 public ProjectMetadata withoutDogmaRepo() {
272 if (!repos().containsKey(Project.REPO_DOGMA)) {
273 return this;
274 }
275 final Map<String, RepositoryMetadata> filtered =
276 repos().entrySet().stream().filter(entry -> !Project.REPO_DOGMA.equals(entry.getKey()))
277 .collect(toImmutableMap(Entry::getKey, Entry::getValue));
278 return new ProjectMetadata(name(),
279 filtered,
280 members(),
281 null,
282 appIds(),
283 creation(),
284 removal());
285 }
286 }