/* * Copyright (c) 2013 by Johannes Dillmann, Zuse Institute Berlin * * Licensed under the BSD License, see LICENSE file for details. * */ package org.xtreemfs.osd.operations; import org.xtreemfs.common.Capability; import org.xtreemfs.common.uuids.ServiceUUID; import org.xtreemfs.common.xloc.InvalidXLocationsException; import org.xtreemfs.common.xloc.XLocations; import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.ErrorType; import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.POSIXErrno; import org.xtreemfs.foundation.pbrpc.generatedinterfaces.RPC.RPCHeader.ErrorResponse; import org.xtreemfs.foundation.pbrpc.utils.ErrorUtils; import org.xtreemfs.mrc.stages.XLocSetCoordinator; import org.xtreemfs.osd.OSDRequest; import org.xtreemfs.osd.OSDRequestDispatcher; import org.xtreemfs.osd.stages.PreprocStage.InvalidateXLocSetCallback; import org.xtreemfs.osd.stages.StorageStage.InternalGetReplicaStateCallback; import org.xtreemfs.pbrpc.generatedinterfaces.GlobalTypes.LeaseState; import org.xtreemfs.pbrpc.generatedinterfaces.OSD.ReplicaStatus; import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_auth_stateRequest; import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_rwr_reset_statusResponse; import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; /** * Sets the authoritative state on an invalidated replica and fetch missing data from other OSDs. <br> * In contrast to {@link InternalRWRAuthStateOperation} this operation does not require a valid view and works on * invalidated replicas. Effectively the replica will be invalidated when executing this operation. <br> * This operation is intended to be called from the MRCs {@link XLocSetCoordinator}. */ public class InternalRWRAuthStateInvalidatedOperation extends OSDOperation { final String sharedSecret; final ServiceUUID localUUID; public InternalRWRAuthStateInvalidatedOperation(OSDRequestDispatcher master) { super(master); sharedSecret = master.getConfig().getCapabilitySecret(); localUUID = master.getConfig().getUUID(); } @Override public int getProcedureId() { return OSDServiceConstants.PROC_ID_XTREEMFS_RWR_AUTH_STATE_INVALIDATED; } @Override public void startRequest(final OSDRequest rq) { final xtreemfs_rwr_auth_stateRequest args = (xtreemfs_rwr_auth_stateRequest) rq.getRequestArgs(); master.getPreprocStage().invalidateXLocSet(rq, args.getFileCredentials(), false, new InvalidateXLocSetCallback() { @Override public void invalidateComplete(LeaseState leaseState, ErrorResponse error) { if (error != null) { rq.sendError(error); } else { postInvalidation(rq); } } }); } private void postInvalidation(final OSDRequest rq) { final String fileId = rq.getFileId(); final xtreemfs_rwr_auth_stateRequest args = (xtreemfs_rwr_auth_stateRequest) rq.getRequestArgs(); master.getStorageStage().internalGetReplicaState(fileId, rq.getLocationList().getLocalReplica().getStripingPolicy(), 0, new InternalGetReplicaStateCallback() { @Override public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { if (error != null) { rq.sendError(error); } else if (InternalRWRResetStatusOperation.checkReplicaStateComplete(args.getState(), localState)) { respond(rq, false, true); } else { // Start the RESET asynchronously and respond immediately. master.getRWReplicationStage().invalidatedReplicaReset(fileId, args.getState(), localState, args.getFileCredentials(), rq.getLocationList(), rq); respond(rq, true, false); } } }); } private void respond(final OSDRequest rq, boolean running, boolean complete) { xtreemfs_rwr_reset_statusResponse response = xtreemfs_rwr_reset_statusResponse.newBuilder().setRunning(running) .setComplete(complete).build(); rq.sendSuccess(response, null); } @Override public void startInternalEvent(Object[] args) { throw new UnsupportedOperationException("Not supported yet."); } @Override public ErrorResponse parseRPCMessage(OSDRequest rq) { try { xtreemfs_rwr_auth_stateRequest rpcrq = (xtreemfs_rwr_auth_stateRequest) rq.getRequestArgs(); rq.setFileId(rpcrq.getFileId()); rq.setCapability(new Capability(rpcrq.getFileCredentials().getXcap(), sharedSecret)); rq.setLocationList(new XLocations(rpcrq.getFileCredentials().getXlocs(), localUUID)); return null; } catch (InvalidXLocationsException ex) { return ErrorUtils.getErrorResponse(ErrorType.ERRNO, POSIXErrno.POSIX_ERROR_EINVAL, ex.toString()); } catch (Throwable ex) { return ErrorUtils.getInternalServerError(ex); } } @Override public boolean requiresCapability() { return true; } @Override public boolean bypassViewValidation() { return true; } }