blob: 31af0f16e15eb017ca9713eebc2039cafeffb152 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.hadoop.ozone.protocolPB;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
import com.google.protobuf.ByteString;
import com.google.protobuf.ServiceException;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.hadoop.hdds.client.ECReplicationConfig;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
import org.apache.hadoop.hdds.protocol.proto.HddsProtos.UpgradeFinalizationStatus;
import org.apache.hadoop.hdds.client.ReplicationConfig;
import org.apache.hadoop.hdds.utils.db.SequenceNumberNotFoundException;
import org.apache.hadoop.ozone.OzoneAcl;
import org.apache.hadoop.ozone.om.OzoneManager;
import org.apache.hadoop.ozone.om.OzoneManagerPrepareState;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.om.helpers.BucketLayout;
import org.apache.hadoop.ozone.om.helpers.DBUpdates;
import org.apache.hadoop.ozone.om.helpers.KeyInfoWithVolumeContext;
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadList;
import org.apache.hadoop.ozone.om.helpers.OmMultipartUploadListParts;
import org.apache.hadoop.ozone.om.helpers.OmPartInfo;
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
import org.apache.hadoop.ozone.om.helpers.OzoneFileStatus;
import org.apache.hadoop.ozone.om.helpers.RepeatedOmKeyInfo;
import org.apache.hadoop.ozone.om.helpers.ServiceInfo;
import org.apache.hadoop.ozone.om.helpers.ServiceInfoEx;
import org.apache.hadoop.ozone.om.helpers.SnapshotInfo;
import org.apache.hadoop.ozone.om.helpers.TenantStateList;
import org.apache.hadoop.ozone.om.helpers.TenantUserInfoValue;
import org.apache.hadoop.ozone.om.helpers.TenantUserList;
import org.apache.hadoop.ozone.om.ratis.OzoneManagerDoubleBuffer;
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils;
import org.apache.hadoop.ozone.om.request.OMClientRequest;
import org.apache.hadoop.ozone.om.request.util.OmResponseUtil;
import org.apache.hadoop.ozone.om.request.validation.RequestFeatureValidator;
import org.apache.hadoop.ozone.om.request.validation.RequestProcessingPhase;
import org.apache.hadoop.ozone.om.request.validation.ValidationCondition;
import org.apache.hadoop.ozone.om.request.validation.ValidationContext;
import org.apache.hadoop.ozone.om.response.OMClientResponse;
import org.apache.hadoop.ozone.om.upgrade.DisallowedUntilLayoutVersion;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CheckVolumeAccessRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.CheckVolumeAccessResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.EchoRPCRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.EchoRPCResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.FinalizeUpgradeProgressRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.FinalizeUpgradeProgressResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetFileStatusRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetFileStatusResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetKeyInfoRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetKeyInfoResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.InfoBucketRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.InfoBucketResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.InfoVolumeRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.InfoVolumeResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyArgs;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyInfo;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListBucketsRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListBucketsResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListKeysRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListKeysResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTenantRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTenantResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTrashRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListTrashResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListVolumeResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupKeyRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupKeyResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.MultipartUploadListPartsRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.MultipartUploadListPartsResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneFileStatusProto;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PrepareStatusResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RangerBGSyncRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RangerBGSyncResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.RepeatedKeyInfo;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ServiceListResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetS3VolumeContextResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Status;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SnapshotDiffRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.SnapshotDiffResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantGetUserInfoResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantListUserRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.TenantListUserResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type;
import org.apache.hadoop.ozone.security.acl.OzoneObjInfo;
import com.google.common.collect.Lists;
import static org.apache.hadoop.ozone.om.upgrade.OMLayoutFeature.MULTITENANCY_SCHEMA;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesRequest;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.DBUpdatesResponse;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetAclRequest;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.GetAclResponse;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListMultipartUploadsRequest;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListMultipartUploadsResponse;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListStatusRequest;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.ListStatusResponse;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupFileRequest;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.LookupFileResponse;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.MultipartUploadInfo;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneAclInfo;
import static org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.PartInfo;
import org.apache.hadoop.ozone.upgrade.UpgradeFinalizer.StatusAndMessages;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Command Handler for OM requests. OM State Machine calls this handler for
* deserializing the client request and sending it to OM.
*/
public class OzoneManagerRequestHandler implements RequestHandler {
static final Logger LOG =
LoggerFactory.getLogger(OzoneManagerRequestHandler.class);
private final OzoneManager impl;
private OzoneManagerDoubleBuffer ozoneManagerDoubleBuffer;
private static final int RPC_PAYLOAD_MULTIPLICATION_FACTOR = 1024;
private static final int MAX_SIZE_KB = 2097151;
public OzoneManagerRequestHandler(OzoneManager om,
OzoneManagerDoubleBuffer ozoneManagerDoubleBuffer) {
this.impl = om;
this.ozoneManagerDoubleBuffer = ozoneManagerDoubleBuffer;
}
//TODO simplify it to make it shorter
@SuppressWarnings("methodlength")
@Override
public OMResponse handleReadRequest(OMRequest request) {
if (LOG.isDebugEnabled()) {
LOG.debug("Received OMRequest: {}, ", request);
}
Type cmdType = request.getCmdType();
OMResponse.Builder responseBuilder = OmResponseUtil.getOMResponseBuilder(
request);
try {
switch (cmdType) {
case CheckVolumeAccess:
CheckVolumeAccessResponse checkVolumeAccessResponse = checkVolumeAccess(
request.getCheckVolumeAccessRequest());
responseBuilder.setCheckVolumeAccessResponse(checkVolumeAccessResponse);
break;
case InfoVolume:
InfoVolumeResponse infoVolumeResponse = infoVolume(
request.getInfoVolumeRequest());
responseBuilder.setInfoVolumeResponse(infoVolumeResponse);
break;
case ListVolume:
ListVolumeResponse listVolumeResponse = listVolumes(
request.getListVolumeRequest());
responseBuilder.setListVolumeResponse(listVolumeResponse);
break;
case InfoBucket:
InfoBucketResponse infoBucketResponse = infoBucket(
request.getInfoBucketRequest());
responseBuilder.setInfoBucketResponse(infoBucketResponse);
break;
case ListBuckets:
ListBucketsResponse listBucketsResponse = listBuckets(
request.getListBucketsRequest());
responseBuilder.setListBucketsResponse(listBucketsResponse);
break;
case LookupKey:
LookupKeyResponse lookupKeyResponse = lookupKey(
request.getLookupKeyRequest(), request.getVersion());
responseBuilder.setLookupKeyResponse(lookupKeyResponse);
break;
case ListKeys:
ListKeysResponse listKeysResponse = listKeys(
request.getListKeysRequest(), request.getVersion());
responseBuilder.setListKeysResponse(listKeysResponse);
break;
case ListTrash:
ListTrashResponse listTrashResponse = listTrash(
request.getListTrashRequest(), request.getVersion());
responseBuilder.setListTrashResponse(listTrashResponse);
break;
case ListMultiPartUploadParts:
MultipartUploadListPartsResponse listPartsResponse =
listParts(request.getListMultipartUploadPartsRequest());
responseBuilder.setListMultipartUploadPartsResponse(listPartsResponse);
break;
case ListMultipartUploads:
ListMultipartUploadsResponse response =
listMultipartUploads(request.getListMultipartUploadsRequest());
responseBuilder.setListMultipartUploadsResponse(response);
break;
case ServiceList:
ServiceListResponse serviceListResponse = getServiceList(
request.getServiceListRequest());
responseBuilder.setServiceListResponse(serviceListResponse);
break;
case RangerBGSync:
RangerBGSyncResponse rangerBGSyncResponse = triggerRangerBGSync(
request.getRangerBGSyncRequest());
responseBuilder.setRangerBGSyncResponse(rangerBGSyncResponse);
break;
case DBUpdates:
DBUpdatesResponse dbUpdatesResponse = getOMDBUpdates(
request.getDbUpdatesRequest());
responseBuilder.setDbUpdatesResponse(dbUpdatesResponse);
break;
case GetFileStatus:
GetFileStatusResponse getFileStatusResponse = getOzoneFileStatus(
request.getGetFileStatusRequest(), request.getVersion());
responseBuilder.setGetFileStatusResponse(getFileStatusResponse);
break;
case LookupFile:
LookupFileResponse lookupFileResponse =
lookupFile(request.getLookupFileRequest(), request.getVersion());
responseBuilder.setLookupFileResponse(lookupFileResponse);
break;
case ListStatus:
ListStatusResponse listStatusResponse =
listStatus(request.getListStatusRequest(), request.getVersion());
responseBuilder.setListStatusResponse(listStatusResponse);
break;
case GetAcl:
GetAclResponse getAclResponse =
getAcl(request.getGetAclRequest());
responseBuilder.setGetAclResponse(getAclResponse);
break;
case FinalizeUpgradeProgress:
FinalizeUpgradeProgressResponse upgradeProgressResponse =
reportUpgradeProgress(request.getFinalizeUpgradeProgressRequest());
responseBuilder
.setFinalizeUpgradeProgressResponse(upgradeProgressResponse);
break;
case PrepareStatus:
PrepareStatusResponse prepareStatusResponse = getPrepareStatus();
responseBuilder.setPrepareStatusResponse(prepareStatusResponse);
break;
case GetS3VolumeContext:
GetS3VolumeContextResponse s3VolumeContextResponse =
getS3VolumeContext();
responseBuilder.setGetS3VolumeContextResponse(s3VolumeContextResponse);
break;
case TenantGetUserInfo:
impl.checkS3MultiTenancyEnabled();
TenantGetUserInfoResponse getUserInfoResponse = tenantGetUserInfo(
request.getTenantGetUserInfoRequest());
responseBuilder.setTenantGetUserInfoResponse(getUserInfoResponse);
break;
case ListTenant:
impl.checkS3MultiTenancyEnabled();
ListTenantResponse listTenantResponse = listTenant(
request.getListTenantRequest());
responseBuilder.setListTenantResponse(listTenantResponse);
break;
case TenantListUser:
impl.checkS3MultiTenancyEnabled();
TenantListUserResponse listUserResponse = tenantListUsers(
request.getTenantListUserRequest());
responseBuilder.setTenantListUserResponse(listUserResponse);
break;
case GetKeyInfo:
responseBuilder.setGetKeyInfoResponse(
getKeyInfo(request.getGetKeyInfoRequest(), request.getVersion()));
break;
case ListSnapshot:
OzoneManagerProtocolProtos.ListSnapshotResponse listSnapshotResponse =
getSnapshots(request.getListSnapshotRequest());
responseBuilder.setListSnapshotResponse(listSnapshotResponse);
break;
case SnapshotDiff:
SnapshotDiffResponse snapshotDiffReport = snapshotDiff(
request.getSnapshotDiffRequest());
responseBuilder.setSnapshotDiffResponse(snapshotDiffReport);
break;
case EchoRPC:
EchoRPCResponse echoRPCResponse =
echoRPC(request.getEchoRPCRequest());
responseBuilder.setEchoRPCResponse(echoRPCResponse);
default:
responseBuilder.setSuccess(false);
responseBuilder.setMessage("Unrecognized Command Type: " + cmdType);
break;
}
responseBuilder.setSuccess(true);
} catch (IOException ex) {
responseBuilder.setSuccess(false);
responseBuilder.setStatus(exceptionToResponseStatus(ex));
if (ex.getMessage() != null) {
responseBuilder.setMessage(ex.getMessage());
}
}
return responseBuilder.build();
}
@Override
public OMClientResponse handleWriteRequest(OMRequest omRequest,
long transactionLogIndex) throws IOException {
OMClientRequest omClientRequest = null;
OMClientResponse omClientResponse = null;
omClientRequest =
OzoneManagerRatisUtils.createClientRequest(omRequest, impl);
omClientResponse = omClientRequest
.validateAndUpdateCache(getOzoneManager(), transactionLogIndex,
ozoneManagerDoubleBuffer::add);
return omClientResponse;
}
@Override
public void updateDoubleBuffer(OzoneManagerDoubleBuffer omDoubleBuffer) {
this.ozoneManagerDoubleBuffer = omDoubleBuffer;
}
private DBUpdatesResponse getOMDBUpdates(
DBUpdatesRequest dbUpdatesRequest)
throws SequenceNumberNotFoundException {
DBUpdatesResponse.Builder builder = DBUpdatesResponse
.newBuilder();
DBUpdates dbUpdatesWrapper =
impl.getDBUpdates(dbUpdatesRequest);
for (int i = 0; i < dbUpdatesWrapper.getData().size(); i++) {
builder.addData(OMPBHelper.getByteString(
dbUpdatesWrapper.getData().get(i)));
}
builder.setSequenceNumber(dbUpdatesWrapper.getCurrentSequenceNumber());
builder.setLatestSequenceNumber(dbUpdatesWrapper.getLatestSequenceNumber());
return builder.build();
}
private GetAclResponse getAcl(GetAclRequest req) throws IOException {
List<OzoneAclInfo> acls = new ArrayList<>();
List<OzoneAcl> aclList =
impl.getAcl(OzoneObjInfo.fromProtobuf(req.getObj()));
if (aclList != null) {
aclList.forEach(a -> acls.add(OzoneAcl.toProtobuf(a)));
}
return GetAclResponse.newBuilder().addAllAcls(acls).build();
}
// Convert and exception to corresponding status code
protected Status exceptionToResponseStatus(IOException ex) {
if (ex instanceof OMException) {
return Status.values()[((OMException) ex).getResult().ordinal()];
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("Unknown error occurs", ex);
}
return Status.INTERNAL_ERROR;
}
}
/**
* Validates that the incoming OM request has required parameters.
* TODO: Add more validation checks before writing the request to Ratis log.
*
* @param omRequest client request to OM
* @throws OMException thrown if required parameters are set to null.
*/
@Override
public void validateRequest(OMRequest omRequest) throws OMException {
Type cmdType = omRequest.getCmdType();
if (cmdType == null) {
throw new OMException("CmdType is null",
OMException.ResultCodes.INVALID_REQUEST);
}
if (omRequest.getClientId() == null) {
throw new OMException("ClientId is null",
OMException.ResultCodes.INVALID_REQUEST);
}
// Layout version should have been set up the leader while serializing
// the request, and hence cannot be null. This version is used by each
// node to identify which request handler version to use.
if (omRequest.getLayoutVersion() == null) {
throw new OMException("LayoutVersion for request is null.",
OMException.ResultCodes.INTERNAL_ERROR);
}
}
private CheckVolumeAccessResponse checkVolumeAccess(
CheckVolumeAccessRequest request) throws IOException {
CheckVolumeAccessResponse.Builder resp =
CheckVolumeAccessResponse.newBuilder();
boolean access = impl.checkVolumeAccess(request.getVolumeName(),
request.getUserAcl());
// if no access, set the response status as access denied
if (!access) {
throw new OMException(OMException.ResultCodes.ACCESS_DENIED);
}
return resp.build();
}
private InfoVolumeResponse infoVolume(InfoVolumeRequest request)
throws IOException {
InfoVolumeResponse.Builder resp = InfoVolumeResponse.newBuilder();
String volume = request.getVolumeName();
OmVolumeArgs ret = impl.getVolumeInfo(volume);
resp.setVolumeInfo(ret.getProtobuf());
return resp.build();
}
@DisallowedUntilLayoutVersion(MULTITENANCY_SCHEMA)
private TenantGetUserInfoResponse tenantGetUserInfo(
TenantGetUserInfoRequest request) throws IOException {
final TenantGetUserInfoResponse.Builder resp =
TenantGetUserInfoResponse.newBuilder();
final String userPrincipal = request.getUserPrincipal();
TenantUserInfoValue ret = impl.tenantGetUserInfo(userPrincipal);
// Note impl.tenantGetUserInfo() throws if errs
if (ret != null) {
resp.addAllAccessIdInfo(ret.getAccessIdInfoList());
}
return resp.build();
}
@DisallowedUntilLayoutVersion(MULTITENANCY_SCHEMA)
private TenantListUserResponse tenantListUsers(
TenantListUserRequest request) throws IOException {
TenantListUserResponse.Builder builder =
TenantListUserResponse.newBuilder();
TenantUserList usersInTenant =
impl.listUsersInTenant(request.getTenantId(), request.getPrefix());
// Note impl.listUsersInTenant() throws if errs
if (usersInTenant != null) {
builder.addAllUserAccessIdInfo(usersInTenant.getUserAccessIds());
}
return builder.build();
}
@DisallowedUntilLayoutVersion(MULTITENANCY_SCHEMA)
private ListTenantResponse listTenant(
ListTenantRequest request) throws IOException {
final ListTenantResponse.Builder resp = ListTenantResponse.newBuilder();
TenantStateList ret = impl.listTenant();
resp.addAllTenantState(ret.getTenantStateList());
return resp.build();
}
private ListVolumeResponse listVolumes(ListVolumeRequest request)
throws IOException {
ListVolumeResponse.Builder resp = ListVolumeResponse.newBuilder();
List<OmVolumeArgs> result = Lists.newArrayList();
if (request.getScope()
== ListVolumeRequest.Scope.VOLUMES_BY_USER) {
result = impl.listVolumeByUser(request.getUserName(),
request.getPrefix(), request.getPrevKey(), request.getMaxKeys());
} else if (request.getScope()
== ListVolumeRequest.Scope.VOLUMES_BY_CLUSTER) {
result =
impl.listAllVolumes(request.getPrefix(), request.getPrevKey(),
request.getMaxKeys());
}
result.forEach(item -> resp.addVolumeInfo(item.getProtobuf()));
return resp.build();
}
private InfoBucketResponse infoBucket(InfoBucketRequest request)
throws IOException {
InfoBucketResponse.Builder resp =
InfoBucketResponse.newBuilder();
OmBucketInfo omBucketInfo = impl.getBucketInfo(
request.getVolumeName(), request.getBucketName());
resp.setBucketInfo(omBucketInfo.getProtobuf());
return resp.build();
}
private LookupKeyResponse lookupKey(LookupKeyRequest request,
int clientVersion) throws IOException {
LookupKeyResponse.Builder resp =
LookupKeyResponse.newBuilder();
KeyArgs keyArgs = request.getKeyArgs();
OmKeyArgs omKeyArgs = new OmKeyArgs.Builder()
.setVolumeName(keyArgs.getVolumeName())
.setBucketName(keyArgs.getBucketName())
.setKeyName(keyArgs.getKeyName())
.setLatestVersionLocation(keyArgs.getLatestVersionLocation())
.setSortDatanodesInPipeline(keyArgs.getSortDatanodes())
.setHeadOp(keyArgs.getHeadOp())
.build();
OmKeyInfo keyInfo = impl.lookupKey(omKeyArgs);
resp.setKeyInfo(keyInfo.getProtobuf(keyArgs.getHeadOp(), clientVersion));
return resp.build();
}
private GetKeyInfoResponse getKeyInfo(GetKeyInfoRequest request,
int clientVersion) throws IOException {
KeyArgs keyArgs = request.getKeyArgs();
OmKeyArgs omKeyArgs = new OmKeyArgs.Builder()
.setVolumeName(keyArgs.getVolumeName())
.setBucketName(keyArgs.getBucketName())
.setKeyName(keyArgs.getKeyName())
.setLatestVersionLocation(keyArgs.getLatestVersionLocation())
.setSortDatanodesInPipeline(keyArgs.getSortDatanodes())
.setHeadOp(keyArgs.getHeadOp())
.setForceUpdateContainerCacheFromSCM(
keyArgs.getForceUpdateContainerCacheFromSCM())
.build();
KeyInfoWithVolumeContext keyInfo = impl.getKeyInfo(omKeyArgs,
request.getAssumeS3Context());
return keyInfo.toProtobuf(clientVersion);
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.LookupKey
)
public static OMResponse disallowLookupKeyResponseWithECReplicationConfig(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException {
if (!resp.hasLookupKeyResponse()) {
return resp;
}
if (resp.getLookupKeyResponse().getKeyInfo().hasEcReplicationConfig()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("Key is a key with Erasure Coded replication, which"
+ " the client can not understand.\n"
+ "Please upgrade the client before trying to read the key: "
+ req.getLookupKeyRequest().getKeyArgs().getVolumeName()
+ "/" + req.getLookupKeyRequest().getKeyArgs().getBucketName()
+ "/" + req.getLookupKeyRequest().getKeyArgs().getKeyName()
+ ".")
.clearLookupKeyResponse()
.build();
}
return resp;
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.LookupKey
)
public static OMResponse disallowLookupKeyWithBucketLayout(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException, IOException {
if (!resp.hasLookupKeyResponse()) {
return resp;
}
KeyInfo keyInfo = resp.getLookupKeyResponse().getKeyInfo();
// If the key is present inside a bucket using a non LEGACY bucket layout,
// then the client needs to be upgraded before proceeding.
if (keyInfo.hasVolumeName() && keyInfo.hasBucketName() &&
!ctx.getBucketLayout(keyInfo.getVolumeName(), keyInfo.getBucketName())
.equals(BucketLayout.LEGACY)) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("Key is present inside a bucket with bucket layout " +
"features, which the client can not understand. Please upgrade" +
" the client to a compatible version before trying to read the" +
" key info for "
+ req.getLookupKeyRequest().getKeyArgs().getVolumeName()
+ "/" + req.getLookupKeyRequest().getKeyArgs().getBucketName()
+ "/" + req.getLookupKeyRequest().getKeyArgs().getKeyName()
+ ".")
.clearLookupKeyResponse()
.build();
}
return resp;
}
private ListBucketsResponse listBuckets(ListBucketsRequest request)
throws IOException {
ListBucketsResponse.Builder resp =
ListBucketsResponse.newBuilder();
List<OmBucketInfo> buckets = impl.listBuckets(
request.getVolumeName(),
request.getStartKey(),
request.getPrefix(),
request.getCount());
for (OmBucketInfo bucket : buckets) {
resp.addBucketInfo(bucket.getProtobuf());
}
return resp.build();
}
private ListKeysResponse listKeys(ListKeysRequest request, int clientVersion)
throws IOException {
ListKeysResponse.Builder resp =
ListKeysResponse.newBuilder();
List<OmKeyInfo> keys = impl.listKeys(
request.getVolumeName(),
request.getBucketName(),
request.getStartKey(),
request.getPrefix(),
request.getCount());
for (OmKeyInfo key : keys) {
resp.addKeyInfo(key.getProtobuf(true, clientVersion));
}
return resp.build();
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.ListKeys
)
public static OMResponse disallowListKeysResponseWithECReplicationConfig(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException {
if (!resp.hasListKeysResponse()) {
return resp;
}
List<KeyInfo> keys = resp.getListKeysResponse().getKeyInfoList();
for (KeyInfo key : keys) {
if (key.hasEcReplicationConfig()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("The list of keys contains keys with Erasure Coded"
+ " replication set, hence the client is not able to"
+ " represent all the keys returned. Please upgrade the"
+ " client to get the list of keys.")
.clearListKeysResponse()
.build();
}
}
return resp;
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.ListKeys
)
public static OMResponse disallowListKeysWithBucketLayout(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException, IOException {
if (!resp.hasListKeysResponse()) {
return resp;
}
// Put volume and bucket pairs into a set to avoid duplicates.
HashSet<Pair<String, String>> volumeBucketSet = new HashSet<>();
List<KeyInfo> keys = resp.getListKeysResponse().getKeyInfoList();
for (KeyInfo key : keys) {
if (key.hasVolumeName() && key.hasBucketName()) {
volumeBucketSet.add(
new ImmutablePair<>(key.getVolumeName(), key.getBucketName()));
}
}
for (Pair<String, String> volumeBucket : volumeBucketSet) {
// If any of the buckets have a non legacy layout, then the client is
// not compatible with the response.
if (!ctx.getBucketLayout(volumeBucket.getLeft(), volumeBucket.getRight())
.isLegacy()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("The list of keys contains keys present inside bucket" +
" with bucket layout features, hence the client is not able " +
"to understand all the keys returned. Please upgrade the"
+ " client to get the list of keys.")
.clearListKeysResponse()
.build();
break;
}
}
return resp;
}
private ListTrashResponse listTrash(ListTrashRequest request,
int clientVersion) throws IOException {
ListTrashResponse.Builder resp =
ListTrashResponse.newBuilder();
List<RepeatedOmKeyInfo> deletedKeys = impl.listTrash(
request.getVolumeName(),
request.getBucketName(),
request.getStartKeyName(),
request.getKeyPrefix(),
request.getMaxKeys());
for (RepeatedOmKeyInfo key: deletedKeys) {
resp.addDeletedKeys(key.getProto(false, clientVersion));
}
return resp.build();
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.ListTrash
)
public static OMResponse disallowListTrashWithECReplicationConfig(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException {
if (!resp.hasListTrashResponse()) {
return resp;
}
List<RepeatedKeyInfo> repeatedKeys =
resp.getListTrashResponse().getDeletedKeysList();
for (RepeatedKeyInfo repeatedKey : repeatedKeys) {
for (KeyInfo key : repeatedKey.getKeyInfoList()) {
if (key.hasEcReplicationConfig()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("The list of keys contains keys with Erasure Coded"
+ " replication set, hence the client is not able to"
+ " represent all the keys returned. Please upgrade the"
+ " client to get the list of keys.")
.clearListTrashResponse()
.build();
}
}
}
return resp;
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.ListTrash
)
public static OMResponse disallowListTrashWithBucketLayout(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException, IOException {
if (!resp.hasListTrashResponse()) {
return resp;
}
// Add the volume and bucket pairs to a set to avoid duplicates.
List<RepeatedKeyInfo> repeatedKeys =
resp.getListTrashResponse().getDeletedKeysList();
HashSet<Pair<String, String>> volumeBucketSet = new HashSet<>();
for (RepeatedKeyInfo repeatedKey : repeatedKeys) {
for (KeyInfo key : repeatedKey.getKeyInfoList()) {
if (key.hasVolumeName() && key.hasBucketName()) {
volumeBucketSet.add(
new ImmutablePair<>(key.getVolumeName(), key.getBucketName()));
}
}
}
// If any of the keys is present inside a bucket using a non LEGACY bucket
// layout, then the client needs to be upgraded before proceeding.
for (Pair<String, String> volumeBucket : volumeBucketSet) {
if (!ctx.getBucketLayout(volumeBucket.getLeft(), volumeBucket.getRight())
.isLegacy()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("The list of keys contains keys present in buckets " +
" using bucket layout features, hence the client is not able to"
+ " understand all the keys returned. Please upgrade the"
+ " client to get the list of keys.")
.clearListTrashResponse()
.build();
break;
}
}
return resp;
}
private ServiceListResponse getServiceList(ServiceListRequest request)
throws IOException {
ServiceListResponse.Builder resp = ServiceListResponse.newBuilder();
ServiceInfoEx serviceInfoEx = impl.getServiceInfo();
List<OzoneManagerProtocolProtos.ServiceInfo> serviceInfoProtos =
new ArrayList<>();
List<ServiceInfo> serviceInfos = serviceInfoEx.getServiceInfoList();
for (ServiceInfo info : serviceInfos) {
serviceInfoProtos.add(info.getProtobuf());
}
resp.addAllServiceInfo(serviceInfoProtos);
if (serviceInfoEx.getCaCertificate() != null) {
resp.setCaCertificate(serviceInfoEx.getCaCertificate());
}
for (String ca : serviceInfoEx.getCaCertPemList()) {
resp.addCaCerts(ca);
}
return resp.build();
}
private MultipartUploadListPartsResponse listParts(
MultipartUploadListPartsRequest multipartUploadListPartsRequest)
throws IOException {
MultipartUploadListPartsResponse.Builder response =
MultipartUploadListPartsResponse.newBuilder();
OmMultipartUploadListParts omMultipartUploadListParts =
impl.listParts(multipartUploadListPartsRequest.getVolume(),
multipartUploadListPartsRequest.getBucket(),
multipartUploadListPartsRequest.getKey(),
multipartUploadListPartsRequest.getUploadID(),
multipartUploadListPartsRequest.getPartNumbermarker(),
multipartUploadListPartsRequest.getMaxParts());
List<OmPartInfo> omPartInfoList =
omMultipartUploadListParts.getPartInfoList();
List<PartInfo> partInfoList =
new ArrayList<>();
omPartInfoList.forEach(partInfo -> partInfoList.add(partInfo.getProto()));
HddsProtos.ReplicationType repType = omMultipartUploadListParts
.getReplicationConfig()
.getReplicationType();
response.setType(repType);
if (repType == HddsProtos.ReplicationType.EC) {
response.setEcReplicationConfig(
((ECReplicationConfig)omMultipartUploadListParts
.getReplicationConfig()).toProto());
} else {
response.setFactor(ReplicationConfig.getLegacyFactor(
omMultipartUploadListParts.getReplicationConfig()));
}
response.setNextPartNumberMarker(
omMultipartUploadListParts.getNextPartNumberMarker());
response.setIsTruncated(omMultipartUploadListParts.isTruncated());
return response.addAllPartsList(partInfoList).build();
}
private ListMultipartUploadsResponse listMultipartUploads(
ListMultipartUploadsRequest request)
throws IOException {
OmMultipartUploadList omMultipartUploadList =
impl.listMultipartUploads(request.getVolume(), request.getBucket(),
request.getPrefix());
List<MultipartUploadInfo> info = omMultipartUploadList
.getUploads()
.stream()
.map(upload -> {
MultipartUploadInfo.Builder bldr = MultipartUploadInfo.newBuilder()
.setVolumeName(upload.getVolumeName())
.setBucketName(upload.getBucketName())
.setKeyName(upload.getKeyName())
.setUploadId(upload.getUploadId());
HddsProtos.ReplicationType repType = upload.getReplicationConfig()
.getReplicationType();
bldr.setType(repType);
if (repType == HddsProtos.ReplicationType.EC) {
bldr.setEcReplicationConfig(
((ECReplicationConfig)upload.getReplicationConfig())
.toProto());
} else {
bldr.setFactor(ReplicationConfig.getLegacyFactor(
upload.getReplicationConfig()));
}
bldr.setCreationTime(upload.getCreationTime().toEpochMilli());
return bldr.build();
})
.collect(Collectors.toList());
ListMultipartUploadsResponse response =
ListMultipartUploadsResponse.newBuilder()
.addAllUploadsList(info)
.build();
return response;
}
private GetFileStatusResponse getOzoneFileStatus(
GetFileStatusRequest request, int clientVersion) throws IOException {
KeyArgs keyArgs = request.getKeyArgs();
OmKeyArgs omKeyArgs = new OmKeyArgs.Builder()
.setVolumeName(keyArgs.getVolumeName())
.setBucketName(keyArgs.getBucketName())
.setKeyName(keyArgs.getKeyName())
.build();
GetFileStatusResponse.Builder rb = GetFileStatusResponse.newBuilder();
rb.setStatus(impl.getFileStatus(omKeyArgs).getProtobuf(clientVersion));
return rb.build();
}
private RangerBGSyncResponse triggerRangerBGSync(
RangerBGSyncRequest rangerBGSyncRequest) throws IOException {
boolean res = impl.triggerRangerBGSync(rangerBGSyncRequest.getNoWait());
return RangerBGSyncResponse.newBuilder().setRunSuccess(res).build();
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.GetFileStatus
)
public static OMResponse disallowGetFileStatusWithECReplicationConfig(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException {
if (!resp.hasGetFileStatusResponse()) {
return resp;
}
if (resp.getGetFileStatusResponse().getStatus().getKeyInfo()
.hasEcReplicationConfig()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("Key is a key with Erasure Coded replication, which"
+ " the client can not understand."
+ " Please upgrade the client before trying to read the key info"
+ " for "
+ req.getGetFileStatusRequest().getKeyArgs().getVolumeName()
+ "/" + req.getGetFileStatusRequest().getKeyArgs().getBucketName()
+ "/" + req.getGetFileStatusRequest().getKeyArgs().getKeyName()
+ ".")
.clearGetFileStatusResponse()
.build();
}
return resp;
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.GetFileStatus
)
public static OMResponse disallowGetFileStatusWithBucketLayout(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException, IOException {
if (!resp.hasGetFileStatusResponse()) {
return resp;
}
// If the File is present inside a bucket with non LEGACY layout,
// then the client should be upgraded before proceeding.
KeyInfo keyInfo = resp.getGetFileStatusResponse().getStatus().getKeyInfo();
if (keyInfo.hasVolumeName() && keyInfo.hasBucketName() &&
!ctx.getBucketLayout(keyInfo.getVolumeName(), keyInfo.getBucketName())
.isLegacy()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("Key is present in a bucket using bucket layout features"
+ " which the client can not understand."
+ " Please upgrade the client before trying to read the key info"
+ " for "
+ req.getGetFileStatusRequest().getKeyArgs().getVolumeName()
+ "/" + req.getGetFileStatusRequest().getKeyArgs().getBucketName()
+ "/" + req.getGetFileStatusRequest().getKeyArgs().getKeyName()
+ ".")
.clearGetFileStatusResponse()
.build();
}
return resp;
}
private LookupFileResponse lookupFile(LookupFileRequest request,
int clientVersion) throws IOException {
KeyArgs keyArgs = request.getKeyArgs();
OmKeyArgs omKeyArgs = new OmKeyArgs.Builder()
.setVolumeName(keyArgs.getVolumeName())
.setBucketName(keyArgs.getBucketName())
.setKeyName(keyArgs.getKeyName())
.setSortDatanodesInPipeline(keyArgs.getSortDatanodes())
.setLatestVersionLocation(keyArgs.getLatestVersionLocation())
.build();
return LookupFileResponse.newBuilder()
.setKeyInfo(impl.lookupFile(omKeyArgs).getProtobuf(clientVersion))
.build();
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.LookupFile
)
public static OMResponse disallowLookupFileWithECReplicationConfig(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException {
if (!resp.hasLookupFileResponse()) {
return resp;
}
if (resp.getLookupFileResponse().getKeyInfo().hasEcReplicationConfig()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("Key is a key with Erasure Coded replication, which the"
+ " client can not understand."
+ " Please upgrade the client before trying to read the key info"
+ " for "
+ req.getLookupFileRequest().getKeyArgs().getVolumeName()
+ "/" + req.getLookupFileRequest().getKeyArgs().getBucketName()
+ "/" + req.getLookupFileRequest().getKeyArgs().getKeyName()
+ ".")
.clearLookupFileResponse()
.build();
}
return resp;
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.LookupFile
)
public static OMResponse disallowLookupFileWithBucketLayout(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException, IOException {
if (!resp.hasLookupFileResponse()) {
return resp;
}
KeyInfo keyInfo = resp.getLookupFileResponse().getKeyInfo();
if (keyInfo.hasVolumeName() && keyInfo.hasBucketName() &&
!ctx.getBucketLayout(keyInfo.getVolumeName(), keyInfo.getBucketName())
.equals(BucketLayout.LEGACY)) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("File is present inside a bucket with bucket layout " +
"features, which the client can not understand. Please upgrade" +
" the client to a compatible version before trying to read the" +
" key info for "
+ req.getLookupFileRequest().getKeyArgs().getVolumeName()
+ "/" + req.getLookupFileRequest().getKeyArgs().getBucketName()
+ "/" + req.getLookupFileRequest().getKeyArgs().getKeyName()
+ ".")
.clearLookupFileResponse()
.build();
}
return resp;
}
private ListStatusResponse listStatus(
ListStatusRequest request, int clientVersion) throws IOException {
KeyArgs keyArgs = request.getKeyArgs();
OmKeyArgs omKeyArgs = new OmKeyArgs.Builder()
.setVolumeName(keyArgs.getVolumeName())
.setBucketName(keyArgs.getBucketName())
.setKeyName(keyArgs.getKeyName())
.setLatestVersionLocation(keyArgs.getLatestVersionLocation())
.setHeadOp(keyArgs.getHeadOp())
.build();
boolean allowPartialPrefixes =
request.hasAllowPartialPrefix() && request.getAllowPartialPrefix();
List<OzoneFileStatus> statuses =
impl.listStatus(omKeyArgs, request.getRecursive(),
request.getStartKey(), request.getNumEntries(),
allowPartialPrefixes);
ListStatusResponse.Builder
listStatusResponseBuilder =
ListStatusResponse.newBuilder();
for (OzoneFileStatus status : statuses) {
listStatusResponseBuilder.addStatuses(status.getProtobuf(clientVersion));
}
return listStatusResponseBuilder.build();
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.ListStatus
)
public static OMResponse disallowListStatusResponseWithECReplicationConfig(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException {
if (!resp.hasListStatusResponse()) {
return resp;
}
List<OzoneFileStatusProto> statuses =
resp.getListStatusResponse().getStatusesList();
for (OzoneFileStatusProto status : statuses) {
if (status.getKeyInfo().hasEcReplicationConfig()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("The list of keys contains keys with Erasure Coded"
+ " replication set, hence the client is not able to"
+ " represent all the keys returned."
+ " Please upgrade the client to get the list of keys.")
.clearListStatusResponse()
.build();
}
}
return resp;
}
@RequestFeatureValidator(
conditions = ValidationCondition.OLDER_CLIENT_REQUESTS,
processingPhase = RequestProcessingPhase.POST_PROCESS,
requestType = Type.ListStatus
)
public static OMResponse disallowListStatusResponseWithBucketLayout(
OMRequest req, OMResponse resp, ValidationContext ctx)
throws ServiceException, IOException {
if (!resp.hasListStatusResponse()) {
return resp;
}
// Add the volume and bucket pairs to a set to avoid duplicate entries.
List<OzoneFileStatusProto> statuses =
resp.getListStatusResponse().getStatusesList();
HashSet<Pair<String, String>> volumeBucketSet = new HashSet<>();
for (OzoneFileStatusProto status : statuses) {
KeyInfo keyInfo = status.getKeyInfo();
if (keyInfo.hasVolumeName() && keyInfo.hasBucketName()) {
volumeBucketSet.add(
new ImmutablePair<>(keyInfo.getVolumeName(),
keyInfo.getBucketName()));
}
}
// If any of the keys are present in a bucket with a non LEGACY bucket
// layout, then the client needs to be upgraded before proceeding.
for (Pair<String, String> volumeBucket : volumeBucketSet) {
if (!ctx.getBucketLayout(volumeBucket.getLeft(),
volumeBucket.getRight()).isLegacy()) {
resp = resp.toBuilder()
.setStatus(Status.NOT_SUPPORTED_OPERATION)
.setMessage("The list of keys is present in a bucket using bucket"
+ " layout features, hence the client is not able to"
+ " represent all the keys returned."
+ " Please upgrade the client to get the list of keys.")
.clearListStatusResponse()
.build();
break;
}
}
return resp;
}
private FinalizeUpgradeProgressResponse reportUpgradeProgress(
FinalizeUpgradeProgressRequest request) throws IOException {
String upgradeClientId = request.getUpgradeClientId();
boolean takeover = request.getTakeover();
boolean readonly = request.getReadonly();
StatusAndMessages progress =
impl.queryUpgradeFinalizationProgress(upgradeClientId, takeover,
readonly);
UpgradeFinalizationStatus.Status protoStatus =
UpgradeFinalizationStatus.Status.valueOf(progress.status().name());
UpgradeFinalizationStatus response =
UpgradeFinalizationStatus.newBuilder()
.setStatus(protoStatus)
.addAllMessages(progress.msgs())
.build();
return FinalizeUpgradeProgressResponse.newBuilder()
.setStatus(response)
.build();
}
private PrepareStatusResponse getPrepareStatus() {
OzoneManagerPrepareState.State prepareState =
impl.getPrepareState().getState();
return PrepareStatusResponse.newBuilder()
.setStatus(prepareState.getStatus())
.setCurrentTxnIndex(prepareState.getIndex()).build();
}
private GetS3VolumeContextResponse getS3VolumeContext()
throws IOException {
return impl.getS3VolumeContext().getProtobuf();
}
private SnapshotDiffResponse snapshotDiff(
SnapshotDiffRequest snapshotDiffRequest) throws IOException {
return SnapshotDiffResponse.newBuilder().setSnapshotDiffReport(
impl.snapshotDiff(snapshotDiffRequest.getVolumeName(),
snapshotDiffRequest.getBucketName(),
snapshotDiffRequest.getFromSnapshot(),
snapshotDiffRequest.getToSnapshot()).toProtobuf()).build();
}
public OzoneManager getOzoneManager() {
return impl;
}
private EchoRPCResponse echoRPC(EchoRPCRequest req) {
EchoRPCResponse.Builder builder =
EchoRPCResponse.newBuilder();
byte[] payloadBytes = new byte[0];
int payloadRespSize = Math.min(
req.getPayloadSizeResp()
* RPC_PAYLOAD_MULTIPLICATION_FACTOR, MAX_SIZE_KB);
if (payloadRespSize > 0) {
payloadBytes = RandomUtils.nextBytes(payloadRespSize);
}
builder.setPayload(ByteString.copyFrom(payloadBytes));
return builder.build();
}
private OzoneManagerProtocolProtos.ListSnapshotResponse getSnapshots(
OzoneManagerProtocolProtos.ListSnapshotRequest request)
throws IOException {
List<SnapshotInfo> snapshotInfos = impl.listSnapshot(
request.getVolumeName(), request.getBucketName(), request.getPrefix(),
request.getPrevSnapshot(), request.getMaxListResult());
List<OzoneManagerProtocolProtos.SnapshotInfo> snapshotInfoList =
snapshotInfos.stream().map(SnapshotInfo::getProtobuf)
.collect(Collectors.toList());
return OzoneManagerProtocolProtos.ListSnapshotResponse.newBuilder()
.addAllSnapshotInfo(snapshotInfoList).build();
}
}