Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

<groupId>org.javaswift</groupId>
<artifactId>joss</artifactId>
<version>0.9.9-SNAPSHOT</version>
<version>1.0.4-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Java OpenStack Storage</name>
<description>Java Client library for OpenStack Storage (Swift)</description>
Expand Down Expand Up @@ -195,4 +195,4 @@
</plugins>
</reporting>

</project>
</project>
11 changes: 11 additions & 0 deletions src/main/java/org/javaswift/joss/client/core/AbstractAccount.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public abstract class AbstractAccount extends AbstractObjectStoreEntity<AccountI

private ServerTime serverTime = new ServerTime(0);

private boolean usePrivateURL = false;

public AbstractAccount(AccountCommandFactory commandFactory, ContainerFactory<Container> containerFactory,
ContainerFactory<Website> websiteFactory, boolean allowCaching) {
super(allowCaching);
Expand Down Expand Up @@ -226,4 +228,13 @@ public String getOriginalHost() {
return this.commandFactory.getOriginalHost();
}

@Override
public void setUsePrivateURL(boolean b) {
this.usePrivateURL = b;
}

@Override
public boolean isUsePrivateURL() {
return this.usePrivateURL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ public String getManifest() {
return info.getManifest() ;
}

public boolean isStaticLargeObject() {
checkForInfoAndAllowHeaderSet();
return info.getStaticLargeObject();
}

public long getContentLength() {
checkForInfoAndAllowHeaderSet();
return info.getContentLength();
Expand Down Expand Up @@ -273,6 +278,31 @@ public String getTempGetUrl(long durationInSeconds) {
return getTempUrl("GET", durationInSeconds);
}

public String getImageScaleUrl(int percentage) {
if (percentage < 1 || percentage > 1000) {
throw new CommandException("Unable to scale image : " + String.valueOf(percentage));
}
return new ImageURL("GET", commandFactory.getTempUrlPrefix(), this).getImageScaleUrl(percentage);
}


public String getImageProcessUrl(String param_string) {
return new ImageURL("GET",commandFactory.getTempUrlPrefix(), this).getImageProcessUrl(param_string);
}

public String getImageScaleTempUrl(int percentage, long expiredtime) {
if (percentage < 1 || percentage > 1000) {
throw new CommandException("Unable to scale image : " + String.valueOf(percentage));
}
return new ImageURL("GET", commandFactory.getTempUrlPrefix(), this).setServerTimeExpiry(expiredtime).getImageScaleTempUrl(percentage);

}

public String getImageProcessTempUrl(String param_string, long expiredtime) {
return new ImageURL("GET", commandFactory.getTempUrlPrefix(), this).setServerTimeExpiry(expiredtime).getImageProcessTempUrl(param_string);

}

@Override
public String getTempPutUrl(long durationInSeconds) {
return getTempUrl("PUT", durationInSeconds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;

public class ContainerCache<N extends Container> {

private Map<String, N> cache = new TreeMap<String, N>();
private Map<String, N> cache = new ConcurrentHashMap<String, N>();

private final AbstractAccount account;

Expand Down
117 changes: 117 additions & 0 deletions src/main/java/org/javaswift/joss/client/core/ImageURL.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
package org.javaswift.joss.client.core;

import org.javaswift.joss.util.HashSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;
import java.util.HashMap;

public class ImageURL {

public static final Logger LOG = LoggerFactory.getLogger(ImageURL.class);

final private AbstractStoredObject object;

final private String prefix;

final private String method;

private long expiry;

private static final Map<String, String> hostnameMap;
static
{
hostnameMap = new HashMap<String, String>();
hostnameMap.put("mss.sankuai.com", "mss-img.sankuai.com");
hostnameMap.put("mss.vip.sankuai.com", "mss-img.vip.sankuai.com");
hostnameMap.put("msstest.sankuai.com", "msstest-img.sankuai.com");
hostnameMap.put("msstest.vip.sankuai.com", "msstest-img.vip.sankuai.com");

}

public ImageURL(final String method, final String prefix, final AbstractStoredObject object) {
this.method = method;
this.prefix = prefix;
this.object = object;
}

public ImageURL setServerTimeExpiry(final long seconds) {
this.expiry = this.object.getAccount().getActualServerTimeInSeconds(seconds);
return this;
}

public ImageURL setFixedExpiry(final long seconds) {
this.expiry = seconds;
return this;
}

protected String getSignaturePlainText(String param) {
// Note that we're not making use here of the standard getPath() because we don't want the URL encoded names,
// but the pure names. Swift uses the same approach to compose a signature plaintext with container/object names.
String objectPath = this.prefix + "/" + this.object.getContainer().getName() + "/" + this.object.getName() + "@" + param;
return this.method + "\n" + this.expiry + "\n" + objectPath;
}

protected String getSignature(String param) {
String plainText = getSignaturePlainText(param);
LOG.debug("Text to hash for the signature (CRLF replaced by readable \\n): "+plainText.replaceAll("\n", "\\n"));
return HashSignature.getSignature(this.object.getContainer().getAccount().getHashPassword(), plainText);
}

private String getImagePublicURL(String param) {
String public_url = this.object.getPublicURL();
String http_prefix = "";
String public_url_without_prefix;
if (public_url.startsWith("http://")) {
http_prefix = "http://";
public_url_without_prefix = public_url.substring(http_prefix.length());
} else if (public_url.startsWith("https://")) {
http_prefix = "https://";
public_url_without_prefix = public_url.substring(http_prefix.length());
} else {
public_url_without_prefix = public_url;
}
String[] url_split = public_url_without_prefix.split("/", 2);
String hostname_str = url_split[0];
String replace_hostname = this.hostnameMap.get(hostname_str);
if (replace_hostname != null) {
hostname_str = replace_hostname;
}
for (int i = 1; i < url_split.length; i++) {
hostname_str += "/" + url_split[i];
}
return http_prefix + hostname_str + "@" + param;

}

public String getImageScaleUrl(int percentage) {
String perentage_str = String.valueOf(percentage) + "p";
return this.getImageProcessUrl(perentage_str);
}


public String getImageProcessUrl(String param_string) {
return this.getImagePublicURL(param_string);
}

public String getImageScaleTempUrl(int percentage) {
String perentage_str = String.valueOf(percentage) + "p";
return this.getImageProcessTempUrl(perentage_str);
}

public String getImageProcessTempUrl(String param_string) {
return this.getImagePublicURL(param_string)+
"?temp_url_sig="+getSignature(param_string)+
"&temp_url_expires="+this.expiry;

}

@SuppressWarnings("SimplifiableIfStatement")
public boolean verify(String signature, long expiry, String param_string) {
if (signature == null || !signature.equals(getSignature(param_string))) {
return false;
}
return expiry > this.object.getAccount().getActualServerTimeInSeconds(0);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ public class AccountConfig {
*/
private String privateHost = null;

public boolean usePrivateURL = false;

/**
* If mock is turned off (default behaviour), then the real ObjectStore will be accessed. If not,
* an in-memory simulation of Swift will be used. It can be accessed as if it were a real
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,8 @@ public AccountFactory setHttpClient(HttpClient httpClient) {
return this;
}

public AccountFactory setUsePrivateURL(boolean b) {
this.config.usePrivateURL = b;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
public abstract class AbstractAccountCommand<M extends HttpRequestBase, N> extends AbstractSecureCommand<M, N> {

public AbstractAccountCommand(Account account, HttpClient httpClient, Access access) {
super(account, httpClient, getURL(access, account), access.getToken());
super(account, httpClient, getURL(access, account, account.isUsePrivateURL()), access.getToken());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
public abstract class AbstractContainerCommand<M extends HttpRequestBase, N> extends AbstractSecureCommand<M, N> {

public AbstractContainerCommand(Account account, HttpClient httpClient, Access access, Container container) {
super(account, httpClient, getURL(access, container), access.getToken());
super(account, httpClient, getURL(access, container, account.isUsePrivateURL()), access.getToken());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ private void logCall(M request) {
}

private void logError(M request, CommandException err) {
LOG.error(
"JOSS / "+getPrintableCall(request)+
(err.getHttpStatusCode() == 0 ? "" : ", HTTP status "+err.getHttpStatusCode())+
(err.getError() == null ? "" : ", Error "+err.getError())+
(err.getMessage() == null ? "" : ", Message '"+err.getMessage()+"'")+
(err.getCause() == null ? "" : ", Cause "+err.getCause().getClass().getSimpleName()));

StringBuffer errorMsg = new StringBuffer();
errorMsg.append("JOSS / " + getPrintableCall(request) +
(err.getHttpStatusCode() == 0 ? "" : ", HTTP status " + err.getHttpStatusCode()) +
(err.getError() == null ? "" : ", Error " + err.getError()) +
(err.getMessage() == null ? "" : ", Message '" + err.getMessage() + "'") +
(err.getCause() == null ? "" : ", Cause " + err.getCause().getClass().getSimpleName())
);
for (String printableHeaderLine : getPrintableHeaderLines(request)) {
LOG.error("* "+printableHeaderLine);
errorMsg.append(", * " + printableHeaderLine);
}
LOG.error(errorMsg.toString());
}

private String getPrintableCall(M request) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,43 @@
import org.javaswift.joss.model.Account;
import org.javaswift.joss.model.ObjectStoreEntity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public abstract class AbstractSecureCommand<M extends HttpRequestBase, N> extends AbstractCommand<M, N> {

private Account account;

public static final Logger LOG = LoggerFactory.getLogger(AbstractSecureCommand.class);

public AbstractSecureCommand(Account account, HttpClient httpClient, String url, String token) {
super(httpClient, url);
this.account = account;
setToken(token);
setConnectionKeepAlive();
}

public static String getURL(Access access, ObjectStoreEntity entity) {
public static String getURL(Access access, ObjectStoreEntity entity, boolean usePrivateURL) {
if (usePrivateURL) {
return access.getInternalURL() + entity.getPath();
}
return access.getPublicURL() + entity.getPath();
}

@Override
public N call() {
account.increaseCallCounter();
try {
if (account.isAllowReauthenticate()) {
super.setAllowErrorLog(false);
}
return super.call();
} catch (UnauthorizedException err) {
if (account.isAllowReauthenticate()) {
LOG.info("Reauthenticate");
Access access = account.authenticate();
setToken(access.getToken());
super.setAllowErrorLog(true);
return super.call();
}
throw err;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public String getPublicHost() {

@Override
public String getPrivateHost() {
return this.privateHost == null ? access.getPublicURL() : this.privateHost;
return this.privateHost == null ? access.getInternalURL() : this.privateHost;
}

@Override
Expand All @@ -63,7 +63,10 @@ public String getOriginalHost() {

@Override
public Access authenticate() {
return access = authCommand.call();
String oldRegion = access.getPreferredRegion();
access = authCommand.call();
access.setPreferredRegion(oldRegion);
return access;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public abstract class AbstractObjectCommand<M extends HttpRequestBase, N> extends AbstractSecureCommand<M, N> {

public AbstractObjectCommand(Account account, HttpClient httpClient, Access access, StoredObject object) {
super(account, httpClient, getURL(access, object), access.getToken());
super(account, httpClient, getURL(access, object, account.isUsePrivateURL()), access.getToken());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ protected ObjectInformation getReturnObject(HttpResponse response) throws IOExce
info.setContentType(ObjectContentType.fromResponse(response));
info.setDeleteAt(DeleteAt.fromResponse(response));
info.setManifest(ObjectManifest.fromResponse(response));
info.setStaticLargeObject(ObjectSLO.fromResponse(response));
return info;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
import org.javaswift.joss.model.Access;
import org.javaswift.joss.model.Account;
import org.javaswift.joss.model.StoredObject;
import org.javaswift.joss.headers.object.ObjectMetadata;

import java.io.IOException;
import java.util.Map;

public class UploadObjectCommandImpl extends AbstractObjectCommand<HttpPut, Object> implements UploadObjectCommand {

Expand All @@ -37,9 +39,20 @@ protected void prepareUpload(UploadInstructions uploadInstructions) throws IOExc
setHeader(uploadInstructions.getObjectManifest());
setHeader(uploadInstructions.getEtag());
setHeader(uploadInstructions.getContentType());
setUserMetadata(uploadInstructions.getMetadata());
request.setEntity(entity);
}

protected void setUserMetadata(Map<String, Object> metadata) {
if (metadata == null) {
return;
}
for (Map.Entry<String, Object> entry: metadata.entrySet()) {
ObjectMetadata objectmetadata = new ObjectMetadata(entry.getKey(), entry.getValue().toString());
setHeader(objectmetadata);
}
}

@Override
protected HttpPut createRequest(String url) {
HttpPut putMethod = new HttpPut(url);
Expand Down
Loading