Skip to content

Commit

Permalink
Rename TimeSource to Clock and move it to ServiceOptions
Browse files Browse the repository at this point in the history
  • Loading branch information
mziccard committed Oct 13, 2015
1 parent 64121d8 commit 194d239
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ public abstract class ServiceOptions<
private final ServiceRpcFactory<ServiceRpcT, OptionsT> serviceRpcFactory;
private final int connectTimeout;
private final int readTimeout;
private final Clock clock;

public interface HttpTransportFactory extends Serializable {
HttpTransport create();
Expand Down Expand Up @@ -91,7 +92,40 @@ public HttpTransport create() {
}
}

/**
* A class providing access to the current time in milliseconds. This class is mainly used for
* testing and will be replaced by Java8's {@code java.time.Clock}.
*
* Implementations should implement {@code Serializable} wherever possible and must document
* whether or not they do support serialization.
*/
public static abstract class Clock {

private static ServiceOptions.Clock DEFAULT_TIME_SOURCE = new DefaultClock();

/**
* Returns current time in milliseconds according to this clock.
*/
public abstract long millis();

/**
* Returns the default clock. Default clock uses {@link System#currentTimeMillis()} to get time
* in milliseconds.
*/
public static ServiceOptions.Clock defaultClock() {
return DEFAULT_TIME_SOURCE;
}

private static class DefaultClock extends ServiceOptions.Clock implements Serializable {

private static final long serialVersionUID = -5077300394286703864L;

@Override
public long millis() {
return System.currentTimeMillis();
}
}
}

protected abstract static class Builder<
ServiceRpcT,
Expand All @@ -106,6 +140,7 @@ protected abstract static class Builder<
private ServiceRpcFactory<ServiceRpcT, OptionsT> serviceRpcFactory;
private int connectTimeout = -1;
private int readTimeout = -1;
private Clock clock;

protected Builder() {}

Expand All @@ -125,6 +160,18 @@ protected B self() {
return (B) this;
}

/**
* Sets the service's clock. The clock is mainly used for testing purpose. {@link Clock} will be
* replaced by Java8's {@code java.time.Clock}.
*
* @param clock the clock to set
* @return the builder.
*/
public B clock(Clock clock) {
this.clock = clock;
return self();
}

/**
* Sets project id.
*
Expand Down Expand Up @@ -221,6 +268,7 @@ protected ServiceOptions(Builder<ServiceRpcT, OptionsT, ?> builder) {
serviceRpcFactory = builder.serviceRpcFactory;
connectTimeout = builder.connectTimeout;
readTimeout = builder.readTimeout;
clock = firstNonNull(builder.clock, Clock.defaultClock());
}

private static AuthCredentials defaultAuthCredentials() {
Expand Down Expand Up @@ -419,9 +467,17 @@ public int readTimeout() {
return readTimeout;
}

/**
* Returns the service's clock. Default time source uses {@link System#currentTimeMillis()} to
* get current time.
*/
public Clock clock() {
return clock;
}

protected int baseHashCode() {
return Objects.hash(projectId, host, httpTransportFactory, authCredentials, retryParams,
serviceRpcFactory);
serviceRpcFactory, connectTimeout, readTimeout, clock);
}

