Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Version information to RC template #491

Merged
merged 4 commits into from
Nov 10, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/main/java/com/google/firebase/remoteconfig/Template.java
Original file line number Diff line number Diff line change
@@ -25,6 +25,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* Represents a Remote Config template.
@@ -202,4 +203,25 @@ TemplateResponse toTemplateResponse() {
.setParameterGroups(parameterGroupResponse)
.setVersion(versionResponse);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Template template = (Template) o;
return Objects.equals(etag, template.etag)
&& Objects.equals(parameters, template.parameters)
&& Objects.equals(conditions, template.conditions)
&& Objects.equals(parameterGroups, template.parameterGroups)
&& Objects.equals(version, template.version);
}

@Override
public int hashCode() {
return Objects.hash(etag, parameters, conditions, parameterGroups, version);
}
}
29 changes: 25 additions & 4 deletions src/main/java/com/google/firebase/remoteconfig/User.java
Original file line number Diff line number Diff line change
@@ -22,14 +22,16 @@
import com.google.firebase.internal.Nullable;
import com.google.firebase.remoteconfig.internal.TemplateResponse.UserResponse;

import java.util.Objects;

/**
* Represents a Remote Config user. Output only.
*/
public final class User {
public class User {

private String email;
private String name;
private String imageUrl;
private final String email;
private final String name;
private final String imageUrl;

User(@NonNull UserResponse userResponse) {
checkNotNull(userResponse);
@@ -67,4 +69,23 @@ public String getName() {
public String getImageUrl() {
return imageUrl;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
User user = (User) o;
return Objects.equals(email, user.email)
&& Objects.equals(name, user.name)
&& Objects.equals(imageUrl, user.imageUrl);
}

@Override
public int hashCode() {
return Objects.hash(email, name, imageUrl);
}
}
88 changes: 70 additions & 18 deletions src/main/java/com/google/firebase/remoteconfig/Version.java
Original file line number Diff line number Diff line change
@@ -26,7 +26,10 @@

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Objects;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Represents a Remote Config template version.
@@ -37,37 +40,53 @@
*/
public final class Version {

private String versionNumber;
private long updateTime;
private String updateOrigin;
private String updateType;
private User updateUser;
private String description;
private String rollbackSource;
private boolean legacy;
private static final Pattern ZULU_TIME_NO_NANOSECONDS_PATTERN = Pattern
.compile("^(\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2})");

/**
* Creates a new {@link Version} with a description.
*/
public static Version withDescription(String description) {
return new Version().setDescription(description);
}
private final String versionNumber;
private final long updateTime;
private final String updateOrigin;
private final String updateType;
private final User updateUser;
private final String rollbackSource;
private final boolean legacy;
private String description;

Version() {
private Version() {
this.versionNumber = null;
this.updateTime = 0L;
this.updateOrigin = null;
this.updateType = null;
this.updateUser = null;
this.rollbackSource = null;
this.legacy = false;
}

Version(@NonNull VersionResponse versionResponse) {
checkNotNull(versionResponse);
this.versionNumber = versionResponse.getVersionNumber();

if (!Strings.isNullOrEmpty(versionResponse.getUpdateTime())) {
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
// Update Time is a timestamp in RFC3339 UTC "Zulu" format, accurate to nanoseconds.
// example: "2014-10-02T15:01:23.045123456Z"
// SimpleDateFormat cannot handle nanoseconds, therefore we drop nanoseconds from the string.
Copy link
Member Author

@lahirumaramba lahirumaramba Nov 4, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that the update time is represented in FC3339 UTC "Zulu" format, accurate to nanoseconds. Added new code here to convert the timestamp to milliseconds properly.

DateTime does not handle nanoseconds so I had to drop them from the timestamp string before parsing. Otherwise SimpleDateFormat considers nanoseconds as milliseconds and add it back to the time making the parsed date/time incorrect.

Apparently, there are better ways to handle nanoseconds in Java8 (LocalDateTime and Instant) :)

Matcher errorMatcher = ZULU_TIME_NO_NANOSECONDS_PATTERN
.matcher(versionResponse.getUpdateTime());
String updateTimeWithoutNanoseconds = "";
if (errorMatcher.find()) {
updateTimeWithoutNanoseconds = errorMatcher.group(1);
}
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
this.updateTime = dateFormat.parse(versionResponse.getUpdateTime()).getTime();
this.updateTime = dateFormat.parse(updateTimeWithoutNanoseconds).getTime();
} catch (ParseException e) {
this.updateTime = 0;
throw new IllegalStateException();
}
} else {
this.updateTime = 0L;
}

this.updateOrigin = versionResponse.getUpdateOrigin();
this.updateType = versionResponse.getUpdateType();
TemplateResponse.UserResponse userResponse = versionResponse.getUpdateUser();
@@ -77,6 +96,13 @@ public static Version withDescription(String description) {
this.legacy = versionResponse.isLegacy();
}

/**
* Creates a new {@link Version} with a description.
*/
public static Version withDescription(String description) {
return new Version().setDescription(description);
}

/**
* Gets the version number of the template.
*
@@ -178,4 +204,30 @@ VersionResponse toVersionResponse() {
return new VersionResponse()
.setDescription(this.description);
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Version version = (Version) o;
return updateTime == version.updateTime
&& legacy == version.legacy
&& Objects.equals(versionNumber, version.versionNumber)
&& Objects.equals(updateOrigin, version.updateOrigin)
&& Objects.equals(updateType, version.updateType)
&& Objects.equals(updateUser, version.updateUser)
&& Objects.equals(description, version.description)
&& Objects.equals(rollbackSource, version.rollbackSource);
}

@Override
public int hashCode() {
return Objects
.hash(versionNumber, updateTime, updateOrigin, updateType, updateUser, description,
rollbackSource, legacy);
}
}
Original file line number Diff line number Diff line change
@@ -294,6 +294,41 @@ public VersionResponse setDescription(String description) {
this.description = description;
return this;
}

public VersionResponse setVersionNumber(String versionNumber) {
this.versionNumber = versionNumber;
return this;
}

public VersionResponse setUpdateTime(String updateTime) {
this.updateTime = updateTime;
return this;
}

public VersionResponse setUpdateOrigin(String updateOrigin) {
this.updateOrigin = updateOrigin;
return this;
}

public VersionResponse setUpdateType(String updateType) {
this.updateType = updateType;
return this;
}

public VersionResponse setUpdateUser(UserResponse updateUser) {
this.updateUser = updateUser;
return this;
}

public VersionResponse setRollbackSource(String rollbackSource) {
this.rollbackSource = rollbackSource;
return this;
}

public VersionResponse setLegacy(Boolean legacy) {
this.legacy = legacy;
return this;
}
}

/**
@@ -321,5 +356,20 @@ public String getName() {
public String getImageUrl() {
return imageUrl;
}

public UserResponse setEmail(String email) {
this.email = email;
return this;
}

public UserResponse setName(String name) {
this.name = name;
return this;
}

public UserResponse setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@
import com.google.firebase.OutgoingHttpRequest;
import com.google.firebase.auth.MockGoogleCredentials;
import com.google.firebase.internal.SdkUtils;
import com.google.firebase.remoteconfig.internal.TemplateResponse;
import com.google.firebase.testing.TestResponseInterceptor;
import com.google.firebase.testing.TestUtils;

@@ -115,25 +116,28 @@ public void testGetTemplate() throws Exception {
"device.os == 'android' && device.country in ['us', 'uk']")
.setTagColor(TagColor.UNSPECIFIED)
);
final Version expectedVersion = new Version(new TemplateResponse.VersionResponse()
.setVersionNumber("17")
.setUpdateOrigin("ADMIN_SDK_NODE")
.setUpdateType("INCREMENTAL_UPDATE")
.setUpdateUser(new TemplateResponse.UserResponse()
.setEmail("firebase-user@account.com")
.setName("dev-admin")
.setImageUrl("http://image.jpg"))
.setUpdateTime("2020-11-03T20:24:15.203Z")
.setDescription("promo config")
);

Template expectedTemplate = new Template()
.setETag(TEST_ETAG)
.setParameters(expectedParameters)
.setConditions(expectedConditions)
.setParameterGroups(expectedParameterGroups)
.setVersion(expectedVersion);

assertEquals(TEST_ETAG, receivedTemplate.getETag());
assertEquals(expectedParameters, receivedTemplate.getParameters());
assertEquals(expectedParameterGroups, receivedTemplate.getParameterGroups());
assertEquals(expectedConditions, receivedTemplate.getConditions());

final Version receivedVersion = receivedTemplate.getVersion();
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
final String updateTime = dateFormat.format(new Date(receivedVersion.getUpdateTime()));

assertEquals("17", receivedVersion.getVersionNumber());
assertEquals("ADMIN_SDK_NODE", receivedVersion.getUpdateOrigin());
assertEquals("INCREMENTAL_UPDATE", receivedVersion.getUpdateType());
assertEquals("firebase-user@account.com", receivedVersion.getUpdateUser().getEmail());
assertEquals("dev-admin", receivedVersion.getUpdateUser().getName());
assertEquals("http://image.jpg", receivedVersion.getUpdateUser().getImageUrl());
assertEquals("Wed, 30 Sep 2020 17:56:07 GMT", updateTime);
assertEquals("promo config", receivedVersion.getDescription());
assertEquals(expectedTemplate, receivedTemplate);
assertEquals(1604435055000L, receivedTemplate.getVersion().getUpdateTime());
checkGetRequestHeader(interceptor.getLastRequest());
}

Loading
Oops, something went wrong.