Skip to content

Commit

Permalink
chore: Parse Last Modified Header (#159)
Browse files Browse the repository at this point in the history
* Last modified parsing

* Last modified parsing
  • Loading branch information
JamieSinn authored Jul 24, 2024
1 parent 6128289 commit f0ba701
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public interface IDevCycleApi {
*/
@Headers({"Content-Type:application/json"})
@GET("config/v1/server/{sdkToken}.json")
Call<ProjectConfig> getConfig(@Path("sdkToken") String sdkToken, @Header("If-None-Match") String etag);
Call<ProjectConfig> getConfig(@Path("sdkToken") String sdkToken, @Header("If-None-Match") String etag, @Header("If-Modified-Since") String lastModified);

/**
* Post events to DevCycle for user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
import retrofit2.Response;

import java.io.IOException;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
Expand All @@ -30,6 +32,7 @@ public final class EnvironmentConfigManager {

private ProjectConfig config;
private String configETag = "";
private String configLastModified = "";

private final String sdkKey;
private final int pollingIntervalMS;
Expand Down Expand Up @@ -69,7 +72,7 @@ public boolean isConfigInitialized() {
}

private ProjectConfig getConfig() throws DevCycleException {
Call<ProjectConfig> config = this.configApiClient.getConfig(this.sdkKey, this.configETag);
Call<ProjectConfig> config = this.configApiClient.getConfig(this.sdkKey, this.configETag, this.configLastModified);
this.config = getResponseWithRetries(config, 1);
return this.config;
}
Expand Down Expand Up @@ -129,23 +132,42 @@ private ProjectConfig getConfigResponse(Call<ProjectConfig> call) throws DevCycl

if (response.isSuccessful()) {
String currentETag = response.headers().get("ETag");
String headerLastModified = response.headers().get("Last-Modified");

if (!this.configLastModified.isEmpty() && headerLastModified != null && !headerLastModified.isEmpty()) {
ZonedDateTime parsedLastModified = ZonedDateTime.parse(
headerLastModified,
DateTimeFormatter.RFC_1123_DATE_TIME
);
ZonedDateTime configLastModified = ZonedDateTime.parse(
this.configLastModified,
DateTimeFormatter.RFC_1123_DATE_TIME
);

if (parsedLastModified.isBefore(configLastModified)) {
DevCycleLogger.warning("Received a config with last-modified header before the current stored timestamp. Not saving config.");
return this.config;
}
}

ProjectConfig config = response.body();
try {
ObjectMapper mapper = new ObjectMapper();
localBucketing.storeConfig(sdkKey, mapper.writeValueAsString(config));
} catch (JsonProcessingException e) {
if (this.config != null) {
DevCycleLogger.error("Unable to parse config with etag: " + currentETag + ". Using cache, etag " + this.configETag);
DevCycleLogger.error("Unable to parse config with etag: " + currentETag + ". Using cache, etag " + this.configETag + " last-modified: " + this.configLastModified);
return this.config;
} else {
errorResponse.setMessage(e.getMessage());
throw new DevCycleException(HttpResponseCode.SERVER_ERROR, errorResponse);
}
}
this.configETag = currentETag;
this.configLastModified = headerLastModified;
return response.body();
} else if (httpResponseCode == HttpResponseCode.NOT_MODIFIED) {
DevCycleLogger.debug("Config not modified, using cache, etag: " + this.configETag);
DevCycleLogger.debug("Config not modified, using cache, etag: " + this.configETag + " last-modified: " + this.configLastModified);
return this.config;
} else {
if (response.errorBody() != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public Call<DevCycleResponse> track(DevCycleUserAndEvents userAndEvents, Boolean
}

@Override
public Call<ProjectConfig> getConfig(String sdkToken, String etag) {
public Call<ProjectConfig> getConfig(String sdkToken, String etag, String lastModified) {
// TODO Auto-generated method stub
return null;
}
Expand Down

0 comments on commit f0ba701

Please sign in to comment.