Skip to content

Commit

Permalink
Merge branch 'release/0.3.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
micheljung committed Mar 14, 2017
2 parents 8130c4c + 9eea6af commit 279f800
Show file tree
Hide file tree
Showing 39 changed files with 1,214 additions and 651 deletions.
14 changes: 11 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'propdeps'

group = 'micheljung'
version = '0.3.3'
version = '0.3.4'

sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories {
mavenCentral()
maven { url "http://repo.jenkins-ci.org/public/" }
maven { url "https://jitpack.io" }
}

Expand Down Expand Up @@ -105,7 +106,7 @@ task createDockerfile(type: Dockerfile, dependsOn: dockerCopyDistResources) {

runCommand 'chmod +x default-cmd.sh'

exposePort 8080
exposePort 8010

defaultCommand './default-cmd.sh', "/${project.name}-${project.version}/bin/${project.name}"
}
Expand All @@ -123,6 +124,11 @@ task pushDockerImage(type: DockerPushImage, dependsOn: buildDockerImage) {
tag project.version
}

configurations.all {
// Cache -SNAPSHOT for 60 seconds only
resolutionStrategy.cacheChangingModulesFor 60, 'seconds'
}

dependencyManagement {
dependencies {
dependency("org.hibernate:hibernate-core:${hibernateVersion}")
Expand All @@ -140,11 +146,13 @@ dependencies {
compile("org.springframework.boot:spring-boot-starter-security")
compile("de.codecentric:spring-boot-admin-starter-client:${springBootAdminClientVersion}")

compile("com.github.FAForever:faf-java-commons:${fafCommonsVersion}")
compile("org.kohsuke:github-api:1.84")
compile("org.jolokia:jolokia-core:${jolokiaVersion}")
compile("org.springframework.security:spring-security-jwt:${springSecurityJwtVersion}")
compile("org.springframework.security.oauth:spring-security-oauth2:${springSecurityOauth2Version}")
compile("org.springframework:spring-context-support:${springContextSupportVersion}")

compile("org.eclipse.jgit:org.eclipse.jgit:${jgitVersionn}")
compile("org.jetbrains:annotations:${jetbrainsAnnotationsVersion}")
compile("com.google.guava:guava:${guavaVersion}")
compile("io.springfox:springfox-swagger-ui:${swaggerVersion}")
Expand Down
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,8 @@ luajVersion=3.0.1
nocatchVersion=1.1
junitAddonsVersion=1.4
zohhakVersion=1.1.1
githubApiVersion=1.84
jgitVersionn=4.5.0.201609210915-r
fafCommonsVersion=76fb583d146082f3db68c0bece38a3ee28ead8e6
h2Version=1.4.193
jacksonDatatypeJsr310Version=2.8.6
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.springframework.web.bind.annotation.RestController;

import javax.inject.Inject;
import java.time.Instant;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
Expand All @@ -29,6 +30,10 @@ public PlayerAchievementsController(AchievementsService achievementsService) {
@ApiOperation(value = "Updates the state and progress of one or multiple achievements.")
public List<AchievementUpdateResponse> update(@RequestBody AchievementUpdateRequest[] updateRequests,
@AuthenticationPrincipal FafUserDetails userDetails) {
// FIXME protect using OAuth scope, so that only the server is allowed to send requests
if (Instant.now().toEpochMilli() > 0) {
throw new UnsupportedOperationException("Not yet supported");
}
int playerId = userDetails.getId();
return Arrays.stream(updateRequests).map(achievementUpdateRequest -> {
switch (achievementUpdateRequest.getOperation()) {
Expand Down
93 changes: 77 additions & 16 deletions src/main/java/com/faforever/api/config/FafApiProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,71 +6,132 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;

@Data
@ConfigurationProperties(prefix = "faf-api", ignoreUnknownFields = false)
public class FafApiProperties {
/**
* The secret used for JWT token generation.
* The API version.
*/
private String jwtSecret = "banana";
private String version = "dev";
private String version;
private Jwt jwt = new Jwt();
private OAuth2 oAuth2 = new OAuth2();
private Async async = new Async();
private Map map = new Map();
private Mod mod = new Mod();
private Replay replay = new Replay();
private Clan clan = new Clan();
private FeaturedMods featuredMods = new FeaturedMods();
private GitHub gitHub = new GitHub();
private Deployment deployment = new Deployment();

@Data
public static class OAuth2 {

private String resourceId = "faf-api";
}

@Data
public static class Jwt {

/**
* The secret used for JWT token generation.
*/
private String secret = "secret";
private int accessTokenValiditySeconds = 3600;
private int refreshTokenValiditySeconds = 3600;
}

@Data
public static class Async {

private int corePoolSize = Runtime.getRuntime().availableProcessors();
private int maxPoolSize = Runtime.getRuntime().availableProcessors() * 4;
private int queueCapacity = Integer.MAX_VALUE;
}

@Data
public static class Map {

private String smallPreviewsUrlFormat = "http://content.faforever.com/faf/vault/map_previews/small/%s";
private String largePreviewsUrlFormat = "http://content.faforever.com/faf/vault/map_previews/large/%s";
private String downloadUrlFormat = "http://content.faforever.com/faf/vault/maps/%s";
private Path folderZipFiles = Paths.get("/content/faf/vault/maps");
private Path folderPreviewPathSmall = Paths.get("/content/faf/vault/map_previews/small");
private Path folderPreviewPathLarge = Paths.get("/content/faf/vault/map_previews/large");
/**
* For instance {@code http://content.faforever.com/faf/vault/map_previews/small/%s}
*/
private String smallPreviewsUrlFormat;
/**
* For instance {@code http://content.faforever.com/faf/vault/map_previews/large/%s}
*/
private String largePreviewsUrlFormat;
/**
* For instance {@code http://content.faforever.com/faf/vault/maps/%s}
*/
private String downloadUrlFormat;
/**
* The directory in which map files are stored.
*/
private Path targetDirectory = Paths.get("static/maps");
/**
* The directory in which small map previews are stored.
*/
private Path directoryPreviewPathSmall = Paths.get("static/map_previews/small");
/**
* The directory in which large map previews are stored.
*/
private Path directoryPreviewPathLarge = Paths.get("static/map_previews/large");
/**
* The size (in pixels) of small map previews.
*/
private int previewSizeSmall = 128;
/**
* The size (in pixels) of large map previews.
*/
private int previewSizeLarge = 512;
/**
* Allowed file extensions of uploaded maps.
*/
private String[] allowedExtensions = {"zip"};
}

@Data
public static class Mod {
private String previewUrlFormat = "http://content.faforever.com/faf/vault/mods_thumbs/%s";
private String downloadUrlFormat = "http://content.faforever.com/faf/vault/mods/%s";
private String previewUrlFormat;
private String downloadUrlFormat;
}

@Data
public static class Replay {
private String downloadUrlFormat;
}

@Data
public static class FeaturedMods {
private String fileUrlFormat = "http://content.faforever.com/faf/updaterNew/%s/%s";
private String fileUrlFormat;
}

@Data
public static class Clan {
private long inviteLinkExpireDurationInMinutes = Duration.ofDays(3).toMinutes();
}

@Data
public static class GitHub {
private String webhookSecret;
private String accessToken;
private String deploymentEnvironment;
}

@Data
public static class Deployment {
private String featuredModsTargetDirectory;
private String repositoriesDirectory;
private String filesDirectoryFormat = "updates_%s_files";
private String forgedAllianceExePath;
private List<DeploymentConfiguration> configurations = new ArrayList<>();

@Data
public static class DeploymentConfiguration {
private String repositoryUrl;
private String branch;
private String modName;
private String modFilesExtension;
private boolean replaceExisting;
}
}
}
23 changes: 23 additions & 0 deletions src/main/java/com/faforever/api/config/GitHubConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.faforever.api.config;

import org.kohsuke.github.GitHub;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

import java.io.IOException;

@Configuration
public class GitHubConfig {
@Bean
@Profile("!dev")
public GitHub gitHub(FafApiProperties fafApiProperties) throws IOException {
return GitHub.connectUsingOAuth(fafApiProperties.getGitHub().getAccessToken());
}

@Bean
@Profile("dev")
public GitHub offlineGitHub() {
return GitHub.offline();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ protected void configure(HttpSecurity http) throws Exception {
.antMatchers("/leaderboards/**").permitAll()
.antMatchers("/featuredMods/**").permitAll()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/gitHub/webhook").permitAll()
// Redirects to Swagger UI
.antMatchers("/").permitAll()
// Swagger UI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public TokenStore tokenStore(JwtAccessTokenConverter jwtAccessTokenConverter) {
@Bean
protected JwtAccessTokenConverter jwtAccessTokenConverter() {
JwtAccessTokenConverter jwtAccessTokenConverter = new JwtAccessTokenConverter();
jwtAccessTokenConverter.setSigningKey(fafApiProperties.getJwtSecret());
jwtAccessTokenConverter.setSigningKey(fafApiProperties.getJwt().getSecret());
((DefaultAccessTokenConverter) jwtAccessTokenConverter.getAccessTokenConverter()).setUserTokenConverter(new FafUserAuthenticationConverter());
return jwtAccessTokenConverter;
}
Expand Down
24 changes: 19 additions & 5 deletions src/main/java/com/faforever/api/data/domain/Game.java
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
package com.faforever.api.data.domain;

import com.faforever.api.data.listeners.GameEnricher;
import com.yahoo.elide.annotation.ComputedAttribute;
import com.yahoo.elide.annotation.Include;
import lombok.Setter;
import org.hibernate.annotations.Formula;
import org.hibernate.annotations.Immutable;
import org.jetbrains.annotations.Nullable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.time.OffsetDateTime;
import javax.persistence.Transient;
import java.time.Instant;
import java.util.List;

@Entity
@Table(name = "game_stats")
@Include(rootLevel = true, type = "game")
@Immutable
@Setter
@EntityListeners(GameEnricher.class)
public class Game {

private int id;
private OffsetDateTime startTime;
private OffsetDateTime endTime;
private Instant startTime;
private Instant endTime;
private VictoryCondition victoryCondition;
private FeaturedMod featuredMod;
private Player host;
private MapVersion mapVersion;
private String name;
private Validity validity;
private List<GamePlayerStats> playerStats;
private String replayUrl;

@Id
@Column(name = "id")
Expand All @@ -42,7 +49,7 @@ public int getId() {
}

@Column(name = "startTime")
public OffsetDateTime getStartTime() {
public Instant getStartTime() {
return startTime;
}

Expand Down Expand Up @@ -86,7 +93,14 @@ public List<GamePlayerStats> getPlayerStats() {
}

@Formula(value = "(SELECT game_player_stats.scoreTime FROM game_player_stats WHERE game_player_stats.gameId = id ORDER BY game_player_stats.scoreTime DESC LIMIT 1)")
public OffsetDateTime getEndTime() {
@Nullable
public Instant getEndTime() {
return endTime;
}

@Transient
@ComputedAttribute
public String getReplayUrl() {
return replayUrl;
}
}
24 changes: 24 additions & 0 deletions src/main/java/com/faforever/api/data/listeners/GameEnricher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.faforever.api.data.listeners;

import com.faforever.api.config.FafApiProperties;
import com.faforever.api.data.domain.Game;
import org.springframework.stereotype.Component;

import javax.inject.Inject;
import javax.persistence.PostLoad;

@Component
public class GameEnricher {

private static FafApiProperties fafApiProperties;

@Inject
public void init(FafApiProperties fafApiProperties) {
GameEnricher.fafApiProperties = fafApiProperties;
}

@PostLoad
public void enhance(Game game) {
game.setReplayUrl(String.format(fafApiProperties.getReplay().getDownloadUrlFormat(), game.getId()));
}
}

0 comments on commit 279f800

Please sign in to comment.