/* * Copyright (c) 2012-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.ReplicaUpdatePolicies; 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_xloc_set_invalidateRequest; import org.xtreemfs.pbrpc.generatedinterfaces.OSD.xtreemfs_xloc_set_invalidateResponse; import org.xtreemfs.pbrpc.generatedinterfaces.OSDServiceConstants; /** * Invalidates the XLocSet (view) on a certain replica.<br> * Invalidated replicas won't respond to operations until a newer XLocSet is installed. The installation will be * executed implicitly when a operation with a newer XLocSet is requested.<br> * This operation is intended to be called from the MRCs {@link XLocSetCoordinator}. */ public class InvalidateXLocSetOperation extends OSDOperation { final String sharedSecret; final ServiceUUID localUUID; public InvalidateXLocSetOperation(OSDRequestDispatcher master) { super(master); sharedSecret = master.getConfig().getCapabilitySecret(); localUUID = master.getConfig().getUUID(); } @Override public int getProcedureId() { return OSDServiceConstants.PROC_ID_XTREEMFS_XLOC_SET_INVALIDATE; } @Override public void startRequest(final OSDRequest rq) { xtreemfs_xloc_set_invalidateRequest rpcrq = (xtreemfs_xloc_set_invalidateRequest) rq.getRequestArgs(); master.getPreprocStage().invalidateXLocSet(rq, rpcrq.getFileCredentials(), true, new InvalidateXLocSetCallback() { @Override public void invalidateComplete(LeaseState leaseState, ErrorResponse error) { if (error != null) { rq.sendError(error); } else { postInvalidation(rq, leaseState); } } }); } private void postInvalidation(final OSDRequest rq, final LeaseState leaseState) { if (ReplicaUpdatePolicies.isRW(rq.getLocationList().getReplicaUpdatePolicy())) { master.getStorageStage().internalGetReplicaState(rq.getFileId(), rq.getLocationList().getLocalReplica().getStripingPolicy(), 0, new InternalGetReplicaStateCallback() { @Override public void getReplicaStateComplete(ReplicaStatus localState, ErrorResponse error) { if (error != null) { rq.sendError(error); } else { invalidationFinished(rq, leaseState, localState); } } }); } else { invalidationFinished(rq, leaseState, null); } } private void invalidationFinished(OSDRequest rq, LeaseState leaseState, ReplicaStatus localState) { xtreemfs_xloc_set_invalidateResponse.Builder response = xtreemfs_xloc_set_invalidateResponse.newBuilder(); response.setLeaseState(leaseState); if (localState != null) { response.setReplicaStatus(localState); } rq.sendSuccess(response.build(), null); } @Override public void startInternalEvent(Object[] args) { throw new UnsupportedOperationException("Not supported yet."); } @Override public ErrorResponse parseRPCMessage(OSDRequest rq) { try { xtreemfs_xloc_set_invalidateRequest rpcrq = (xtreemfs_xloc_set_invalidateRequest) 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() { // View validation will be handled at {@link PreprocStage#invalidateXLocSet()}. return true; } }