package org.xtreemfs.sandbox;
import java.io.IOException;
import java.util.Arrays;
import org.xtreemfs.common.libxtreemfs.Client;
import org.xtreemfs.common.libxtreemfs.ClientFactory;
import org.xtreemfs.common.libxtreemfs.FileHandle;
import org.xtreemfs.common.libxtreemfs.Options;
import org.xtreemfs.common.libxtreemfs.Volume;
import org.xtreemfs.foundation.SSLOptions;
import org.xtreemfs.foundation.logging.Logging;
import org.xtreemfs.foundation.pbrpc.Schemes;
import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials;
import org.xtreemfs.foundation.util.PBRPCServiceURL;
import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.PORTS;
import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL;
/**
* Minimal example which uses the libxtreemfs for Java and default SSL certificates from tests/certs/ to test
* basic functionality of running servers.
*
* The URL to an existing volume has to be provided as first parameter e.g., pbrpcs://localhost/regular
*
* You can easily start a full XtreemFS installation with SSL enabled as follows:
*
* - go to the "tests" directory below the root of the XtreemFS repository
*
* - run "./xtestenv -f -v regular" to start an SSL-enabled test setup which creates a new volume "regular"
*
* - press the Enter key to shut it down again
*
* Don't forget to set the working directory to the root of the XtreemFS repository. Otherwise, the example
* won't find the default SSL certificates which are also used by the test setup.
*
* E.g., in Eclipse set the working directory to: ${workspace_loc:xtreemfs_server}/../../ when
* "xtreemfs_server" is the name of the Eclipse project.
*
* @author mberlin
*
*/
public class ExampleLibxtreemfsWithSSL {
/** Directory with testing SSL certificates. Path relative to the root of the repository. */
public static final String CERT_DIR = "tests/certs/";
/**
* @param args
* args[0] = URL to existing volume e.g., pbrpcs://localhost/regular
* @return
* @throws Exception
*/
public static void main(String[] args) {
if (args.length < 1) {
System.out.println("usage: <URL to existing volume e.g., pbrpcs://localhost/regular>");
return;
}
Client client = null;
FileHandle fileHandle = null;
try {
// Parse command line parameter.
int lastSlashIndex = args[0].lastIndexOf('/');
final PBRPCServiceURL url = new PBRPCServiceURL(args[0].substring(0, lastSlashIndex),
Schemes.SCHEME_PBRPC, PORTS.DIR_PBRPC_PORT_DEFAULT.getNumber());
final String volumeName = args[0].substring(lastSlashIndex + 1);
// Init libxtreemfs
final Options options = new Options();
final UserCredentials userCredentials = UserCredentials.newBuilder()
.setUsername(System.getProperty("user.name")).addGroups("root").build();
final SSLOptions sslOptions = url.getProtocol().equals(Schemes.SCHEME_PBRPC) ? null : new SSLOptions(
CERT_DIR + "Client.p12", "passphrase", SSLOptions.PKCS12_CONTAINER, CERT_DIR + "trusted.jks",
"passphrase", SSLOptions.JKS_CONTAINER, false, false, null, null);
// Alternatively, specify own certificate files for debugging:
// final SSLOptions sslOptions = new SSLOptions(
// new FileInputStream(
// "/home/mberlin/ZIB/XtreemFS/tasks archive/2013-08-05 Debug SSL issues/xtfsclient/config/xtfs-vm-certs/TestUser01.p12"),
// "test123",
// SSLOptions.PKCS12_CONTAINER,
// new FileInputStream(
// "/home/mberlin/ZIB/XtreemFS/tasks archive/2013-08-05 Debug SSL issues/xtfsclient/config/xtfs-vm-certs/trusted.jks"),
// "J9AUcbrdVkFg75kcqumz", SSLOptions.JKS_CONTAINER, false, false, null);
Logging.start(Logging.LEVEL_WARN);
client = ClientFactory.createClient(url.getHost() + ":" + url.getPort(), userCredentials, sslOptions,
options);
client.start();
Volume volume = client.openVolume(volumeName, sslOptions, options);
// Open a file.
fileHandle = volume.openFile(
userCredentials,
"/example_libxtreemfs_test_" + String.format("%03d", (int) (Math.random() * 1000)) + ".bin",
SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber()
| SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_EXCL.getNumber()
| SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber(), 0644);
// Init chunk to be written.
byte[] data = new byte[1 << 17]; // 128 kB chunk.
Arrays.fill(data, (byte) 0xAB);
// Write 1 MB to file.
for (int offset = 0; offset < (1 << 20); offset += data.length) {
fileHandle.write(userCredentials, data, data.length, offset);
}
// Read 1 MB from file.
byte[] readData = new byte[data.length];
for (int offset = 0; offset < (1 << 20); offset += data.length) {
int readCount = fileHandle.read(userCredentials, readData, data.length, offset);
if (readCount != data.length) {
throw new IOException("Read less data than expected: " + readCount + " bytes instead of: "
+ data.length);
}
if (!Arrays.equals(readData, data)) {
throw new IOException("Read data differs from written chunk at offset: " + offset);
}
}
} catch (Exception e) {
System.err.println("An error occurred: " + e.getMessage() + "\n Full Stacktrace:\n" + e.getStackTrace());
return;
} finally {
if (fileHandle != null) {
try {
fileHandle.close();
} catch (IOException e) {
System.err.println("Failed to close() the file: " + e.getMessage() + "\n Full Stacktrace:\n"
+ e.getStackTrace());
return;
}
}
if (client != null) {
client.shutdown();
}
System.out.println("If no errors are shown, the example was successfully executed.");
}
return;
}
}