Skip to content

Commit

Permalink
Merge pull request Azure#19 from christav/blobwriter-from-service-wor…
Browse files Browse the repository at this point in the history
…king-393

Move createBlobWriter method to rest proxy
  • Loading branch information
Chris Tavares committed Dec 11, 2012
2 parents 04dbddc + 82602ca commit dfad16b
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 92 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,39 +32,34 @@ public void register(Registry registry) {
@Override
public ClientConfig create(String profile, Builder builder, Map<String, Object> properties) {
ClientConfig clientConfig = new DefaultClientConfig();
profile = normalizeProfile(profile);
TimeoutSettings timeoutSettings = builder.build(profile, TimeoutSettings.class, properties);
timeoutSettings.applyTimeout(clientConfig);
return clientConfig;
}
});

// Lower levels of the stack assume timeouts are set.
// Set default timeout on clientConfig in case user
// hasn't set it yet in their configuration
registry.add(new Builder.Factory<TimeoutSettings>() {

clientConfig.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, new Integer(90 * 1000));
clientConfig.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, new Integer(90 * 1000));
@Override
public TimeoutSettings create(String profile, Builder builder, Map<String, Object> properties) {
Object connectTimeout = null;
Object readTimeout = null;

profile = normalizeProfile(profile);

for (Entry<String, Object> entry : properties.entrySet()) {
Object propertyValue = entry.getValue();
String propertyKey = entry.getKey();

if (propertyKey.equals(profile + Configuration.PROPERTY_CONNECT_TIMEOUT)) {
propertyKey = ClientConfig.PROPERTY_CONNECT_TIMEOUT;
connectTimeout = propertyValue;
}
if (propertyKey.equals(profile + Configuration.PROPERTY_READ_TIMEOUT)) {
propertyKey = ClientConfig.PROPERTY_READ_TIMEOUT;
}

// ClientConfig requires instance of Integer to properly set
// timeouts, but config file will deliver strings. Special
// case these timeout properties and convert them to Integer
// if necessary.
if (propertyKey.equals(ClientConfig.PROPERTY_CONNECT_TIMEOUT)
|| propertyKey.equals(ClientConfig.PROPERTY_READ_TIMEOUT)) {
if (propertyValue instanceof String) {
propertyValue = Integer.valueOf((String) propertyValue);
}
readTimeout = propertyValue;
}
clientConfig.getProperties().put(propertyKey, propertyValue);
}
return clientConfig;

return new TimeoutSettings(connectTimeout, readTimeout);
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright 2012 Microsoft Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.windowsazure.services.core.utils.pipeline;

import com.sun.jersey.api.client.config.ClientConfig;

/**
* Class used for injecting timeout settings into the various places that need it.
*
*/
public class TimeoutSettings {
private static final int DEFAULT_TIMEOUT_MS = 90 * 1000;

private final Integer connectTimeout;
private final Integer readTimeout;

/**
* Construct a {@link TimeoutSettings} object with the default
* timeout.
*/
public TimeoutSettings() {
connectTimeout = Integer.valueOf(null);
readTimeout = Integer.valueOf(null);
}

public TimeoutSettings(Object connectTimeout, Object readTimeout) {
this.connectTimeout = getTimeout(connectTimeout);
this.readTimeout = getTimeout(readTimeout);
}

public void applyTimeout(ClientConfig clientConfig) {
clientConfig.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT, connectTimeout);
clientConfig.getProperties().put(ClientConfig.PROPERTY_READ_TIMEOUT, readTimeout);
}

private Integer getTimeout(Object timeoutValue) {
if (timeoutValue == null) {
return new Integer(DEFAULT_TIMEOUT_MS);
}

if (timeoutValue instanceof Integer) {
return (Integer) timeoutValue;
}

if (timeoutValue instanceof String) {
return Integer.valueOf((String) timeoutValue);
}

throw new IllegalArgumentException("timeoutValue");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.microsoft.windowsazure.services.core.FilterableService;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityContract;
import com.microsoft.windowsazure.services.media.models.LocatorInfo;

/**
* Contract for interacting with the back end of Media Services
Expand All @@ -28,4 +29,13 @@ public interface MediaContract extends FilterableService<MediaContract>, EntityC

URI getRestServiceUri();

/**
* Creates an instance of the <code>WritableBlobContainerContract</code> API that will
* write to the blob container given by the provided locator.
*
* @param locator
* locator specifying where to upload to
* @return the implementation of <code>WritableBlobContainerContract</code>
*/
WritableBlobContainerContract createBlobWriter(LocatorInfo locator);
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,7 @@
*/
package com.microsoft.windowsazure.services.media;

import java.net.URI;

import com.microsoft.windowsazure.services.core.Configuration;
import com.microsoft.windowsazure.services.media.implementation.MediaBlobContainerWriter;
import com.microsoft.windowsazure.services.media.models.LocatorInfo;
import com.microsoft.windowsazure.services.media.models.LocatorType;
import com.sun.jersey.api.client.Client;

/**
*
Expand Down Expand Up @@ -70,55 +64,4 @@ public static MediaContract create(String profile) {
public static MediaContract create(String profile, Configuration config) {
return config.create(profile, MediaContract.class);
}

/**
* Creates an instance of the <code>WritableBlobContainerContract</code> API that will
* write to the blob container given by the provided locator.
*
* @param locator
* locator specifying where to upload to
* @return the implementation of <code>WritableBlobContainerContract</code>
*/
public static WritableBlobContainerContract createBlobWriter(LocatorInfo locator) {
if (locator.getLocatorType() != LocatorType.SAS) {
throw new IllegalArgumentException("Can only write to SAS locators");
}

LocatorParser p = new LocatorParser(locator);

return new MediaBlobContainerWriter(createUploaderClient(), p.getAccountName(), p.getStorageUri(),
p.getContainer(), p.getSASToken());
}

/**
* Helper class to encapsulate pulling information out of the locator.
*/
private static class LocatorParser {
URI locatorPath;

LocatorParser(LocatorInfo locator) {
locatorPath = URI.create(locator.getPath());
}

String getAccountName() {
return locatorPath.getHost().split("\\.")[0];
}

String getStorageUri() {
return locatorPath.getScheme() + "://" + locatorPath.getAuthority();
}

String getContainer() {
return locatorPath.getPath().substring(1);
}

String getSASToken() {
return locatorPath.getRawQuery();
}
}

private static Client createUploaderClient() {
Client client = Client.create();
return client;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,15 @@
import com.microsoft.windowsazure.services.core.ServiceFilter;
import com.microsoft.windowsazure.services.core.utils.ServiceExceptionFactory;
import com.microsoft.windowsazure.services.media.MediaContract;
import com.microsoft.windowsazure.services.media.WritableBlobContainerContract;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityActionOperation;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityCreationOperation;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityDeleteOperation;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityGetOperation;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityListOperation;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityUpdateOperation;
import com.microsoft.windowsazure.services.media.models.ListResult;
import com.microsoft.windowsazure.services.media.models.LocatorInfo;
import com.sun.jersey.api.client.ClientHandlerException;
import com.sun.jersey.api.client.UniformInterfaceException;

Expand Down Expand Up @@ -196,4 +198,12 @@ public URI getRestServiceUri() {
return service.getRestServiceUri();
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.MediaContract#createBlobWriter(com.microsoft.windowsazure.services.media.models.LocatorInfo)
*/
@Override
public WritableBlobContainerContract createBlobWriter(LocatorInfo locator) {
return service.createBlobWriter(locator);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,15 @@
import org.apache.commons.logging.LogFactory;

import com.microsoft.windowsazure.services.core.ServiceFilter;
import com.microsoft.windowsazure.services.core.utils.pipeline.TimeoutSettings;
import com.microsoft.windowsazure.services.media.MediaContract;
import com.microsoft.windowsazure.services.media.WritableBlobContainerContract;
import com.microsoft.windowsazure.services.media.implementation.entities.EntityRestProxy;
import com.microsoft.windowsazure.services.media.models.LocatorInfo;
import com.microsoft.windowsazure.services.media.models.LocatorType;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

/**
* The Class MediaRestProxy.
Expand All @@ -38,6 +44,8 @@ public class MediaRestProxy extends EntityRestProxy implements MediaContract {
/** The redirect filter. */
private RedirectFilter redirectFilter;

private final TimeoutSettings timeoutSettings;

/**
* Instantiates a new media rest proxy.
*
Expand All @@ -49,12 +57,16 @@ public class MediaRestProxy extends EntityRestProxy implements MediaContract {
* the redirect filter
* @param versionHeadersFilter
* the version headers filter
* @param timeoutSettings
* Currently configured HTTP client timeouts
*
*/
@Inject
public MediaRestProxy(Client channel, OAuthFilter authFilter, RedirectFilter redirectFilter,
VersionHeadersFilter versionHeadersFilter) {
VersionHeadersFilter versionHeadersFilter, TimeoutSettings timeoutSettings) {
super(channel, new ServiceFilter[0]);

this.timeoutSettings = timeoutSettings;
this.redirectFilter = redirectFilter;
channel.addFilter(redirectFilter);
channel.addFilter(authFilter);
Expand All @@ -68,9 +80,12 @@ public MediaRestProxy(Client channel, OAuthFilter authFilter, RedirectFilter red
* the channel
* @param filters
* the filters
* @param timeoutSettings
* currently configured HTTP client timeouts
*/
private MediaRestProxy(Client channel, ServiceFilter[] filters) {
private MediaRestProxy(Client channel, ServiceFilter[] filters, TimeoutSettings timeoutSettings) {
super(channel, filters);
this.timeoutSettings = timeoutSettings;
}

/* (non-Javadoc)
Expand All @@ -81,7 +96,7 @@ public MediaContract withFilter(ServiceFilter filter) {
ServiceFilter[] filters = getFilters();
ServiceFilter[] newFilters = Arrays.copyOf(filters, filters.length + 1);
newFilters[filters.length] = filter;
return new MediaRestProxy(getChannel(), newFilters);
return new MediaRestProxy(getChannel(), newFilters, timeoutSettings);
}

/* (non-Javadoc)
Expand All @@ -91,4 +106,53 @@ public MediaContract withFilter(ServiceFilter filter) {
public URI getRestServiceUri() {
return this.redirectFilter.getBaseURI();
}
}

/* (non-Javadoc)
* @see com.microsoft.windowsazure.services.media.MediaContract#createBlobWriter(com.microsoft.windowsazure.services.media.models.LocatorInfo)
*/
@Override
public WritableBlobContainerContract createBlobWriter(LocatorInfo locator) {
if (locator.getLocatorType() != LocatorType.SAS) {
throw new IllegalArgumentException("Can only write to SAS locators");
}

LocatorParser p = new LocatorParser(locator);

return new MediaBlobContainerWriter(createUploaderClient(), p.getAccountName(), p.getStorageUri(),
p.getContainer(), p.getSASToken());
}

/**
* Helper class to encapsulate pulling information out of the locator.
*/
private static class LocatorParser {
URI locatorPath;

LocatorParser(LocatorInfo locator) {
locatorPath = URI.create(locator.getPath());
}

String getAccountName() {
return locatorPath.getHost().split("\\.")[0];
}

String getStorageUri() {
return locatorPath.getScheme() + "://" + locatorPath.getAuthority();
}

String getContainer() {
return locatorPath.getPath().substring(1);
}

String getSASToken() {
return locatorPath.getRawQuery();
}
}

private Client createUploaderClient() {
ClientConfig clientConfig = new DefaultClientConfig();
timeoutSettings.applyTimeout(clientConfig);
Client client = Client.create(clientConfig);
return client;
}
}
Loading

0 comments on commit dfad16b

Please sign in to comment.