-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
439 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package io.werender.examples; | ||
|
||
import org.apache.commons.cli.CommandLine; | ||
import org.apache.commons.cli.CommandLineParser; | ||
import org.apache.commons.cli.DefaultParser; | ||
import org.apache.commons.cli.HelpFormatter; | ||
import org.apache.commons.cli.Option; | ||
import org.apache.commons.cli.Options; | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
import org.openapitools.client.ApiClient; | ||
import org.openapitools.client.Configuration; | ||
import org.openapitools.client.model.StorageFile; | ||
|
||
import okhttp3.OkHttpClient; | ||
import okhttp3.logging.HttpLoggingInterceptor; | ||
|
||
public class App { | ||
private static Log log = LogFactory.getLog(App.class); | ||
|
||
private static final String APP_NAME = "werender-example-rest-java"; | ||
|
||
private static final String COMMAND_UPLOAD_FILE = "upload_file"; | ||
private static final String COMMAND_HELP = "help"; | ||
|
||
public static void handleUploadFile(CommandLine cmdLine) { | ||
// Retrieve configuration. | ||
Config config = Config.create(); | ||
log.info(String.format("Using server %s", config.getAddress())); | ||
|
||
// Create API client. | ||
ApiClient apiClient = Configuration.getDefaultApiClient(); | ||
apiClient.setBasePath(config.getAddress()); | ||
apiClient.setUserAgent("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15.7) WeRender/0.4.0"); | ||
|
||
OkHttpClient client = new OkHttpClient.Builder() | ||
.addInterceptor(new SignatureInterceptor(config.getPublicKey(), config.getPrivateKey())) | ||
.addInterceptor(new HttpLoggingInterceptor()).build(); | ||
apiClient.setHttpClient(client); | ||
|
||
// Upload the local file to remote directory. | ||
try { | ||
// Get local file path and remote directory path. | ||
String[] optionValues = cmdLine.getOptionValues(COMMAND_UPLOAD_FILE); | ||
String localFilePath = optionValues[0]; | ||
String remoteDirPath = optionValues[1]; | ||
log.info(String.format("Start to upload file from %s to %s", localFilePath, remoteDirPath)); | ||
|
||
// Create command to do the actual work. | ||
CommandContext commandContext = new CommandContext(apiClient); | ||
UploadFileCommand command = new UploadFileCommand(localFilePath, remoteDirPath); | ||
StorageFile file = command.execute(commandContext); | ||
|
||
log.info(String.format("Uploaded file from %s to %s with id %s", localFilePath, remoteDirPath, | ||
file.getId())); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} | ||
} | ||
|
||
public static void handleHelp(Options options) { | ||
HelpFormatter formatter = new HelpFormatter(); | ||
formatter.printHelp(APP_NAME, options); | ||
} | ||
|
||
public static void main(String[] args) { | ||
// Prepare command line options. | ||
Option uploadFileOption = Option.builder(COMMAND_UPLOAD_FILE).hasArgs() | ||
.desc("upload a file from local path to remote directory").build(); | ||
Option helpOption = Option.builder(COMMAND_HELP).desc("print help").build(); | ||
|
||
Options options = new Options(); | ||
options.addOption(uploadFileOption); | ||
options.addOption(helpOption); | ||
|
||
// Process command line. | ||
try { | ||
CommandLineParser parser = new DefaultParser(); | ||
CommandLine cmdLine = parser.parse(options, args); | ||
if (cmdLine.hasOption(COMMAND_HELP)) { | ||
handleHelp(options); | ||
} else if (cmdLine.hasOption(COMMAND_UPLOAD_FILE)) { | ||
handleUploadFile(cmdLine); | ||
} else { | ||
handleHelp(options); | ||
} | ||
} catch (Exception e) { | ||
System.out.println(e.getMessage()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package io.werender.examples; | ||
|
||
public interface Command<T> { | ||
|
||
public T execute(CommandContext context) throws Exception; | ||
|
||
} |
24 changes: 24 additions & 0 deletions
24
rest/java/src/main/java/io/werender/examples/CommandContext.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package io.werender.examples; | ||
|
||
import org.openapitools.client.ApiClient; | ||
import org.openapitools.client.api.StorageApi; | ||
|
||
public class CommandContext { | ||
|
||
private ApiClient apiClient; | ||
private StorageApi storageApi; | ||
|
||
public CommandContext(ApiClient apiClient) { | ||
this.apiClient = apiClient; | ||
storageApi = new StorageApi(apiClient); | ||
} | ||
|
||
public ApiClient getApiClient() { | ||
return apiClient; | ||
} | ||
|
||
public StorageApi getStorageApi() { | ||
return storageApi; | ||
} | ||
|
||
} |
109 changes: 109 additions & 0 deletions
109
rest/java/src/main/java/io/werender/examples/Config.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package io.werender.examples; | ||
|
||
import java.io.FileNotFoundException; | ||
import java.io.FileReader; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Paths; | ||
|
||
import org.apache.commons.lang3.SystemUtils; | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
|
||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import com.google.gson.JsonParser; | ||
|
||
public class Config { | ||
private static Log log = LogFactory.getLog(Config.class); | ||
|
||
public static final String DEFAULT_SERVER_ADDRESS = "https://api-us-east-2.werender.io/v1"; | ||
public static final String DEFAULT_SERVER_VERSION = "v1"; | ||
|
||
private String address; | ||
private String publicKey; | ||
private String privateKey; | ||
|
||
public static Config create() { | ||
/* Create instance. */ | ||
Config config = new Config(); | ||
|
||
/* Get home folder and configuration folder. */ | ||
String homeDirPath = SystemUtils.getUserHome().getAbsolutePath(); | ||
String configDirPath = new String(homeDirPath); | ||
if (SystemUtils.IS_OS_MAC_OSX) { | ||
configDirPath += "/Library/Application Support/werender"; | ||
} else { | ||
log.fatal(String.format("Unsupported platform")); | ||
} | ||
|
||
/* Read werender.config file. */ | ||
try { | ||
String serverAddress = Config.DEFAULT_SERVER_ADDRESS; | ||
|
||
String configFilePath = configDirPath + "/werender.config"; | ||
FileReader reader = new FileReader(configFilePath); | ||
JsonParser parser = new JsonParser(); | ||
JsonElement rootElement = parser.parse(reader); | ||
JsonObject rootObject = rootElement.getAsJsonObject(); | ||
if (rootObject.has("internal")) { | ||
JsonObject internalObject = rootObject.get("internal").getAsJsonObject(); | ||
if (internalObject.has("server")) { | ||
JsonObject serverObject = internalObject.get("server").getAsJsonObject(); | ||
if (serverObject.has("server_address")) { | ||
serverAddress = serverObject.get("server_address").getAsString(); | ||
} | ||
} | ||
} | ||
|
||
if (!serverAddress.endsWith(DEFAULT_SERVER_VERSION)) { | ||
serverAddress += String.format("/%s", DEFAULT_SERVER_VERSION); | ||
} | ||
config.setAddress(serverAddress); | ||
} catch (FileNotFoundException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
/* Read werender.key file. */ | ||
try { | ||
String keyFilePath = configDirPath + "/werender.key"; | ||
String key = Files.readString(Paths.get(keyFilePath)); | ||
String[] keyTokens = key.split(","); | ||
config.setPublicKey(keyTokens[0]); | ||
config.setPrivateKey(keyTokens[1].trim()); | ||
} catch (IOException e) { | ||
e.printStackTrace(); | ||
} | ||
|
||
/* Return instance. */ | ||
return config; | ||
} | ||
|
||
private Config() { | ||
} | ||
|
||
public String getAddress() { | ||
return address; | ||
} | ||
|
||
public void setAddress(String address) { | ||
this.address = address; | ||
} | ||
|
||
public String getPublicKey() { | ||
return publicKey; | ||
} | ||
|
||
public void setPublicKey(String publicKey) { | ||
this.publicKey = publicKey; | ||
} | ||
|
||
public String getPrivateKey() { | ||
return privateKey; | ||
} | ||
|
||
public void setPrivateKey(String privateKey) { | ||
this.privateKey = privateKey; | ||
} | ||
|
||
} |
59 changes: 59 additions & 0 deletions
59
rest/java/src/main/java/io/werender/examples/FileUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package io.werender.examples; | ||
|
||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.InputStream; | ||
import java.security.MessageDigest; | ||
|
||
import javax.xml.bind.annotation.adapters.HexBinaryAdapter; | ||
|
||
public final class FileUtil { | ||
|
||
public static final String MODE_STRICT = "strict"; | ||
public static final String MODE_UNIQUE = "unique"; | ||
|
||
public static final String EXT_FBX = "fbx"; | ||
public static final String EXT_USD = "usd"; | ||
|
||
public static final String CONTENT_TYPE_BINARY = "application/octet-stream"; | ||
public static final String CONTENT_TYPE_MODEL_FBX = "model/fbx"; | ||
public static final String CONTENT_TYPE_MODEL_USD = "model/usd"; | ||
|
||
public static String computeFileChecksum(File file) throws Exception { | ||
MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); | ||
try (InputStream input = new FileInputStream(file)) { | ||
|
||
byte[] buffer = new byte[8192]; | ||
int len = input.read(buffer); | ||
|
||
while (len != -1) { | ||
sha1.update(buffer, 0, len); | ||
len = input.read(buffer); | ||
} | ||
|
||
String checksum = new HexBinaryAdapter().marshal(sha1.digest()); | ||
checksum = "sha1:" + checksum.toLowerCase(); | ||
return checksum; | ||
} | ||
} | ||
|
||
public static String getContentType(String filePath) { | ||
String contentType = CONTENT_TYPE_BINARY; | ||
String[] tokens = filePath.split("\\."); | ||
if (tokens.length > 0) { | ||
String lastToken = tokens[tokens.length - 1]; | ||
switch (lastToken) { | ||
case EXT_FBX: | ||
contentType = CONTENT_TYPE_MODEL_FBX; | ||
break; | ||
case EXT_USD: | ||
contentType = CONTENT_TYPE_MODEL_USD; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
return contentType; | ||
} | ||
|
||
} |
67 changes: 67 additions & 0 deletions
67
rest/java/src/main/java/io/werender/examples/SignatureInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
package io.werender.examples; | ||
|
||
import java.io.IOException; | ||
import java.security.InvalidKeyException; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.text.SimpleDateFormat; | ||
import java.util.Base64; | ||
import java.util.Calendar; | ||
import java.util.Locale; | ||
import java.util.TimeZone; | ||
|
||
import javax.crypto.Mac; | ||
import javax.crypto.spec.SecretKeySpec; | ||
|
||
import okhttp3.Interceptor; | ||
import okhttp3.Request; | ||
import okhttp3.Response; | ||
|
||
public class SignatureInterceptor implements Interceptor { | ||
private static final String SIGNATURE_ALGORITHM = "HmacSHA1"; | ||
|
||
private String publicKey; | ||
private String privateKey; | ||
|
||
private static String getDate() { | ||
Calendar calendar = Calendar.getInstance(); | ||
SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); | ||
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); | ||
return dateFormat.format(calendar.getTime()); | ||
} | ||
|
||
private static String getSignature(String method, String host, String date, String privateKey) { | ||
String message = String.format("%s\n%s\n%s", method, host, date); | ||
String signature = null; | ||
try { | ||
SecretKeySpec signingKey = new SecretKeySpec(privateKey.getBytes(), SIGNATURE_ALGORITHM); | ||
Mac mac = Mac.getInstance(SIGNATURE_ALGORITHM); | ||
mac.init(signingKey); | ||
byte[] macOutput = mac.doFinal(message.getBytes()); | ||
signature = Base64.getEncoder().encodeToString(macOutput); | ||
} catch (NoSuchAlgorithmException e) { | ||
e.printStackTrace(); | ||
} catch (InvalidKeyException e) { | ||
e.printStackTrace(); | ||
} | ||
return signature; | ||
} | ||
|
||
public SignatureInterceptor(String publicKey, String privateKey) { | ||
this.publicKey = publicKey; | ||
this.privateKey = privateKey; | ||
} | ||
|
||
@Override | ||
public Response intercept(Chain chain) throws IOException { | ||
Request request = chain.request(); | ||
String method = request.method(); | ||
String date = getDate(); | ||
String host = request.url().host(); | ||
String signature = getSignature(method, host, date, privateKey); | ||
Request newRequest = request.newBuilder() | ||
.addHeader("Authorization", String.format("WR %s:%s", publicKey, signature)) | ||
.addHeader("Date", getDate()).addHeader("Host", host).build(); | ||
return chain.proceed(newRequest); | ||
} | ||
|
||
} |
Oops, something went wrong.