Skip to content

Commit

Permalink
Merge branch 'release/0.3.6'
Browse files Browse the repository at this point in the history
  • Loading branch information
micheljung committed Mar 31, 2017
2 parents 8152c78 + 89decdf commit cf8daf3
Show file tree
Hide file tree
Showing 48 changed files with 404 additions and 219 deletions.
1 change: 1 addition & 0 deletions .idea/codeStyleSettings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ apply plugin: 'org.springframework.boot'
apply plugin: 'propdeps'

group = 'micheljung'
version = '0.3.5'
version = '0.3.6'

sourceCompatibility = 1.8
targetCompatibility = 1.8
Expand Down Expand Up @@ -134,6 +134,7 @@ dependencyManagement {
dependency("org.hibernate:hibernate-core:${hibernateVersion}")
dependency("org.hibernate:hibernate-entitymanager:${hibernateVersion}")
dependency("org.hibernate:hibernate-validator:${hibernateVersion}")
dependency("org.mockito:mockito-core:${mockitoVersion}")
}
}

Expand All @@ -158,7 +159,8 @@ dependencies {
compile("io.springfox:springfox-swagger-ui:${swaggerVersion}")
compile("io.springfox:springfox-swagger2:${swaggerVersion}")
compile("javax.inject:javax.inject:${javaxInjectVersion}")
compile("com.yahoo.elide:elide-datastore-hibernate5:${elideHibernateVersion}")
compile("com.yahoo.elide:elide-core:${elideVersion}")
compile("com.yahoo.elide:elide-datastore-hibernate5:${elideVersion}")
compile("org.hibernate:hibernate-java8:${hibernateVersion}")
compile("com.zaxxer:HikariCP:${hikariCpVersion}") {
exclude(module: 'tools')
Expand Down
5 changes: 3 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
profile=dev
springBootVersion=1.4.2.RELEASE
springBootVersion=1.5.2.RELEASE
jjwtVersion=0.7.0
javaxInjectVersion=1
elideHibernateVersion=2.5.1
elideVersion=3.0.2
hibernateVersion=5.1.0.Final
mysqlConnectorVersion=6.0.5
gradleDockerVersion=3.0.4
Expand All @@ -26,3 +26,4 @@ jgitVersionn=4.5.0.201609210915-r
fafCommonsVersion=76fb583d146082f3db68c0bece38a3ee28ead8e6
h2Version=1.4.193
jacksonDatatypeJsr310Version=2.8.6
mockitoVersion=2.7.0
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
@NoArgsConstructor
class AchievementUpdateRequest {

private int playerId;
private String achievementId;
private Operation operation;
private int steps;

AchievementUpdateRequest(String achievementId, Operation operation, int steps) {
AchievementUpdateRequest(int playerId, String achievementId, Operation operation, int steps) {
this.playerId = playerId;
this.achievementId = achievementId;
this.operation = operation;
this.steps = steps;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package com.faforever.api.achievements;

import com.faforever.api.error.ProgrammingError;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder;
import com.yahoo.elide.jsonapi.models.Data;
import com.yahoo.elide.jsonapi.models.JsonApiDocument;
import com.yahoo.elide.jsonapi.models.Resource;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.inject.Inject;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@RestController
@RequestMapping(path = "/achievements")
public class AchievementsController {

private static final String JSON_API_MEDIA_TYPE = "application/vnd.api+json";
private final AchievementsService achievementsService;
private AtomicInteger nextUpdateId;

@Inject
public AchievementsController(AchievementsService achievementsService) {
this.achievementsService = achievementsService;
nextUpdateId = new AtomicInteger();
}

@ApiOperation(value = "Updates the state and progress of one or multiple achievements.")
@PreAuthorize("#oauth2.hasScope('write_achievements')")
@RequestMapping(value = "/update", method = RequestMethod.PATCH, produces = JSON_API_MEDIA_TYPE)
public JsonApiDocument update(@RequestBody AchievementUpdateRequest[] updateRequests) {
return new JsonApiDocument(new Data<>(Arrays.stream(updateRequests)
.map(request -> {
switch (request.getOperation()) {
case REVEAL:
throw new UnsupportedOperationException("REVEAL is not yet implemented");
case UNLOCK:
return achievementsService.unlock(request.getPlayerId(), request.getAchievementId());
case INCREMENT:
return achievementsService.increment(request.getPlayerId(), request.getAchievementId(), request.getSteps());
case SET_STEPS_AT_LEAST:
return achievementsService.setStepsAtLeast(request.getPlayerId(), request.getAchievementId(), request.getSteps());
default:
throw new ProgrammingError("Uncovered update type: " + request.getOperation());
}
})
.map(this::toResource)
.collect(Collectors.toList())));
}

private Resource toResource(UpdatedAchievementResponse updatedAchievementResponse) {
Builder<String, Object> attributesBuilder = ImmutableMap.<String, Object>builder()
.put("achievementId", updatedAchievementResponse.getAchievementId())
.put("state", updatedAchievementResponse.getState())
.put("newlyUnlocked", updatedAchievementResponse.isNewlyUnlocked());

if (updatedAchievementResponse.getCurrentSteps() != null) {
attributesBuilder.put("currentSteps", updatedAchievementResponse.getCurrentSteps());
}

return new Resource("updatedAchievement", String.valueOf(nextUpdateId.getAndIncrement()),
attributesBuilder.build(), null, null, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public AchievementsService(AchievementDefinitionRepository achievementDefinition
this.playerAchievementRepository = playerAchievementRepository;
}

AchievementUpdateResponse increment(String achievementId, int steps, int playerId) {
return updateSteps(achievementId, steps, playerId, (currentSteps, newSteps) -> currentSteps + newSteps);
UpdatedAchievementResponse increment(int playerId, String achievementId, int steps) {
return updateSteps(playerId, achievementId, steps, (currentSteps, newSteps) -> currentSteps + newSteps);
}

private AchievementUpdateResponse updateSteps(String achievementId, int steps, int playerId, BiFunction<Integer, Integer, Integer> stepsFunction) {
private UpdatedAchievementResponse updateSteps(int playerId, String achievementId, int steps, BiFunction<Integer, Integer, Integer> stepsFunction) {
AchievementDefinition achievementDefinition = achievementDefinitionRepository.getOne(achievementId);
if (achievementDefinition.getType() != AchievementType.INCREMENTAL) {
throw new ApiException(new Error(ACHIEVEMENT_NOT_INCREMENTAL, achievementId));
Expand All @@ -54,24 +54,22 @@ private AchievementUpdateResponse updateSteps(String achievementId, int steps, i

playerAchievementRepository.save(playerAchievement);

return new AchievementUpdateResponse(newlyUnlocked, playerAchievement.getState(), playerAchievement.getCurrentSteps());
return new UpdatedAchievementResponse(achievementId, newlyUnlocked, playerAchievement.getState(), playerAchievement.getCurrentSteps());
}

private PlayerAchievement getOrCreatePlayerAchievement(int playerId, AchievementDefinition achievementDefinition, AchievementState initialState) {
return playerAchievementRepository.findOneByAchievementIdAndPlayerId(achievementDefinition.getId(), playerId)
.orElseGet(() -> {
PlayerAchievement newPlayerAchievement = new PlayerAchievement();
newPlayerAchievement.setAchievement(achievementDefinition);
newPlayerAchievement.setState(initialState);
return newPlayerAchievement;
});
.orElseGet(() -> new PlayerAchievement()
.setPlayerId(playerId)
.setAchievement(achievementDefinition)
.setState(initialState));
}

AchievementUpdateResponse setStepsAtLeast(String achievementId, int steps, int playerId) {
return updateSteps(achievementId, steps, playerId, Math::max);
UpdatedAchievementResponse setStepsAtLeast(int playerId, String achievementId, int steps) {
return updateSteps(playerId, achievementId, steps, Math::max);
}

AchievementUpdateResponse unlock(String achievementId, int playerId) {
UpdatedAchievementResponse unlock(int playerId, String achievementId) {
AchievementDefinition achievementDefinition = achievementDefinitionRepository.getOne(achievementId);
if (achievementDefinition.getType() != AchievementType.STANDARD) {
throw new ApiException(new Error(ACHIEVEMENT_NOT_STANDARD, achievementId));
Expand All @@ -86,6 +84,6 @@ AchievementUpdateResponse unlock(String achievementId, int playerId) {
playerAchievementRepository.save(playerAchievement);
}

return new AchievementUpdateResponse(newlyUnlocked, playerAchievement.getState());
return new UpdatedAchievementResponse(achievementId, newlyUnlocked, playerAchievement.getState());
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,19 @@
import org.jetbrains.annotations.Nullable;

@Getter
class AchievementUpdateResponse {
class UpdatedAchievementResponse {

private final String achievementId;
private final Integer currentSteps;
private final AchievementState state;
private final boolean newlyUnlocked;

AchievementUpdateResponse(boolean newlyUnlocked, AchievementState state) {
this(newlyUnlocked, state, null);
UpdatedAchievementResponse(String achievementId, boolean newlyUnlocked, AchievementState state) {
this(achievementId, newlyUnlocked, state, null);
}

AchievementUpdateResponse(boolean newlyUnlocked, AchievementState state, @Nullable Integer currentSteps) {
UpdatedAchievementResponse(String achievementId, boolean newlyUnlocked, AchievementState state, @Nullable Integer currentSteps) {
this.achievementId = achievementId;
this.currentSteps = currentSteps;
this.state = state;
this.newlyUnlocked = newlyUnlocked;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public static class Jwt {
/**
* The secret used for JWT token generation.
*/
private String secret = "secret";
private String secret;
private int accessTokenValiditySeconds = 3600;
private int refreshTokenValiditySeconds = 3600;
}
Expand Down
16 changes: 10 additions & 6 deletions src/main/java/com/faforever/api/config/elide/ElideConfig.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package com.faforever.api.config.elide;

import com.faforever.api.data.JsonApiController;
import com.faforever.api.data.DataController;
import com.faforever.api.data.checks.IsAuthenticated;
import com.faforever.api.data.checks.IsClanLeader;
import com.faforever.api.data.checks.IsClanMembershipDeletable;
import com.faforever.api.data.checks.IsOwner;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yahoo.elide.Elide;
import com.yahoo.elide.ElideSettingsBuilder;
import com.yahoo.elide.audit.Slf4jLogger;
import com.yahoo.elide.core.EntityDictionary;
import com.yahoo.elide.core.filter.dialect.RSQLFilterDialect;
import com.yahoo.elide.datastores.hibernate5.HibernateStore;
import com.yahoo.elide.datastores.hibernate5.HibernateStore.Builder;
import com.yahoo.elide.jsonapi.JsonApiMapper;
import com.yahoo.elide.security.checks.Check;
import org.hibernate.SessionFactory;
Expand Down Expand Up @@ -42,13 +44,15 @@ public Elide elide(EntityManagerFactory entityManagerFactory, ObjectMapper objec
EntityDictionary entityDictionary = new EntityDictionary(checks);
RSQLFilterDialect rsqlFilterDialect = new RSQLFilterDialect(entityDictionary);

return new Elide.Builder(new HibernateStore(entityManagerFactory.unwrap(SessionFactory.class)))
HibernateStore hibernateStore = new Builder(entityManagerFactory.unwrap(SessionFactory.class)).build();

return new Elide(new ElideSettingsBuilder(hibernateStore)
.withJsonApiMapper(new JsonApiMapper(entityDictionary, objectMapper))
.withAuditLogger(new Slf4jLogger())
.withEntityDictionary(entityDictionary)
.withJoinFilterDialect(rsqlFilterDialect)
.withSubqueryFilterDialect(rsqlFilterDialect)
.build();
.build());
}

/**
Expand All @@ -60,7 +64,7 @@ public CacheResolver elideCacheResolver(CacheManager cacheManager) {
return new AbstractCacheResolver(cacheManager) {
@Override
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
String jsonApiPath = getJsonApiPath((HttpServletRequest) context.getArgs()[1]);
String jsonApiPath = getDataApiPath((HttpServletRequest) context.getArgs()[1]);
String type = jsonApiPath.split("/")[0];

if (!cacheManager.getCacheNames().contains(type)) {
Expand All @@ -72,8 +76,8 @@ protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> co
};
}

private String getJsonApiPath(HttpServletRequest request) {
private String getDataApiPath(HttpServletRequest request) {
return ((String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE))
.replace(JsonApiController.PATH_PREFIX, "");
.replace(DataController.PATH_PREFIX, "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,16 @@ protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable() // http://stackoverflow.com/a/29917946
.headers()
.cacheControl().disable()
.cacheControl().disable()
.and().formLogin().permitAll()
.and().authorizeRequests()
.antMatchers(HttpMethod.OPTIONS).permitAll()
// Elide JSON-API
.antMatchers("/data/**").permitAll()
// Additional APIs
.antMatchers("/leaderboards/**").permitAll()
.antMatchers("/featuredMods/**").permitAll()
.antMatchers("/oauth/**").permitAll()
.antMatchers("/gitHub/webhook").permitAll()
// Redirects to Swagger UI
.antMatchers("/").permitAll()
// Swagger UI
.antMatchers("/swagger-ui.html").permitAll()
.antMatchers("/swagger-resources/**").permitAll()
.antMatchers("/v2/api-docs/**").permitAll()
// Require authentication for everything else
.antMatchers("/**").authenticated();
.antMatchers("/").permitAll();
// @formatter:on
}

Expand All @@ -77,7 +68,8 @@ public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
registry.addMapping("/**")
.allowedMethods("*");
}
};
}
Expand Down
Loading

0 comments on commit cf8daf3

Please sign in to comment.