protected boolean baseEquals(ServiceOptions<?, ?> other) {
Expand All @@ -430,7 +486,10 @@ protected boolean baseEquals(ServiceOptions<?, ?> other) {
&& Objects.equals(httpTransportFactory, other.httpTransportFactory)
&& Objects.equals(authCredentials, other.authCredentials)
&& Objects.equals(retryParams, other.retryParams)
&& Objects.equals(serviceRpcFactory, other.serviceRpcFactory);
&& Objects.equals(serviceRpcFactory, other.serviceRpcFactory)
&& Objects.equals(connectTimeout, other.connectTimeout)
&& Objects.equals(readTimeout, other.readTimeout)
&& Objects.equals(clock, clock);
}

public abstract Builder<ServiceRpcT, OptionsT, ?> toBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ public BlobWriteChannel writer(BlobInfo blobInfo, BlobTargetOption... options) {
@Override
public URL signUrl(BlobInfo blobInfo, long duration, TimeUnit unit, SignUrlOption... options) {
long expiration = TimeUnit.SECONDS.convert(
options().timeSource().millis() + unit.toMillis(duration), TimeUnit.MILLISECONDS);
options().clock().millis() + unit.toMillis(duration), TimeUnit.MILLISECONDS);
EnumMap<SignUrlOption.Option, Object> optionMap = Maps.newEnumMap(SignUrlOption.Option.class);
for (SignUrlOption option : options) {
optionMap.put(option.option(), option.value());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.google.gcloud.spi.StorageRpc;
import com.google.gcloud.spi.StorageRpcFactory;

import java.io.Serializable;
import java.util.Objects;
import java.util.Set;

Expand All @@ -35,47 +34,12 @@ public class StorageOptions extends ServiceOptions<StorageRpc, StorageOptions> {
private static final String DEFAULT_PATH_DELIMITER = "/";

private final String pathDelimiter;
private final TimeSource timeSource;
private transient StorageRpc storageRpc;

/**
* A class providing access to the current time in milliseconds.
*
* Implementations should implement {@code Serializable} wherever possible and must document
* whether or not they do support serialization.
*/
public static abstract class TimeSource {

private static TimeSource DEFAULT_TIME_SOURCE = new DefaultTimeSource();

/**
* Returns current time in milliseconds according to this time source.
*/
public abstract long millis();

/**
* Returns the default time source.
*/
public static TimeSource defaultTimeSource() {
return DEFAULT_TIME_SOURCE;
}

private static class DefaultTimeSource extends TimeSource implements Serializable {

private static final long serialVersionUID = -5077300394286703864L;

@Override
public long millis() {
return System.currentTimeMillis();
}
}
}

public static class Builder extends
ServiceOptions.Builder<StorageRpc, StorageOptions, Builder> {

private String pathDelimiter;
private TimeSource timeSource;

private Builder() {}

Expand All @@ -85,6 +49,7 @@ private Builder(StorageOptions options) {

/**
* Sets the path delimiter for the storage service.
*
* @param pathDelimiter the path delimiter to set
* @return the builder.
*/
Expand All @@ -93,17 +58,6 @@ public Builder pathDelimiter(String pathDelimiter) {
return this;
}

/**
* Sets the time source for the storage service. The time source is used by `signUrl` to compute
* URL's expiry time. If no time source is set by default `System.getTimeMillis()` is used.
* @param source the time source to set
* @return the builder.
*/
public Builder timeSource(TimeSource source) {
this.timeSource = source;
return this;
}

@Override
public StorageOptions build() {
return new StorageOptions(this);
Expand All @@ -113,8 +67,6 @@ public StorageOptions build() {
private StorageOptions(Builder builder) {
super(builder);
pathDelimiter = MoreObjects.firstNonNull(builder.pathDelimiter, DEFAULT_PATH_DELIMITER);
timeSource = MoreObjects.firstNonNull(builder.timeSource, TimeSource.defaultTimeSource());
// todo: consider providing read-timeout
}

@Override
Expand Down Expand Up @@ -144,14 +96,6 @@ public String pathDelimiter() {
return pathDelimiter;
}

/**
* Returns the storage service's time source. Default time source uses `System.getTimeMillis()` to
* get current time.
*/
public TimeSource timeSource() {
return timeSource;
}

@Override
public Builder toBuilder() {
return new Builder(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import com.google.common.io.BaseEncoding;
import com.google.gcloud.AuthCredentials.ServiceAccountAuthCredentials;
import com.google.gcloud.RetryParams;
import com.google.gcloud.ServiceOptions;
import com.google.gcloud.spi.StorageRpc;
import com.google.gcloud.spi.StorageRpc.Tuple;

Expand Down Expand Up @@ -172,7 +173,7 @@ public class StorageImplTest {
+ "EkPPhszldvQTY486uPxyD/D7HdfnGW/Nbw5JUhfvecAdudDEhNAQ3PNabyDMI+TpiHy4NTWOrgdcWrzj6VXcdc"
+ "+uuABnPwRCdcyJ1xl2kOrPksRnp1auNGMLOe4IpEBjGY7baX9UG8+A45MbG0aHmkR59Op/aR9XowIDAQAB";

private static final StorageOptions.TimeSource TIME_SOURCE = new StorageOptions.TimeSource() {
private static final ServiceOptions.Clock TIME_SOURCE = new ServiceOptions.Clock() {
@Override
public long millis() {
return 42000L;
Expand Down Expand Up @@ -804,7 +805,7 @@ public void testSignUrl() throws NoSuchAlgorithmException, InvalidKeyException,
EasyMock.createMock(ServiceAccountAuthCredentials.class);
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
EasyMock.expect(optionsMock.authCredentials()).andReturn(credentialsMock).times(2);
EasyMock.expect(optionsMock.timeSource()).andReturn(TIME_SOURCE);
EasyMock.expect(optionsMock.clock()).andReturn(TIME_SOURCE);
EasyMock.expect(credentialsMock.privateKey()).andReturn(privateKey);
EasyMock.expect(credentialsMock.account()).andReturn(account);
EasyMock.replay(optionsMock, storageRpcMock, credentialsMock);
Expand Down Expand Up @@ -839,7 +840,7 @@ public void testSignUrlWithOptions() throws NoSuchAlgorithmException, InvalidKey
EasyMock.createMock(ServiceAccountAuthCredentials.class);
EasyMock.expect(optionsMock.storageRpc()).andReturn(storageRpcMock);
EasyMock.expect(optionsMock.authCredentials()).andReturn(credentialsMock).times(2);
EasyMock.expect(optionsMock.timeSource()).andReturn(TIME_SOURCE);
EasyMock.expect(optionsMock.clock()).andReturn(TIME_SOURCE);
EasyMock.expect(credentialsMock.privateKey()).andReturn(privateKey);
EasyMock.expect(credentialsMock.account()).andReturn(account);
EasyMock.replay(optionsMock, storageRpcMock, credentialsMock);
Expand Down

0 comments on commit 194d239

Please sign in to comment.