HDDS-1730. Implement File CreateDirectory Request to use Cache and Do… (#1026)
This commit is contained in:
parent
d203045c30
commit
1e727cf2a1
|
@ -100,6 +100,17 @@ public interface OMMetadataManager {
|
||||||
|
|
||||||
String getOzoneKey(String volume, String bucket, String key);
|
String getOzoneKey(String volume, String bucket, String key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a volume, bucket and a key, return the corresponding DB directory
|
||||||
|
* key.
|
||||||
|
*
|
||||||
|
* @param volume - volume name
|
||||||
|
* @param bucket - bucket name
|
||||||
|
* @param key - key name
|
||||||
|
* @return DB directory key as String.
|
||||||
|
*/
|
||||||
|
String getOzoneDirKey(String volume, String bucket, String key);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the DB key name of a open key in OM metadata store. Should be
|
* Returns the DB key name of a open key in OM metadata store. Should be
|
||||||
|
|
|
@ -46,6 +46,7 @@ import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
|
import org.apache.hadoop.ozone.om.helpers.OmMultipartKeyInfo;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
|
import org.apache.hadoop.ozone.om.helpers.OmPrefixInfo;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils;
|
||||||
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
|
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
|
||||||
import org.apache.hadoop.ozone.om.lock.OzoneManagerLock;
|
import org.apache.hadoop.ozone.om.lock.OzoneManagerLock;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeList;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeList;
|
||||||
|
@ -381,6 +382,12 @@ public class OmMetadataManagerImpl implements OMMetadataManager {
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getOzoneDirKey(String volume, String bucket, String key) {
|
||||||
|
key = OzoneFSUtils.addTrailingSlashIfNeeded(key);
|
||||||
|
return getOzoneKey(volume, bucket, key);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOpenKey(String volume, String bucket,
|
public String getOpenKey(String volume, String bucket,
|
||||||
String key, long id) {
|
String key, long id) {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.apache.hadoop.ozone.om.request.bucket.OMBucketCreateRequest;
|
||||||
import org.apache.hadoop.ozone.om.request.bucket.OMBucketDeleteRequest;
|
import org.apache.hadoop.ozone.om.request.bucket.OMBucketDeleteRequest;
|
||||||
import org.apache.hadoop.ozone.om.request.bucket.OMBucketSetPropertyRequest;
|
import org.apache.hadoop.ozone.om.request.bucket.OMBucketSetPropertyRequest;
|
||||||
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.request.file.OMDirectoryCreateRequest;
|
||||||
import org.apache.hadoop.ozone.om.request.key.OMAllocateBlockRequest;
|
import org.apache.hadoop.ozone.om.request.key.OMAllocateBlockRequest;
|
||||||
import org.apache.hadoop.ozone.om.request.key.OMKeyCommitRequest;
|
import org.apache.hadoop.ozone.om.request.key.OMKeyCommitRequest;
|
||||||
import org.apache.hadoop.ozone.om.request.key.OMKeyCreateRequest;
|
import org.apache.hadoop.ozone.om.request.key.OMKeyCreateRequest;
|
||||||
|
@ -90,6 +91,8 @@ public final class OzoneManagerRatisUtils {
|
||||||
return new OMKeyDeleteRequest(omRequest);
|
return new OMKeyDeleteRequest(omRequest);
|
||||||
case RenameKey:
|
case RenameKey:
|
||||||
return new OMKeyRenameRequest(omRequest);
|
return new OMKeyRenameRequest(omRequest);
|
||||||
|
case CreateDirectory:
|
||||||
|
return new OMDirectoryCreateRequest(omRequest);
|
||||||
default:
|
default:
|
||||||
// TODO: will update once all request types are implemented.
|
// TODO: will update once all request types are implemented.
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,282 @@
|
||||||
|
/**
|
||||||
|
* 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.om.request.file;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.apache.hadoop.fs.FileEncryptionInfo;
|
||||||
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.OMAction;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetrics;
|
||||||
|
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||||
|
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmKeyLocationInfoGroup;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.request.key.OMKeyRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.file.OMDirectoryCreateResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateDirectoryRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateDirectoryResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.KeyArgs;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.OzoneObj;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
|
||||||
|
|
||||||
|
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.BUCKET_NOT_FOUND;
|
||||||
|
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.FILE_ALREADY_EXISTS;
|
||||||
|
import static org.apache.hadoop.ozone.om.lock.OzoneManagerLock.Resource.BUCKET_LOCK;
|
||||||
|
/**
|
||||||
|
* Handle create directory request.
|
||||||
|
*/
|
||||||
|
public class OMDirectoryCreateRequest extends OMClientRequest
|
||||||
|
implements OMKeyRequest {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMDirectoryCreateRequest.class);
|
||||||
|
|
||||||
|
public OMDirectoryCreateRequest(OMRequest omRequest) {
|
||||||
|
super(omRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMRequest preExecute(OzoneManager ozoneManager) {
|
||||||
|
CreateDirectoryRequest createDirectoryRequest =
|
||||||
|
getOmRequest().getCreateDirectoryRequest();
|
||||||
|
Preconditions.checkNotNull(createDirectoryRequest);
|
||||||
|
|
||||||
|
KeyArgs.Builder newKeyArgs = createDirectoryRequest.getKeyArgs()
|
||||||
|
.toBuilder().setModificationTime(Time.now());
|
||||||
|
|
||||||
|
CreateDirectoryRequest.Builder newCreateDirectoryRequest =
|
||||||
|
createDirectoryRequest.toBuilder().setKeyArgs(newKeyArgs);
|
||||||
|
|
||||||
|
return getOmRequest().toBuilder().setCreateDirectoryRequest(
|
||||||
|
newCreateDirectoryRequest).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
|
long transactionLogIndex) {
|
||||||
|
|
||||||
|
KeyArgs keyArgs = getOmRequest().getCreateDirectoryRequest().getKeyArgs();
|
||||||
|
|
||||||
|
String volumeName = keyArgs.getVolumeName();
|
||||||
|
String bucketName = keyArgs.getBucketName();
|
||||||
|
String keyName = keyArgs.getKeyName();
|
||||||
|
|
||||||
|
OMResponse.Builder omResponse =
|
||||||
|
OzoneManagerProtocolProtos.OMResponse.newBuilder().setCmdType(
|
||||||
|
OzoneManagerProtocolProtos.Type.CreateDirectory).setStatus(
|
||||||
|
OzoneManagerProtocolProtos.Status.OK);
|
||||||
|
|
||||||
|
OMMetrics omMetrics = ozoneManager.getMetrics();
|
||||||
|
omMetrics.incNumCreateDirectory();
|
||||||
|
|
||||||
|
AuditLogger auditLogger = ozoneManager.getAuditLogger();
|
||||||
|
OzoneManagerProtocolProtos.UserInfo userInfo = getOmRequest().getUserInfo();
|
||||||
|
|
||||||
|
Map<String, String> auditMap = buildKeyArgsAuditMap(keyArgs);
|
||||||
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
boolean acquiredLock = false;
|
||||||
|
IOException exception = null;
|
||||||
|
OmKeyInfo dirKeyInfo = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// check Acl
|
||||||
|
if (ozoneManager.getAclsEnabled()) {
|
||||||
|
checkAcls(ozoneManager, OzoneObj.ResourceType.BUCKET,
|
||||||
|
OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.WRITE,
|
||||||
|
volumeName, bucketName, keyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is the root of the filesystem.
|
||||||
|
if (keyName.length() == 0) {
|
||||||
|
return new OMDirectoryCreateResponse(null,
|
||||||
|
omResponse.setCreateDirectoryResponse(
|
||||||
|
CreateDirectoryResponse.newBuilder()).build());
|
||||||
|
}
|
||||||
|
// acquire lock
|
||||||
|
acquiredLock = omMetadataManager.getLock().acquireLock(BUCKET_LOCK,
|
||||||
|
volumeName, bucketName);
|
||||||
|
|
||||||
|
// TODO: Not checking volume exist here, once we have full cache we can
|
||||||
|
// add volume exist check also.
|
||||||
|
|
||||||
|
OmBucketInfo omBucketInfo = omMetadataManager.getBucketTable().get(
|
||||||
|
omMetadataManager.getBucketKey(volumeName, bucketName));
|
||||||
|
|
||||||
|
if (omBucketInfo == null) {
|
||||||
|
throw new OMException("Bucket not found " + bucketName,
|
||||||
|
BUCKET_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Need to check if any files exist in the given path, if they exist we
|
||||||
|
// cannot create a directory with the given key.
|
||||||
|
OMDirectoryResult omDirectoryResult = verifyFilesInPath(omMetadataManager,
|
||||||
|
volumeName, bucketName, omMetadataManager.getOzoneDirKey(volumeName,
|
||||||
|
bucketName, keyName), Paths.get(keyName));
|
||||||
|
|
||||||
|
if (omDirectoryResult == OMDirectoryResult.FILE_ALREADY_EXISTS) {
|
||||||
|
throw new OMException("Unable to create directory: " +keyName
|
||||||
|
+ " in volume/bucket: " + volumeName + "/" + bucketName,
|
||||||
|
FILE_ALREADY_EXISTS);
|
||||||
|
} else if (omDirectoryResult == OMDirectoryResult.SUB_DIRECTORY_EXISTS ||
|
||||||
|
omDirectoryResult == OMDirectoryResult.NONE) {
|
||||||
|
dirKeyInfo = createDirectoryKeyInfo(ozoneManager, omBucketInfo,
|
||||||
|
volumeName, bucketName, keyName, keyArgs);
|
||||||
|
|
||||||
|
omMetadataManager.getKeyTable().addCacheEntry(
|
||||||
|
new CacheKey<>(omMetadataManager.getOzoneKey(volumeName, bucketName,
|
||||||
|
dirKeyInfo.getKeyName())),
|
||||||
|
new CacheValue<>(Optional.of(dirKeyInfo), transactionLogIndex));
|
||||||
|
}
|
||||||
|
// if directory already exists do nothing or do we need to throw
|
||||||
|
// exception? Current KeyManagerImpl code does just return, following
|
||||||
|
// similar approach.
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
exception = ex;
|
||||||
|
} finally {
|
||||||
|
if (acquiredLock) {
|
||||||
|
omMetadataManager.getLock().releaseLock(BUCKET_LOCK, volumeName,
|
||||||
|
bucketName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.CREATE_DIRECTORY,
|
||||||
|
auditMap, exception, userInfo));
|
||||||
|
|
||||||
|
if (exception == null) {
|
||||||
|
LOG.debug("Directory is successfully created for Key: {} in " +
|
||||||
|
"volume/bucket:{}/{}", keyName, volumeName, bucketName);
|
||||||
|
omResponse.setCreateDirectoryResponse(
|
||||||
|
CreateDirectoryResponse.newBuilder());
|
||||||
|
return new OMDirectoryCreateResponse(dirKeyInfo,
|
||||||
|
omResponse.build());
|
||||||
|
} else {
|
||||||
|
LOG.error("CreateDirectory failed for Key: {} in volume/bucket:{}/{}",
|
||||||
|
keyName, volumeName, bucketName, exception);
|
||||||
|
omMetrics.incNumCreateDirectoryFails();
|
||||||
|
return new OMDirectoryCreateResponse(null,
|
||||||
|
createErrorOMResponse(omResponse, exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify any files exist in the given path in the specified volume/bucket.
|
||||||
|
* @param omMetadataManager
|
||||||
|
* @param volumeName
|
||||||
|
* @param bucketName
|
||||||
|
* @param keyPath
|
||||||
|
* @return true - if file exist in the given path, else false.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private OMDirectoryResult verifyFilesInPath(
|
||||||
|
OMMetadataManager omMetadataManager, String volumeName, String bucketName,
|
||||||
|
String directoryName, Path keyPath) throws IOException {
|
||||||
|
|
||||||
|
while (keyPath != null) {
|
||||||
|
String keyName = keyPath.toString();
|
||||||
|
|
||||||
|
String dbKeyName = omMetadataManager.getOzoneKey(volumeName,
|
||||||
|
bucketName, keyName);
|
||||||
|
String dbDirKeyName = omMetadataManager.getOzoneDirKey(volumeName,
|
||||||
|
bucketName, keyName);
|
||||||
|
|
||||||
|
if (omMetadataManager.getKeyTable().get(dbKeyName) != null) {
|
||||||
|
// Found a file in the given path.
|
||||||
|
return OMDirectoryResult.FILE_ALREADY_EXISTS;
|
||||||
|
} else if (omMetadataManager.getKeyTable().get(dbDirKeyName) != null) {
|
||||||
|
if (dbDirKeyName.equals(directoryName)) {
|
||||||
|
return OMDirectoryResult.DIRECTORY_ALREADY_EXISTS;
|
||||||
|
} else {
|
||||||
|
return OMDirectoryResult.SUB_DIRECTORY_EXISTS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keyPath = keyPath.getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Found no files/ directories in the given path.
|
||||||
|
return OMDirectoryResult.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private OmKeyInfo createDirectoryKeyInfo(OzoneManager ozoneManager,
|
||||||
|
OmBucketInfo omBucketInfo, String volumeName, String bucketName,
|
||||||
|
String keyName, KeyArgs keyArgs)
|
||||||
|
throws IOException {
|
||||||
|
FileEncryptionInfo encryptionInfo = getFileEncryptionInfo(ozoneManager,
|
||||||
|
omBucketInfo);
|
||||||
|
String dirName = OzoneFSUtils.addTrailingSlashIfNeeded(keyName);
|
||||||
|
|
||||||
|
return new OmKeyInfo.Builder()
|
||||||
|
.setVolumeName(volumeName)
|
||||||
|
.setBucketName(bucketName)
|
||||||
|
.setKeyName(dirName)
|
||||||
|
.setOmKeyLocationInfos(Collections.singletonList(
|
||||||
|
new OmKeyLocationInfoGroup(0, new ArrayList<>())))
|
||||||
|
.setCreationTime(keyArgs.getModificationTime())
|
||||||
|
.setModificationTime(keyArgs.getModificationTime())
|
||||||
|
.setDataSize(0)
|
||||||
|
.setReplicationType(HddsProtos.ReplicationType.RATIS)
|
||||||
|
.setReplicationFactor(HddsProtos.ReplicationFactor.ONE)
|
||||||
|
.setFileEncryptionInfo(encryptionInfo)
|
||||||
|
.setAcls(keyArgs.getAclsList())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return codes used by verifyFilesInPath method.
|
||||||
|
*/
|
||||||
|
enum OMDirectoryResult {
|
||||||
|
DIRECTORY_ALREADY_EXISTS,
|
||||||
|
FILE_ALREADY_EXISTS,
|
||||||
|
SUB_DIRECTORY_EXISTS,
|
||||||
|
NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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 contains classes related to file requests.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.request.file;
|
|
@ -0,0 +1,67 @@
|
||||||
|
/**
|
||||||
|
* 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.om.response.file;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.utils.db.BatchOperation;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response for create directory request.
|
||||||
|
*/
|
||||||
|
public class OMDirectoryCreateResponse extends OMClientResponse {
|
||||||
|
|
||||||
|
public static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMDirectoryCreateResponse.class);
|
||||||
|
private OmKeyInfo dirKeyInfo;
|
||||||
|
|
||||||
|
public OMDirectoryCreateResponse(@Nullable OmKeyInfo dirKeyInfo,
|
||||||
|
OMResponse omResponse) {
|
||||||
|
super(omResponse);
|
||||||
|
this.dirKeyInfo = dirKeyInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
|
if (dirKeyInfo != null) {
|
||||||
|
String dirKey =
|
||||||
|
omMetadataManager.getOzoneKey(dirKeyInfo.getVolumeName(),
|
||||||
|
dirKeyInfo.getBucketName(), dirKeyInfo.getKeyName());
|
||||||
|
omMetadataManager.getKeyTable().putWithBatch(batchOperation, dirKey,
|
||||||
|
dirKeyInfo);
|
||||||
|
} else {
|
||||||
|
// When directory already exists, we don't add it to cache. And it is
|
||||||
|
// not an error, in this case dirKeyInfo will be null.
|
||||||
|
LOG.debug("Response Status is OK, dirKeyInfo is null in " +
|
||||||
|
"OMDirectoryCreateResponse");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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 contains classes related to file responses.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.response.file;
|
|
@ -108,6 +108,7 @@ public class OzoneManagerHARequestHandlerImpl
|
||||||
case CommitKey:
|
case CommitKey:
|
||||||
case DeleteKey:
|
case DeleteKey:
|
||||||
case RenameKey:
|
case RenameKey:
|
||||||
|
case CreateDirectory:
|
||||||
//TODO: We don't need to pass transactionID, this will be removed when
|
//TODO: We don't need to pass transactionID, this will be removed when
|
||||||
// complete write requests is changed to new model. And also we can
|
// complete write requests is changed to new model. And also we can
|
||||||
// return OMClientResponse, then adding to doubleBuffer can be taken
|
// return OMClientResponse, then adding to doubleBuffer can be taken
|
||||||
|
|
|
@ -85,7 +85,6 @@ public class OzoneManagerProtocolServerSideTranslatorPB implements
|
||||||
if (OmUtils.isReadOnly(request)) {
|
if (OmUtils.isReadOnly(request)) {
|
||||||
return submitReadRequestToOM(request);
|
return submitReadRequestToOM(request);
|
||||||
} else {
|
} else {
|
||||||
// PreExecute if needed.
|
|
||||||
if (omRatisServer.isLeader()) {
|
if (omRatisServer.isLeader()) {
|
||||||
try {
|
try {
|
||||||
OMClientRequest omClientRequest =
|
OMClientRequest omClientRequest =
|
||||||
|
@ -93,7 +92,7 @@ public class OzoneManagerProtocolServerSideTranslatorPB implements
|
||||||
if (omClientRequest != null) {
|
if (omClientRequest != null) {
|
||||||
request = omClientRequest.preExecute(ozoneManager);
|
request = omClientRequest.preExecute(ozoneManager);
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch(IOException ex) {
|
||||||
// As some of the preExecute returns error. So handle here.
|
// As some of the preExecute returns error. So handle here.
|
||||||
return createErrorResponse(request, ex);
|
return createErrorResponse(request, ex);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,327 @@
|
||||||
|
/**
|
||||||
|
* 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.om.request.file;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.commons.lang.RandomStringUtils;
|
||||||
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditMessage;
|
||||||
|
import org.apache.hadoop.ozone.om.OMConfigKeys;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetrics;
|
||||||
|
import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
|
||||||
|
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||||
|
import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateDirectoryRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.KeyArgs;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test OM directory create request.
|
||||||
|
*/
|
||||||
|
public class TestOMDirectoryCreateRequest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder folder = new TemporaryFolder();
|
||||||
|
|
||||||
|
private OzoneManager ozoneManager;
|
||||||
|
private OMMetrics omMetrics;
|
||||||
|
private OMMetadataManager omMetadataManager;
|
||||||
|
private AuditLogger auditLogger;
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
ozoneManager = Mockito.mock(OzoneManager.class);
|
||||||
|
omMetrics = OMMetrics.create();
|
||||||
|
OzoneConfiguration ozoneConfiguration = new OzoneConfiguration();
|
||||||
|
ozoneConfiguration.set(OMConfigKeys.OZONE_OM_DB_DIRS,
|
||||||
|
folder.newFolder().getAbsolutePath());
|
||||||
|
omMetadataManager = new OmMetadataManagerImpl(ozoneConfiguration);
|
||||||
|
when(ozoneManager.getMetrics()).thenReturn(omMetrics);
|
||||||
|
when(ozoneManager.getMetadataManager()).thenReturn(omMetadataManager);
|
||||||
|
auditLogger = Mockito.mock(AuditLogger.class);
|
||||||
|
when(ozoneManager.getAuditLogger()).thenReturn(auditLogger);
|
||||||
|
Mockito.doNothing().when(auditLogger).logWrite(any(AuditMessage.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void stop() {
|
||||||
|
omMetrics.unRegister();
|
||||||
|
Mockito.framework().clearInlineMocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPreExecute() throws Exception {
|
||||||
|
|
||||||
|
String volumeName = "vol1";
|
||||||
|
String bucketName = "bucket1";
|
||||||
|
String keyName = "a/b/c";
|
||||||
|
|
||||||
|
TestOMRequestUtils.addVolumeAndBucketToDB(volumeName, bucketName,
|
||||||
|
omMetadataManager);
|
||||||
|
|
||||||
|
OMRequest omRequest = createDirectoryRequest(volumeName, bucketName,
|
||||||
|
keyName);
|
||||||
|
OMDirectoryCreateRequest omDirectoryCreateRequest =
|
||||||
|
new OMDirectoryCreateRequest(omRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedOmRequest =
|
||||||
|
omDirectoryCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
// As in preExecute, we modify original request.
|
||||||
|
Assert.assertNotEquals(omRequest, modifiedOmRequest);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCache() throws Exception {
|
||||||
|
String volumeName = "vol1";
|
||||||
|
String bucketName = "bucket1";
|
||||||
|
String keyName = RandomStringUtils.randomAlphabetic(5);
|
||||||
|
for (int i =0; i< 3; i++) {
|
||||||
|
keyName += "/" + RandomStringUtils.randomAlphabetic(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add volume and bucket entries to DB.
|
||||||
|
TestOMRequestUtils.addVolumeAndBucketToDB(volumeName, bucketName,
|
||||||
|
omMetadataManager);
|
||||||
|
|
||||||
|
OMRequest omRequest = createDirectoryRequest(volumeName, bucketName,
|
||||||
|
keyName);
|
||||||
|
OMDirectoryCreateRequest omDirectoryCreateRequest =
|
||||||
|
new OMDirectoryCreateRequest(omRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedOmRequest =
|
||||||
|
omDirectoryCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L);
|
||||||
|
|
||||||
|
Assert.assertTrue(omClientResponse.getOMResponse().getStatus()
|
||||||
|
== OzoneManagerProtocolProtos.Status.OK);
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName)) != null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithBucketNotFound() throws Exception {
|
||||||
|
String volumeName = "vol1";
|
||||||
|
String bucketName = "bucket1";
|
||||||
|
String keyName = RandomStringUtils.randomAlphabetic(5);
|
||||||
|
for (int i =0; i< 3; i++) {
|
||||||
|
keyName += "/" + RandomStringUtils.randomAlphabetic(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
OMRequest omRequest = createDirectoryRequest(volumeName, bucketName,
|
||||||
|
keyName);
|
||||||
|
OMDirectoryCreateRequest omDirectoryCreateRequest =
|
||||||
|
new OMDirectoryCreateRequest(omRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedOmRequest =
|
||||||
|
omDirectoryCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L);
|
||||||
|
|
||||||
|
Assert.assertTrue(omClientResponse.getOMResponse().getStatus()
|
||||||
|
== OzoneManagerProtocolProtos.Status.BUCKET_NOT_FOUND);
|
||||||
|
|
||||||
|
// Key should not exist in DB
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName)) == null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithSubDirectoryInPath()
|
||||||
|
throws Exception {
|
||||||
|
String volumeName = "vol1";
|
||||||
|
String bucketName = "bucket1";
|
||||||
|
String keyName = RandomStringUtils.randomAlphabetic(5);
|
||||||
|
for (int i =0; i< 3; i++) {
|
||||||
|
keyName += "/" + RandomStringUtils.randomAlphabetic(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add volume and bucket entries to DB.
|
||||||
|
TestOMRequestUtils.addVolumeAndBucketToDB(volumeName, bucketName,
|
||||||
|
omMetadataManager);
|
||||||
|
|
||||||
|
TestOMRequestUtils.addKeyToTable(false, volumeName, bucketName,
|
||||||
|
keyName.substring(0, 12), 1L, HddsProtos.ReplicationType.RATIS,
|
||||||
|
HddsProtos.ReplicationFactor.ONE, omMetadataManager);
|
||||||
|
OMRequest omRequest = createDirectoryRequest(volumeName, bucketName,
|
||||||
|
keyName);
|
||||||
|
OMDirectoryCreateRequest omDirectoryCreateRequest =
|
||||||
|
new OMDirectoryCreateRequest(omRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedOmRequest =
|
||||||
|
omDirectoryCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L);
|
||||||
|
|
||||||
|
Assert.assertTrue(omClientResponse.getOMResponse().getStatus()
|
||||||
|
== OzoneManagerProtocolProtos.Status.OK);
|
||||||
|
|
||||||
|
// Key should exist in DB and cache.
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName)) != null);
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().getCacheValue(
|
||||||
|
new CacheKey<>(omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName))) != null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithDirectoryAlreadyExists()
|
||||||
|
throws Exception {
|
||||||
|
String volumeName = "vol1";
|
||||||
|
String bucketName = "bucket1";
|
||||||
|
String keyName = RandomStringUtils.randomAlphabetic(5);
|
||||||
|
for (int i =0; i< 3; i++) {
|
||||||
|
keyName += "/" + RandomStringUtils.randomAlphabetic(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add volume and bucket entries to DB.
|
||||||
|
TestOMRequestUtils.addVolumeAndBucketToDB(volumeName, bucketName,
|
||||||
|
omMetadataManager);
|
||||||
|
|
||||||
|
TestOMRequestUtils.addKeyToTable(false, volumeName, bucketName,
|
||||||
|
OzoneFSUtils.addTrailingSlashIfNeeded(keyName), 1L,
|
||||||
|
HddsProtos.ReplicationType.RATIS, HddsProtos.ReplicationFactor.ONE,
|
||||||
|
omMetadataManager);
|
||||||
|
OMRequest omRequest = createDirectoryRequest(volumeName, bucketName,
|
||||||
|
keyName);
|
||||||
|
OMDirectoryCreateRequest omDirectoryCreateRequest =
|
||||||
|
new OMDirectoryCreateRequest(omRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedOmRequest =
|
||||||
|
omDirectoryCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L);
|
||||||
|
|
||||||
|
Assert.assertTrue(omClientResponse.getOMResponse().getStatus()
|
||||||
|
== OzoneManagerProtocolProtos.Status.OK);
|
||||||
|
|
||||||
|
// Key should exist in DB
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName)) != null);
|
||||||
|
|
||||||
|
// As it already exists, it should not be in cache.
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().getCacheValue(
|
||||||
|
new CacheKey<>(omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName))) == null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithFilesInPath() throws Exception {
|
||||||
|
String volumeName = "vol1";
|
||||||
|
String bucketName = "bucket1";
|
||||||
|
String keyName = RandomStringUtils.randomAlphabetic(5);
|
||||||
|
for (int i =0; i< 3; i++) {
|
||||||
|
keyName += "/" + RandomStringUtils.randomAlphabetic(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add volume and bucket entries to DB.
|
||||||
|
TestOMRequestUtils.addVolumeAndBucketToDB(volumeName, bucketName,
|
||||||
|
omMetadataManager);
|
||||||
|
// Add a key with first two levels.
|
||||||
|
TestOMRequestUtils.addKeyToTable(false, volumeName, bucketName,
|
||||||
|
keyName.substring(0, 11), 1L, HddsProtos.ReplicationType.RATIS,
|
||||||
|
HddsProtos.ReplicationFactor.ONE, omMetadataManager);
|
||||||
|
OMRequest omRequest = createDirectoryRequest(volumeName, bucketName,
|
||||||
|
keyName);
|
||||||
|
OMDirectoryCreateRequest omDirectoryCreateRequest =
|
||||||
|
new OMDirectoryCreateRequest(omRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedOmRequest =
|
||||||
|
omDirectoryCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
omDirectoryCreateRequest = new OMDirectoryCreateRequest(modifiedOmRequest);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omDirectoryCreateRequest.validateAndUpdateCache(ozoneManager, 100L);
|
||||||
|
|
||||||
|
Assert.assertTrue(omClientResponse.getOMResponse().getStatus()
|
||||||
|
== OzoneManagerProtocolProtos.Status.FILE_ALREADY_EXISTS);
|
||||||
|
|
||||||
|
// Key should not exist in DB
|
||||||
|
Assert.assertTrue(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(
|
||||||
|
volumeName, bucketName, keyName)) == null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create OMRequest which encapsulates CreateDirectory request.
|
||||||
|
* @param volumeName
|
||||||
|
* @param bucketName
|
||||||
|
* @param keyName
|
||||||
|
* @return OMRequest
|
||||||
|
*/
|
||||||
|
private OMRequest createDirectoryRequest(String volumeName, String bucketName,
|
||||||
|
String keyName) {
|
||||||
|
return OMRequest.newBuilder().setCreateDirectoryRequest(
|
||||||
|
CreateDirectoryRequest.newBuilder().setKeyArgs(
|
||||||
|
KeyArgs.newBuilder().setVolumeName(volumeName)
|
||||||
|
.setBucketName(bucketName).setKeyName(keyName)))
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory)
|
||||||
|
.setClientId(UUID.randomUUID().toString()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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 contains test classes for file requests.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.request.file;
|
|
@ -0,0 +1,123 @@
|
||||||
|
/**
|
||||||
|
* 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.om.response.file;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
import org.apache.hadoop.hdds.protocol.proto.HddsProtos;
|
||||||
|
import org.apache.hadoop.ozone.om.OMConfigKeys;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OzoneFSUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
|
import org.apache.hadoop.utils.db.BatchOperation;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TemporaryFolder;
|
||||||
|
import org.slf4j.event.Level;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests OMDirectoryCreateResponse.
|
||||||
|
*/
|
||||||
|
public class TestOMDirectoryCreateResponse {
|
||||||
|
@Rule
|
||||||
|
public TemporaryFolder folder = new TemporaryFolder();
|
||||||
|
|
||||||
|
private OMMetadataManager omMetadataManager;
|
||||||
|
private BatchOperation batchOperation;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() throws Exception {
|
||||||
|
OzoneConfiguration ozoneConfiguration = new OzoneConfiguration();
|
||||||
|
ozoneConfiguration.set(OMConfigKeys.OZONE_OM_DB_DIRS,
|
||||||
|
folder.newFolder().getAbsolutePath());
|
||||||
|
omMetadataManager = new OmMetadataManagerImpl(ozoneConfiguration);
|
||||||
|
batchOperation = omMetadataManager.getStore().initBatchOperation();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToDBBatch() throws Exception {
|
||||||
|
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String keyName = UUID.randomUUID().toString();
|
||||||
|
String bucketName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
OmKeyInfo omKeyInfo = TestOMRequestUtils.createOmKeyInfo(volumeName,
|
||||||
|
bucketName, OzoneFSUtils.addTrailingSlashIfNeeded(keyName),
|
||||||
|
HddsProtos.ReplicationType.RATIS, HddsProtos.ReplicationFactor.ONE);
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder().setCreateDirectoryResponse(
|
||||||
|
OzoneManagerProtocolProtos.CreateDirectoryResponse.getDefaultInstance())
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMDirectoryCreateResponse omDirectoryCreateResponse =
|
||||||
|
new OMDirectoryCreateResponse(omKeyInfo, omResponse);
|
||||||
|
|
||||||
|
omDirectoryCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
|
||||||
|
// Do manual commit and see whether addToBatch is successful or not.
|
||||||
|
omMetadataManager.getStore().commitBatchOperation(batchOperation);
|
||||||
|
|
||||||
|
Assert.assertNotNull(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(volumeName, bucketName, keyName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToDBBatchWithNullOmkeyInfo() throws Exception {
|
||||||
|
|
||||||
|
GenericTestUtils.setLogLevel(OMDirectoryCreateResponse.LOG, Level.DEBUG);
|
||||||
|
GenericTestUtils.LogCapturer logCapturer = GenericTestUtils.LogCapturer
|
||||||
|
.captureLogs(OMDirectoryCreateResponse.LOG);
|
||||||
|
|
||||||
|
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String keyName = UUID.randomUUID().toString();
|
||||||
|
String bucketName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder().setCreateDirectoryResponse(
|
||||||
|
OzoneManagerProtocolProtos.CreateDirectoryResponse.getDefaultInstance())
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateDirectory)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMDirectoryCreateResponse omDirectoryCreateResponse =
|
||||||
|
new OMDirectoryCreateResponse(null, omResponse);
|
||||||
|
|
||||||
|
omDirectoryCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
|
||||||
|
// Do manual commit and see whether addToBatch is successful or not.
|
||||||
|
omMetadataManager.getStore().commitBatchOperation(batchOperation);
|
||||||
|
|
||||||
|
Assert.assertNull(omMetadataManager.getKeyTable().get(
|
||||||
|
omMetadataManager.getOzoneDirKey(volumeName, bucketName, keyName)));
|
||||||
|
|
||||||
|
Assert.assertTrue(logCapturer.getOutput().contains("Response Status is " +
|
||||||
|
"OK, dirKeyInfo is null"));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* 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 contains test classes for file responses.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.response.file;
|
Loading…
Reference in New Issue