/* * Copyright (c) 2011 by Paul Seiferth, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package org.xtreemfs.common.libxtreemfs; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Map; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.xtreemfs.common.ReplicaUpdatePolicies; import org.xtreemfs.common.libxtreemfs.ClientFactory.ClientType; import org.xtreemfs.common.libxtreemfs.RPCCaller.CallGenerator; import org.xtreemfs.dir.DIRConfig; import org.xtreemfs.dir.DIRRequestDispatcher; import org.xtreemfs.foundation.buffer.ReusableBuffer; import org.xtreemfs.foundation.json.JSONParser; import org.xtreemfs.foundation.json.JSONString; import org.xtreemfs.foundation.logging.Logging; import org.xtreemfs.foundation.pbrpc.client.RPCAuthentication; import org.xtreemfs.foundation.pbrpc.client.RPCResponse; import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.Auth; import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.UserCredentials; import org.xtreemfs.foundation.util.FSUtils; import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.OSDWriteResponse; import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.REPL_FLAG; import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SERVICES; import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.SYSTEM_V_FCNTL; import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openRequest; import org.xtreemfs.pbrpc.generatedinterfaces.MRC.openResponse; import org.xtreemfs.pbrpc.generatedinterfaces.MRCServiceClient; import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ObjectData; import org.xtreemfs.pbrpc.generatedinterfaces.OSD.writeRequest; import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceClient; import org.xtreemfs.test.SetupUtils; import org.xtreemfs.test.TestEnvironment; import org.xtreemfs.test.TestHelper; public class RPCCallerTest { @Rule public final TestRule testLog = TestHelper.testLog; private static DIRRequestDispatcher dir; private static DIRConfig dirConfig; private static TestEnvironment testEnv; private static UserCredentials userCredentials; private static Auth auth; private static String dirServiceAddress; private static String mrcServiceAddress; private static MRCServiceClient mrcServiceClient; private static OSDServiceClient osdServiceClient; @BeforeClass public static void initializeTest() throws Exception { Logging.start(SetupUtils.DEBUG_LEVEL, SetupUtils.DEBUG_CATEGORIES); FSUtils.delTree(new java.io.File(SetupUtils.TEST_DIR)); dirConfig = SetupUtils.createDIRConfig(); dir = new DIRRequestDispatcher(dirConfig, SetupUtils.createDIRdbsConfig()); dir.startup(); dir.waitForStartup(); testEnv = new TestEnvironment(new TestEnvironment.Services[] { TestEnvironment.Services.DIR_CLIENT, TestEnvironment.Services.TIME_SYNC, TestEnvironment.Services.RPC_CLIENT, TestEnvironment.Services.MRC, TestEnvironment.Services.OSD, TestEnvironment.Services.OSD }); testEnv.start(); userCredentials = UserCredentials.newBuilder().setUsername("test").addGroups("test").build(); auth = RPCAuthentication.authNone; dirServiceAddress = testEnv.getDIRAddress().getHostName() + ":" + testEnv.getDIRAddress().getPort(); mrcServiceAddress = testEnv.getMRCAddress().getHostName() + ":" + testEnv.getMRCAddress().getPort(); mrcServiceClient = new MRCServiceClient(testEnv.getRpcClient(), null); osdServiceClient = new OSDServiceClient(testEnv.getRpcClient(), null); } @AfterClass public static void shutdownTest() throws Exception { testEnv.shutdown(); dir.shutdown(); dir.waitForShutdown(); } @SuppressWarnings("unchecked") @Test public void testRedirect() throws Exception { final String VOLUME_NAME = "testVolume"; final String FILE_PATH = "replicatedFile"; final int NUMBER_OF_REPLICAS = 2; Options options = new Options(); ClientImplementation client = (ClientImplementation) ClientFactory.createClient(ClientType.JAVA, dirServiceAddress, userCredentials, null, options); client.start(); client.createVolume(mrcServiceAddress, auth, userCredentials, VOLUME_NAME); Volume volume = client.openVolume(VOLUME_NAME, null, options); // set default replication policy for root dir volume.setDefaultReplicationPolicy(userCredentials, "/", ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, NUMBER_OF_REPLICAS, REPL_FLAG.REPL_FLAG_FULL_REPLICA.getNumber()); String replPolString = volume.getXAttr(userCredentials, "/", "xtreemfs.default_rp"); JSONString policy = new JSONString(replPolString); Map<String, Object> jsonMap = (Map<String, Object>) JSONParser.parseJSON(policy); assertEquals(ReplicaUpdatePolicies.REPL_UPDATE_PC_WARONE, jsonMap.get("update-policy").toString()); UUIDIterator mrcUUIDIterator = new UUIDIterator(); mrcUUIDIterator.addUUID(mrcServiceAddress); openRequest request = openRequest .newBuilder() .setVolumeName(VOLUME_NAME) .setPath(FILE_PATH) .setFlags( SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_CREAT.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_TRUNC.getNumber() | SYSTEM_V_FCNTL.SYSTEM_V_FCNTL_H_O_RDWR.getNumber()).setMode(0777) .setAttributes(0).build(); openResponse response = RPCCaller.<openRequest, openResponse> syncCall(SERVICES.MRC, userCredentials, auth, options, client, mrcUUIDIterator, true, request, new CallGenerator<openRequest, openResponse>() { @Override public RPCResponse<openResponse> executeCall(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, openRequest input) throws IOException { return mrcServiceClient.open(server, authHeader, userCreds, input); } }); FileInfo fileInfo = new FileInfo((VolumeImplementation) volume, Helper.extractFileIdFromXcap(response .getCreds().getXcap()), FILE_PATH, false, response.getCreds().getXlocs(), Helper.generateVersion4UUID()); FileHandleImplementation fileHandle = fileInfo.createFileHandle(response.getCreds().getXcap(), false); // write testfile String data = "Need a testfile? Why not (\\|)(+,,,+)(|/)?"; fileHandle.write(userCredentials, data.getBytes(), data.length(), 0); // create uuidIterator with switched OSDs in order force a Redirect Exception UUIDIterator uuidIterator = new UUIDIterator(); uuidIterator.addUUID(response.getCreds().getXlocs().getReplicas(1).getOsdUuids(0)); uuidIterator.addUUID(response.getCreds().getXlocs().getReplicas(0).getOsdUuids(0)); // make a write with the new uuidIterator String overwriteData = "1111111111111111111111111111111111111111111111111111"; final ReusableBuffer overwriteBuf = ReusableBuffer.wrap(overwriteData.getBytes()); writeRequest.Builder writeReq = writeRequest.newBuilder(); writeReq.setFileCredentials(response.getCreds()); writeReq.setFileId(response.getCreds().getXcap().getFileId()); writeReq.setObjectNumber(0); writeReq.setObjectVersion(0); writeReq.setOffset(0); writeReq.setLeaseTimeout(0); ObjectData objectData = ObjectData.newBuilder().setChecksum(0).setInvalidChecksumOnOsd(false) .setZeroPadding(0).build(); writeReq.setObjectData(objectData); RPCCaller.<writeRequest, OSDWriteResponse> syncCall(SERVICES.OSD, userCredentials, auth, options, client, uuidIterator, false, writeReq.build(), new CallGenerator<writeRequest, OSDWriteResponse>() { @Override public RPCResponse<OSDWriteResponse> executeCall(InetSocketAddress server, Auth authHeader, UserCredentials userCreds, writeRequest input) throws IOException { // TODO Auto-generated method stub return osdServiceClient.write(server, authHeader, userCreds, input, overwriteBuf); } }); // Read from file. byte[] readData = new byte[overwriteData.length()]; int readCount = fileHandle.read(userCredentials, readData, overwriteData.length(), 0); assertEquals(overwriteData.length(), readCount); for (int i = 0; i < overwriteData.length(); i++) { assertEquals(readData[i], overwriteData.getBytes()[i]); } } }