Skip to content

Commit 045a6e9

Browse files
committed
chore: misc cleanup
1 parent aab7300 commit 045a6e9

16 files changed

Lines changed: 157 additions & 60 deletions

‎src/main/java/io/papermc/fill/SharedConstants.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public final class SharedConstants {
2929
public static final String API_V2_ROUTE_PREFIX = "/v2/";
3030
public static final String API_V3_ROUTE_PREFIX = "/v3/";
3131

32+
public static final Instant API_V1_SUNSET = LocalDate.of(2021, Month.NOVEMBER, 24)
33+
.atStartOfDay(ZoneOffset.UTC)
34+
.toInstant();
3235
public static final Instant API_V2_CUTOFF = LocalDate.of(2025, Month.DECEMBER, 31)
3336
.atStartOfDay(ZoneOffset.UTC)
3437
.toInstant();
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2024 PaperMC
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+
* http://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+
package io.papermc.fill.configuration;
17+
18+
import java.time.Clock;
19+
import java.time.ZoneOffset;
20+
import org.jspecify.annotations.NullMarked;
21+
import org.springframework.context.annotation.Bean;
22+
import org.springframework.context.annotation.Configuration;
23+
24+
@Configuration
25+
@NullMarked
26+
public class TimeConfiguration {
27+
@Bean
28+
public Clock clock() {
29+
return Clock.system(ZoneOffset.UTC);
30+
}
31+
}

‎src/main/java/io/papermc/fill/controller/Data2Controller.java‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,15 @@
2727
import io.papermc.fill.exception.DownloadNotFoundException;
2828
import io.papermc.fill.exception.ProjectNotFoundException;
2929
import io.papermc.fill.exception.StorageReadException;
30+
import io.papermc.fill.exception.SunsetException;
3031
import io.papermc.fill.exception.VersionNotFoundException;
3132
import io.papermc.fill.model.Download;
3233
import io.papermc.fill.service.StorageService;
3334
import io.papermc.fill.util.http.Caching;
3435
import io.papermc.fill.util.http.Responses;
3536
import io.swagger.v3.oas.annotations.Hidden;
3637
import jakarta.validation.constraints.PositiveOrZero;
38+
import java.time.Clock;
3739
import java.time.Duration;
3840
import org.jspecify.annotations.NullMarked;
3941
import org.springframework.beans.factory.annotation.Autowired;
@@ -52,19 +54,21 @@
5254
public class Data2Controller {
5355
private static final Duration CACHE_LENGTH_DOWNLOAD = Duration.ofDays(7);
5456

57+
private final Clock clock;
5558
private final ProjectRepository projects;
5659
private final VersionRepository versions;
5760
private final BuildRepository builds;
58-
5961
private final StorageService storage;
6062

6163
@Autowired
6264
public Data2Controller(
65+
final Clock clock,
6366
final ProjectRepository projects,
6467
final VersionRepository versions,
6568
final BuildRepository builds,
6669
final StorageService storage
6770
) {
71+
this.clock = clock;
6872
this.projects = projects;
6973
this.versions = versions;
7074
this.builds = builds;
@@ -83,6 +87,9 @@ public ResponseEntity<?> getDownload(
8387
@PathVariable("download")
8488
final String downloadName
8589
) {
90+
if (this.isSunset()) {
91+
throw new SunsetException();
92+
}
8693
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
8794
final VersionEntity version = this.versions.findByProjectAndKey(project, versionKey).orElseThrow(VersionNotFoundException::new);
8895
if (version.createdAt().isAfter(SharedConstants.API_V2_CUTOFF)) {
@@ -124,4 +131,8 @@ public ResponseEntity<?> getDownload(
124131

125132
throw new DownloadNotFoundException();
126133
}
134+
135+
private boolean isSunset() {
136+
return this.clock.instant().isAfter(SharedConstants.API_V2_SUNSET);
137+
}
127138
}

‎src/main/java/io/papermc/fill/controller/GraphMutationController.java‎

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@
4848
import io.papermc.fill.model.BuildChannel;
4949
import io.papermc.fill.model.Java;
5050
import io.papermc.fill.model.Support;
51-
import io.papermc.fill.model.SupportStatus;
51+
import java.time.Clock;
5252
import java.time.Instant;
53+
import java.util.Date;
5354
import org.bson.types.ObjectId;
5455
import org.jspecify.annotations.NullMarked;
5556
import org.springframework.beans.factory.annotation.Autowired;
@@ -61,18 +62,21 @@
6162
@Controller
6263
@NullMarked
6364
public class GraphMutationController {
65+
private final Clock clock;
6466
private final ProjectRepository projects;
6567
private final FamilyRepository families;
6668
private final VersionRepository versions;
6769
private final BuildRepository builds;
6870

6971
@Autowired
7072
public GraphMutationController(
73+
final Clock clock,
7174
final ProjectRepository projects,
7275
final FamilyRepository families,
7376
final VersionRepository versions,
7477
final BuildRepository builds
7578
) {
79+
this.clock = clock;
7680
this.projects = projects;
7781
this.families = families;
7882
this.versions = versions;
@@ -89,9 +93,10 @@ public CreateFamilyPayload createFamily(
8993
if (this.families.findByProjectAndKey(project, input.key()).isPresent()) {
9094
throw new DuplicateFamilyException();
9195
}
96+
final Instant createdAt = this.clock.instant();
9297
final FamilyEntity entity = this.families.save(FamilyEntity.create(
93-
new ObjectId(),
94-
Instant.now(),
98+
new ObjectId(Date.from(createdAt)),
99+
createdAt,
95100
project,
96101
input.key(),
97102
input.java()
@@ -141,14 +146,15 @@ public CreateVersionPayload createVersion(
141146
if (this.versions.findByProjectAndKey(project, input.key()).isPresent()) {
142147
throw new DuplicateVersionException();
143148
}
149+
final Instant createdAt = this.clock.instant();
144150
final VersionEntity entity = this.versions.save(VersionEntity.create(
145-
new ObjectId(),
146-
Instant.now(),
151+
new ObjectId(Date.from(createdAt)),
152+
createdAt,
147153
project,
148154
family,
149155
input.key(),
150156
null,
151-
new Support(SupportStatus.SUPPORTED, null),
157+
Support.SUPPORTED,
152158
input.java()
153159
));
154160
return new CreateVersionPayload(entity);

‎src/main/java/io/papermc/fill/controller/GraphQueryController.java‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@
3838
import io.papermc.fill.model.BuildWithDownloadsImpl;
3939
import io.papermc.fill.model.Commit;
4040
import io.papermc.fill.model.DownloadWithUrl;
41-
import io.papermc.fill.model.Family;
4241
import io.papermc.fill.model.Java;
42+
import io.papermc.fill.model.Keyed;
4343
import io.papermc.fill.model.Project;
4444
import io.papermc.fill.model.Support;
4545
import io.papermc.fill.model.SupportStatus;
46+
import io.papermc.fill.model.Timestamped;
4647
import io.papermc.fill.model.Version;
4748
import io.papermc.fill.service.StorageService;
4849
import io.papermc.fill.util.graphql.CursorCodec;
@@ -86,7 +87,6 @@ public class GraphQueryController {
8687
private final FamilyRepository families;
8788
private final VersionRepository versions;
8889
private final BuildRepository builds;
89-
9090
private final StorageService storage;
9191

9292
@Autowired
@@ -108,7 +108,7 @@ public GraphQueryController(
108108
public List<ProjectEntity> getProjects() {
109109
return this.projects.findAll()
110110
.stream()
111-
.sorted(Project.COMPARATOR_KEY)
111+
.sorted(Keyed.KEY_ASC)
112112
.toList();
113113
}
114114

@@ -140,7 +140,7 @@ public List<FamilyEntity> mapProjectFamilies(
140140
final ProjectEntity project
141141
) {
142142
Stream<FamilyEntity> families = this.families.findAllByProject(project);
143-
families = families.sorted(Family.COMPARATOR_CREATED_AT_REVERSE);
143+
families = families.sorted(Timestamped.CREATED_AT_DESC);
144144
return families.toList();
145145
}
146146

‎src/main/java/io/papermc/fill/controller/Meta2Controller.java‎

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@
3030
import io.papermc.fill.exception.BuildNotFoundException;
3131
import io.papermc.fill.exception.FamilyNotFoundException;
3232
import io.papermc.fill.exception.ProjectNotFoundException;
33+
import io.papermc.fill.exception.SunsetException;
3334
import io.papermc.fill.exception.VersionNotFoundException;
3435
import io.papermc.fill.model.Build;
3536
import io.papermc.fill.model.BuildChannel;
3637
import io.papermc.fill.model.Commit;
3738
import io.papermc.fill.model.Download;
38-
import io.papermc.fill.model.Family;
3939
import io.papermc.fill.model.Keyed;
40-
import io.papermc.fill.model.Version;
40+
import io.papermc.fill.model.Timestamped;
4141
import io.papermc.fill.model.response.v2.BuildResponse;
4242
import io.papermc.fill.model.response.v2.BuildsResponse;
4343
import io.papermc.fill.model.response.v2.FamilyBuildsResponse;
@@ -51,6 +51,7 @@
5151
import io.papermc.fill.util.http.Responses;
5252
import io.swagger.v3.oas.annotations.tags.Tag;
5353
import jakarta.validation.constraints.PositiveOrZero;
54+
import java.time.Clock;
5455
import java.time.Duration;
5556
import java.util.List;
5657
import java.util.Map;
@@ -79,21 +80,23 @@ public class Meta2Controller {
7980
private static final Duration CACHE_LENGTH_VERSION_BUILDS = Duration.ofMinutes(5);
8081
private static final Duration CACHE_LENGTH_BUILD = Duration.ofDays(7);
8182

83+
private final Clock clock;
8284
private final ApplicationApiProperties properties;
83-
8485
private final ProjectRepository projects;
8586
private final FamilyRepository families;
8687
private final VersionRepository versions;
8788
private final BuildRepository builds;
8889

8990
@Autowired
9091
public Meta2Controller(
92+
final Clock clock,
9193
final ApplicationApiProperties properties,
9294
final ProjectRepository projects,
9395
final FamilyRepository families,
9496
final VersionRepository versions,
9597
final BuildRepository builds
9698
) {
99+
this.clock = clock;
97100
this.properties = properties;
98101
this.projects = projects;
99102
this.families = families;
@@ -104,6 +107,9 @@ public Meta2Controller(
104107
@CrossOrigin(methods = RequestMethod.GET)
105108
@GetMapping("/v2/projects")
106109
public ResponseEntity<?> getProjects() {
110+
if (this.isSunset()) {
111+
throw new SunsetException();
112+
}
107113
final List<ProjectEntity> projects = this.projects.findAll();
108114
final ProjectsResponse response = new ProjectsResponse(Keyed.keysOf(projects));
109115
return Responses.ok(response, Caching.publicShared(CACHE_LENGTH_PROJECTS));
@@ -115,14 +121,17 @@ public ResponseEntity<?> getProject(
115121
@PathVariable("project")
116122
final String projectKey
117123
) {
124+
if (this.isSunset()) {
125+
throw new SunsetException();
126+
}
118127
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
119128
final List<FamilyEntity> families = this.families.findAllByProject(project)
120129
.filter(family -> family.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
121-
.sorted(Family.COMPARATOR_CREATED_AT)
130+
.sorted(Timestamped.CREATED_AT_ASC)
122131
.toList();
123132
final List<VersionEntity> versions = this.versions.findAllByProject(project)
124133
.filter(version -> version.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
125-
.sorted(Version.COMPARATOR_CREATED_AT)
134+
.sorted(Timestamped.CREATED_AT_ASC)
126135
.toList();
127136
final ProjectResponse response = new ProjectResponse(
128137
project.key(),
@@ -141,14 +150,17 @@ public ResponseEntity<?> getFamily(
141150
@PathVariable("family")
142151
final String familyKey
143152
) {
153+
if (this.isSunset()) {
154+
throw new SunsetException();
155+
}
144156
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
145157
final FamilyEntity family = this.families.findByProjectAndKey(project, familyKey).orElseThrow(FamilyNotFoundException::new);
146158
if (family.createdAt().isAfter(SharedConstants.API_V2_CUTOFF)) {
147159
throw new FamilyNotFoundException();
148160
}
149161
final List<VersionEntity> versions = this.versions.findAllByFamily(family)
150162
.filter(version -> version.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
151-
.sorted(Version.COMPARATOR_CREATED_AT)
163+
.sorted(Timestamped.CREATED_AT_ASC)
152164
.toList();
153165
final FamilyResponse response = new FamilyResponse(
154166
project.key(),
@@ -167,20 +179,23 @@ public ResponseEntity<?> getFamilyBuilds(
167179
@PathVariable("family")
168180
final String familyKey
169181
) {
182+
if (this.isSunset()) {
183+
throw new SunsetException();
184+
}
170185
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
171186
final FamilyEntity family = this.families.findByProjectAndKey(project, familyKey).orElseThrow(FamilyNotFoundException::new);
172187
if (family.createdAt().isAfter(SharedConstants.API_V2_CUTOFF)) {
173188
throw new FamilyNotFoundException();
174189
}
175190
final List<VersionEntity> versions = this.versions.findAllByFamily(family)
176191
.filter(version -> version.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
177-
.sorted(Version.COMPARATOR_CREATED_AT)
192+
.sorted(Timestamped.CREATED_AT_ASC)
178193
.toList();
179194
final Map<ObjectId, VersionEntity> versionsById = versions.stream()
180195
.collect(Collectors.toMap(AbstractEntity::_id, Function.identity()));
181196
final List<BuildEntity> builds = this.builds.findAllByVersionIn(versionsById.keySet())
182197
.filter(build -> build.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
183-
.sorted(Build.COMPARATOR_NUMBER)
198+
.sorted(Build.NUMBER_ASC)
184199
.toList();
185200
final FamilyBuildsResponse response = new FamilyBuildsResponse(
186201
project.key(),
@@ -208,14 +223,17 @@ public ResponseEntity<?> getVersion(
208223
@PathVariable("version")
209224
final String versionKey
210225
) {
226+
if (this.isSunset()) {
227+
throw new SunsetException();
228+
}
211229
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
212230
final VersionEntity version = this.versions.findByProjectAndKey(project, versionKey).orElseThrow(VersionNotFoundException::new);
213231
if (version.createdAt().isAfter(SharedConstants.API_V2_CUTOFF)) {
214232
throw new VersionNotFoundException();
215233
}
216234
final List<BuildEntity> builds = this.builds.findAllByVersion(version)
217235
.filter(build -> build.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
218-
.sorted(Build.COMPARATOR_NUMBER)
236+
.sorted(Build.NUMBER_ASC)
219237
.toList();
220238
final VersionResponse response = new VersionResponse(
221239
project.key(),
@@ -234,14 +252,17 @@ public ResponseEntity<?> getVersionBuilds(
234252
@PathVariable("version")
235253
final String versionKey
236254
) {
255+
if (this.isSunset()) {
256+
throw new SunsetException();
257+
}
237258
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
238259
final VersionEntity version = this.versions.findByProjectAndKey(project, versionKey).orElseThrow(VersionNotFoundException::new);
239260
if (version.createdAt().isAfter(SharedConstants.API_V2_CUTOFF)) {
240261
throw new VersionNotFoundException();
241262
}
242263
final List<BuildEntity> builds = this.builds.findAllByVersion(version)
243264
.filter(build -> build.createdAt().isBefore(SharedConstants.API_V2_CUTOFF))
244-
.sorted(Build.COMPARATOR_NUMBER)
265+
.sorted(Build.NUMBER_ASC)
245266
.toList();
246267
final BuildsResponse response = new BuildsResponse(
247268
project.key(),
@@ -270,6 +291,9 @@ public ResponseEntity<?> getVersionBuild(
270291
@PositiveOrZero
271292
final int buildNumber
272293
) {
294+
if (this.isSunset()) {
295+
throw new SunsetException();
296+
}
273297
final ProjectEntity project = this.projects.findByKey(projectKey).orElseThrow(ProjectNotFoundException::new);
274298
final VersionEntity version = this.versions.findByProjectAndKey(project, versionKey).orElseThrow(VersionNotFoundException::new);
275299
if (version.createdAt().isAfter(SharedConstants.API_V2_CUTOFF)) {
@@ -293,6 +317,10 @@ public ResponseEntity<?> getVersionBuild(
293317
return Responses.ok(response, Caching.publicShared(CACHE_LENGTH_BUILD));
294318
}
295319

320+
private boolean isSunset() {
321+
return this.clock.instant().isAfter(SharedConstants.API_V2_SUNSET);
322+
}
323+
296324
private static boolean isPromoted(final Build build) {
297325
return build.channel() == BuildChannel.RECOMMENDED;
298326
}

0 commit comments

Comments
 (0)