HDDS-1620. Implement Volume Write Requests to use Cache and DoubleBuffer. (#884)
This commit is contained in:
parent
a43f4440f7
commit
88c53d516c
|
@ -20,6 +20,8 @@
|
||||||
package org.apache.hadoop.utils.db;
|
package org.apache.hadoop.utils.db;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.lang3.NotImplementedException;
|
import org.apache.commons.lang3.NotImplementedException;
|
||||||
import org.apache.hadoop.classification.InterfaceStability;
|
import org.apache.hadoop.classification.InterfaceStability;
|
||||||
|
@ -131,6 +133,14 @@ default void cleanupCache(long epoch) {
|
||||||
throw new NotImplementedException("cleanupCache is not implemented");
|
throw new NotImplementedException("cleanupCache is not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return cache iterator maintained for this table.
|
||||||
|
*/
|
||||||
|
default Iterator<Map.Entry<CacheKey<KEY>, CacheValue<VALUE>>>
|
||||||
|
cacheIterator() {
|
||||||
|
throw new NotImplementedException("cacheIterator is not implemented");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to represent the key and value pair of a db entry.
|
* Class used to represent the key and value pair of a db entry.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
package org.apache.hadoop.utils.db;
|
package org.apache.hadoop.utils.db;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.hadoop.utils.db.cache.CacheKey;
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
@ -82,7 +84,7 @@ public boolean isEmpty() throws IOException {
|
||||||
@Override
|
@Override
|
||||||
public boolean isExist(KEY key) throws IOException {
|
public boolean isExist(KEY key) throws IOException {
|
||||||
CacheValue<VALUE> cacheValue= cache.get(new CacheKey<>(key));
|
CacheValue<VALUE> cacheValue= cache.get(new CacheKey<>(key));
|
||||||
return (cacheValue != null && cacheValue.getValue() != null) ||
|
return (cacheValue != null && cacheValue.getCacheValue() != null) ||
|
||||||
rawTable.isExist(codecRegistry.asRawData(key));
|
rawTable.isExist(codecRegistry.asRawData(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ public VALUE get(KEY key) throws IOException {
|
||||||
return getFromTable(key);
|
return getFromTable(key);
|
||||||
} else {
|
} else {
|
||||||
// We have a value in cache, return the value.
|
// We have a value in cache, return the value.
|
||||||
return cacheValue.getValue();
|
return cacheValue.getCacheValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,6 +158,9 @@ public void addCacheEntry(CacheKey<KEY> cacheKey,
|
||||||
cache.put(cacheKey, cacheValue);
|
cache.put(cacheKey, cacheValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Iterator<Map.Entry<CacheKey<KEY>, CacheValue<VALUE>>> cacheIterator() {
|
||||||
|
return cache.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cleanupCache(long epoch) {
|
public void cleanupCache(long epoch) {
|
||||||
|
|
|
@ -33,7 +33,7 @@ public CacheKey(KEY key) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
|
|
||||||
public KEY getKey() {
|
public KEY getCacheKey() {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public CacheValue(Optional<VALUE> value, long epoch) {
|
||||||
this.epoch = epoch;
|
this.epoch = epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VALUE getValue() {
|
public VALUE getCacheValue() {
|
||||||
return value.orNull();
|
return value.orNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
package org.apache.hadoop.utils.db.cache;
|
package org.apache.hadoop.utils.db.cache;
|
||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
@ -77,6 +78,11 @@ public int size() {
|
||||||
return cache.size();
|
return cache.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Map.Entry<CACHEKEY, CACHEVALUE>> iterator() {
|
||||||
|
return cache.entrySet().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
private void evictCache(long epoch) {
|
private void evictCache(long epoch) {
|
||||||
EpochEntry<CACHEKEY> currentEntry = null;
|
EpochEntry<CACHEKEY> currentEntry = null;
|
||||||
for (Iterator<EpochEntry<CACHEKEY>> iterator = epochEntries.iterator();
|
for (Iterator<EpochEntry<CACHEKEY>> iterator = epochEntries.iterator();
|
||||||
|
|
|
@ -22,6 +22,9 @@
|
||||||
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
import org.apache.hadoop.classification.InterfaceAudience.Private;
|
||||||
import org.apache.hadoop.classification.InterfaceStability.Evolving;
|
import org.apache.hadoop.classification.InterfaceStability.Evolving;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache used for RocksDB tables.
|
* Cache used for RocksDB tables.
|
||||||
* @param <CACHEKEY>
|
* @param <CACHEKEY>
|
||||||
|
@ -60,4 +63,10 @@ public interface TableCache<CACHEKEY extends CacheKey,
|
||||||
* @return size
|
* @return size
|
||||||
*/
|
*/
|
||||||
int size();
|
int size();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an iterator for the cache.
|
||||||
|
* @return iterator of the underlying cache for the table.
|
||||||
|
*/
|
||||||
|
Iterator<Map.Entry<CACHEKEY, CACHEVALUE>> iterator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ public void testPartialTableCache() {
|
||||||
|
|
||||||
for (int i=0; i < 10; i++) {
|
for (int i=0; i < 10; i++) {
|
||||||
Assert.assertEquals(Integer.toString(i),
|
Assert.assertEquals(Integer.toString(i),
|
||||||
tableCache.get(new CacheKey<>(Integer.toString(i))).getValue());
|
tableCache.get(new CacheKey<>(Integer.toString(i))).getCacheValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
// On a full table cache if some one calls cleanup it is a no-op.
|
// On a full table cache if some one calls cleanup it is a no-op.
|
||||||
|
@ -59,7 +59,7 @@ public void testPartialTableCache() {
|
||||||
|
|
||||||
for (int i=5; i < 10; i++) {
|
for (int i=5; i < 10; i++) {
|
||||||
Assert.assertEquals(Integer.toString(i),
|
Assert.assertEquals(Integer.toString(i),
|
||||||
tableCache.get(new CacheKey<>(Integer.toString(i))).getValue());
|
tableCache.get(new CacheKey<>(Integer.toString(i))).getCacheValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ public void testPartialTableCacheParallel() throws Exception {
|
||||||
// Check we have first 10 entries in cache.
|
// Check we have first 10 entries in cache.
|
||||||
for (int i=1; i <= 10; i++) {
|
for (int i=1; i <= 10; i++) {
|
||||||
Assert.assertEquals(Integer.toString(i),
|
Assert.assertEquals(Integer.toString(i),
|
||||||
tableCache.get(new CacheKey<>(Integer.toString(i))).getValue());
|
tableCache.get(new CacheKey<>(Integer.toString(i))).getCacheValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
int deleted = 5;
|
int deleted = 5;
|
||||||
|
@ -115,7 +115,7 @@ public void testPartialTableCacheParallel() throws Exception {
|
||||||
// Check if we have remaining entries.
|
// Check if we have remaining entries.
|
||||||
for (int i=6; i <= totalCount; i++) {
|
for (int i=6; i <= totalCount; i++) {
|
||||||
Assert.assertEquals(Integer.toString(i),
|
Assert.assertEquals(Integer.toString(i),
|
||||||
tableCache.get(new CacheKey<>(Integer.toString(i))).getValue());
|
tableCache.get(new CacheKey<>(Integer.toString(i))).getCacheValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
tableCache.cleanup(10);
|
tableCache.cleanup(10);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.apache.hadoop.ozone.OzoneAcl;
|
import org.apache.hadoop.ozone.OzoneAcl;
|
||||||
import org.apache.hadoop.ozone.OzoneConsts;
|
import org.apache.hadoop.ozone.OzoneConsts;
|
||||||
|
@ -154,6 +155,28 @@ public Map<String, String> toAuditMap() {
|
||||||
return auditMap;
|
return auditMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (o == null || getClass() != o.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
OmVolumeArgs that = (OmVolumeArgs) o;
|
||||||
|
return creationTime == that.creationTime &&
|
||||||
|
quotaInBytes == that.quotaInBytes &&
|
||||||
|
Objects.equals(adminName, that.adminName) &&
|
||||||
|
Objects.equals(ownerName, that.ownerName) &&
|
||||||
|
Objects.equals(volume, that.volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(adminName, ownerName, volume, creationTime,
|
||||||
|
quotaInBytes);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builder for OmVolumeArgs.
|
* Builder for OmVolumeArgs.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -287,7 +287,7 @@ message VolumeInfo {
|
||||||
optional uint64 quotaInBytes = 4;
|
optional uint64 quotaInBytes = 4;
|
||||||
repeated hadoop.hdds.KeyValue metadata = 5;
|
repeated hadoop.hdds.KeyValue metadata = 5;
|
||||||
repeated OzoneAclInfo volumeAcls = 6;
|
repeated OzoneAclInfo volumeAcls = 6;
|
||||||
required uint64 creationTime = 7;
|
optional uint64 creationTime = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,7 +53,7 @@ https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>2.2.0</version>
|
<version>2.28.2</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.hadoop.hdds.client.BlockID;
|
import org.apache.hadoop.hdds.client.BlockID;
|
||||||
|
@ -62,6 +64,9 @@
|
||||||
import static org.apache.hadoop.ozone.OzoneConsts.OM_DB_NAME;
|
import static org.apache.hadoop.ozone.OzoneConsts.OM_DB_NAME;
|
||||||
import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
|
import static org.apache.hadoop.ozone.OzoneConsts.OM_KEY_PREFIX;
|
||||||
|
|
||||||
|
import org.apache.hadoop.utils.db.TypedTable;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -451,10 +456,27 @@ private boolean startsWith(byte[] firstArray, byte[] secondArray) {
|
||||||
public boolean isVolumeEmpty(String volume) throws IOException {
|
public boolean isVolumeEmpty(String volume) throws IOException {
|
||||||
String volumePrefix = getVolumeKey(volume + OM_KEY_PREFIX);
|
String volumePrefix = getVolumeKey(volume + OM_KEY_PREFIX);
|
||||||
|
|
||||||
|
// First check in bucket table cache.
|
||||||
|
Iterator<Map.Entry<CacheKey<String>, CacheValue<OmBucketInfo>>> iterator =
|
||||||
|
((TypedTable< String, OmBucketInfo>) bucketTable).cacheIterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry< CacheKey< String >, CacheValue< OmBucketInfo > > entry =
|
||||||
|
iterator.next();
|
||||||
|
String key = entry.getKey().getCacheKey();
|
||||||
|
OmBucketInfo omBucketInfo = entry.getValue().getCacheValue();
|
||||||
|
// Making sure that entry is not for delete bucket request.
|
||||||
|
if (key.startsWith(volumePrefix) && omBucketInfo != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try (TableIterator<String, ? extends KeyValue<String, OmBucketInfo>>
|
try (TableIterator<String, ? extends KeyValue<String, OmBucketInfo>>
|
||||||
bucketIter = bucketTable.iterator()) {
|
bucketIter = bucketTable.iterator()) {
|
||||||
KeyValue<String, OmBucketInfo> kv = bucketIter.seek(volumePrefix);
|
KeyValue<String, OmBucketInfo> kv = bucketIter.seek(volumePrefix);
|
||||||
if (kv != null && kv.getKey().startsWith(volumePrefix)) {
|
// During iteration from DB, check in mean time if this bucket is not
|
||||||
|
// marked for delete.
|
||||||
|
if (kv != null && kv.getKey().startsWith(volumePrefix) &&
|
||||||
|
bucketTable.get(kv.getKey()) != null) {
|
||||||
return false; // we found at least one bucket with this volume prefix.
|
return false; // we found at least one bucket with this volume prefix.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -473,6 +495,8 @@ public boolean isVolumeEmpty(String volume) throws IOException {
|
||||||
public boolean isBucketEmpty(String volume, String bucket)
|
public boolean isBucketEmpty(String volume, String bucket)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
String keyPrefix = getBucketKey(volume, bucket);
|
String keyPrefix = getBucketKey(volume, bucket);
|
||||||
|
//TODO: When Key ops are converted in to HA model, use cache also to
|
||||||
|
// determine bucket is empty or not.
|
||||||
try (TableIterator<String, ? extends KeyValue<String, OmKeyInfo>> keyIter =
|
try (TableIterator<String, ? extends KeyValue<String, OmKeyInfo>> keyIter =
|
||||||
keyTable.iterator()) {
|
keyTable.iterator()) {
|
||||||
KeyValue<String, OmKeyInfo> kv = keyIter.seek(keyPrefix);
|
KeyValue<String, OmKeyInfo> kv = keyIter.seek(keyPrefix);
|
||||||
|
|
|
@ -198,6 +198,8 @@
|
||||||
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RATIS_PORT_DEFAULT;
|
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RATIS_PORT_DEFAULT;
|
||||||
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_SERVICE_IDS_KEY;
|
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_SERVICE_IDS_KEY;
|
||||||
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RATIS_PORT_KEY;
|
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RATIS_PORT_KEY;
|
||||||
|
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_USER_MAX_VOLUME;
|
||||||
|
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_USER_MAX_VOLUME_DEFAULT;
|
||||||
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_AUTH_METHOD;
|
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_AUTH_METHOD;
|
||||||
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_REQUEST;
|
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.INVALID_REQUEST;
|
||||||
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_ERROR_OTHER;
|
import static org.apache.hadoop.ozone.om.exceptions.OMException.ResultCodes.TOKEN_ERROR_OTHER;
|
||||||
|
@ -276,12 +278,20 @@ public final class OzoneManager extends ServiceRuntimeInfoImpl
|
||||||
private static String keyProviderUriKeyName =
|
private static String keyProviderUriKeyName =
|
||||||
CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_PROVIDER_PATH;
|
CommonConfigurationKeysPublic.HADOOP_SECURITY_KEY_PROVIDER_PATH;
|
||||||
|
|
||||||
|
// Adding parameters needed for VolumeRequests here, so that during request
|
||||||
|
// execution, we can get from ozoneManager.
|
||||||
|
private long maxUserVolumeCount;
|
||||||
|
|
||||||
|
|
||||||
private OzoneManager(OzoneConfiguration conf) throws IOException,
|
private OzoneManager(OzoneConfiguration conf) throws IOException,
|
||||||
AuthenticationException {
|
AuthenticationException {
|
||||||
super(OzoneVersionInfo.OZONE_VERSION_INFO);
|
super(OzoneVersionInfo.OZONE_VERSION_INFO);
|
||||||
Preconditions.checkNotNull(conf);
|
Preconditions.checkNotNull(conf);
|
||||||
configuration = conf;
|
configuration = conf;
|
||||||
|
this.maxUserVolumeCount = conf.getInt(OZONE_OM_USER_MAX_VOLUME,
|
||||||
|
OZONE_OM_USER_MAX_VOLUME_DEFAULT);
|
||||||
|
Preconditions.checkArgument(this.maxUserVolumeCount > 0,
|
||||||
|
OZONE_OM_USER_MAX_VOLUME + " value should be greater than zero");
|
||||||
omStorage = new OMStorage(conf);
|
omStorage = new OMStorage(conf);
|
||||||
omId = omStorage.getOmId();
|
omId = omStorage.getOmId();
|
||||||
if (omStorage.getState() != StorageState.INITIALIZED) {
|
if (omStorage.getState() != StorageState.INITIALIZED) {
|
||||||
|
@ -3201,7 +3211,11 @@ public OMFailoverProxyProvider getOMFailoverProxyProvider() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OMMetrics getOmMetrics() {
|
/**
|
||||||
return metrics;
|
* Return maximum volumes count per user.
|
||||||
|
* @return maxUserVolumeCount
|
||||||
|
*/
|
||||||
|
public long getMaxUserVolumeCount() {
|
||||||
|
return maxUserVolumeCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,11 +142,13 @@ private void flushTransactions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanupCache(long lastRatisTransactionIndex) {
|
private void cleanupCache(long lastRatisTransactionIndex) {
|
||||||
// As now only bucket transactions are handled only called cleanupCache
|
// As now only volume and bucket transactions are handled only called
|
||||||
// on bucketTable.
|
// cleanupCache on bucketTable.
|
||||||
// TODO: After supporting all write operations we need to call
|
// TODO: After supporting all write operations we need to call
|
||||||
// cleanupCache on the tables only when buffer has entries for that table.
|
// cleanupCache on the tables only when buffer has entries for that table.
|
||||||
omMetadataManager.getBucketTable().cleanupCache(lastRatisTransactionIndex);
|
omMetadataManager.getBucketTable().cleanupCache(lastRatisTransactionIndex);
|
||||||
|
omMetadataManager.getVolumeTable().cleanupCache(lastRatisTransactionIndex);
|
||||||
|
omMetadataManager.getUserTable().cleanupCache(lastRatisTransactionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
import org.apache.hadoop.ozone.container.common.transport.server.ratis
|
import org.apache.hadoop.ozone.container.common.transport.server.ratis
|
||||||
.ContainerStateMachine;
|
.ContainerStateMachine;
|
||||||
import org.apache.hadoop.ozone.om.OzoneManager;
|
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||||
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
|
||||||
import org.apache.hadoop.ozone.om.helpers.OMRatisHelper;
|
import org.apache.hadoop.ozone.om.helpers.OMRatisHelper;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
@ -189,14 +188,7 @@ public void notifyNotLeader(Collection<TransactionContext> pendingEntries)
|
||||||
private TransactionContext handleStartTransactionRequests(
|
private TransactionContext handleStartTransactionRequests(
|
||||||
RaftClientRequest raftClientRequest, OMRequest omRequest) {
|
RaftClientRequest raftClientRequest, OMRequest omRequest) {
|
||||||
|
|
||||||
OMRequest newOmRequest = null;
|
|
||||||
try {
|
|
||||||
switch (omRequest.getCmdType()) {
|
switch (omRequest.getCmdType()) {
|
||||||
case CreateVolume:
|
|
||||||
case SetVolumeProperty:
|
|
||||||
case DeleteVolume:
|
|
||||||
newOmRequest = handler.handleStartTransaction(omRequest);
|
|
||||||
break;
|
|
||||||
case AllocateBlock:
|
case AllocateBlock:
|
||||||
return handleAllocateBlock(raftClientRequest, omRequest);
|
return handleAllocateBlock(raftClientRequest, omRequest);
|
||||||
case CreateKey:
|
case CreateKey:
|
||||||
|
@ -211,31 +203,6 @@ private TransactionContext handleStartTransactionRequests(
|
||||||
.setLogData(raftClientRequest.getMessage().getContent())
|
.setLogData(raftClientRequest.getMessage().getContent())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
|
||||||
TransactionContext transactionContext = TransactionContext.newBuilder()
|
|
||||||
.setClientRequest(raftClientRequest)
|
|
||||||
.setStateMachine(this)
|
|
||||||
.setServerRole(RaftProtos.RaftPeerRole.LEADER)
|
|
||||||
.build();
|
|
||||||
if (ex instanceof OMException) {
|
|
||||||
IOException ioException =
|
|
||||||
new IOException(ex.getMessage() + STATUS_CODE +
|
|
||||||
((OMException) ex).getResult());
|
|
||||||
transactionContext.setException(ioException);
|
|
||||||
} else {
|
|
||||||
transactionContext.setException(ex);
|
|
||||||
}
|
|
||||||
LOG.error("Exception in startTransaction for cmdType " +
|
|
||||||
omRequest.getCmdType(), ex);
|
|
||||||
return transactionContext;
|
|
||||||
}
|
|
||||||
TransactionContext transactionContext = TransactionContext.newBuilder()
|
|
||||||
.setClientRequest(raftClientRequest)
|
|
||||||
.setStateMachine(this)
|
|
||||||
.setServerRole(RaftProtos.RaftPeerRole.LEADER)
|
|
||||||
.setLogData(OMRatisHelper.convertRequestToByteString(newOmRequest))
|
|
||||||
.build();
|
|
||||||
return transactionContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransactionContext handleInitiateMultipartUpload(
|
private TransactionContext handleInitiateMultipartUpload(
|
||||||
|
|
|
@ -17,11 +17,16 @@
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.om.ratis.utils;
|
package org.apache.hadoop.ozone.om.ratis.utils;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||||
import org.apache.hadoop.ozone.om.request.bucket.OMBucketCreateRequest;
|
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.volume.OMVolumeCreateRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.request.volume.OMVolumeDeleteRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.request.volume.OMVolumeSetOwnerRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.request.volume.OMVolumeSetQuotaRequest;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
.OMRequest;
|
.OMRequest;
|
||||||
|
@ -43,10 +48,27 @@ private OzoneManagerRatisUtils() {
|
||||||
* @return OMClientRequest
|
* @return OMClientRequest
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public static OMClientRequest createClientRequest(OMRequest omRequest)
|
public static OMClientRequest createClientRequest(OMRequest omRequest) {
|
||||||
throws IOException {
|
|
||||||
Type cmdType = omRequest.getCmdType();
|
Type cmdType = omRequest.getCmdType();
|
||||||
switch (cmdType) {
|
switch (cmdType) {
|
||||||
|
case CreateVolume:
|
||||||
|
return new OMVolumeCreateRequest(omRequest);
|
||||||
|
case SetVolumeProperty:
|
||||||
|
boolean hasQuota = omRequest.getSetVolumePropertyRequest()
|
||||||
|
.hasQuotaInBytes();
|
||||||
|
boolean hasOwner = omRequest.getSetVolumePropertyRequest().hasOwnerName();
|
||||||
|
Preconditions.checkState(hasOwner || hasQuota, "Either Quota or owner " +
|
||||||
|
"should be set in the SetVolumeProperty request");
|
||||||
|
Preconditions.checkState(!(hasOwner && hasQuota), "Either Quota or " +
|
||||||
|
"owner should be set in the SetVolumeProperty request. Should not " +
|
||||||
|
"set both");
|
||||||
|
if (hasQuota) {
|
||||||
|
return new OMVolumeSetQuotaRequest(omRequest);
|
||||||
|
} else {
|
||||||
|
return new OMVolumeSetOwnerRequest(omRequest);
|
||||||
|
}
|
||||||
|
case DeleteVolume:
|
||||||
|
return new OMVolumeDeleteRequest(omRequest);
|
||||||
case CreateBucket:
|
case CreateBucket:
|
||||||
return new OMBucketCreateRequest(omRequest);
|
return new OMBucketCreateRequest(omRequest);
|
||||||
case DeleteBucket:
|
case DeleteBucket:
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
*/
|
*/
|
||||||
public abstract class OMClientRequest implements RequestAuditor {
|
public abstract class OMClientRequest implements RequestAuditor {
|
||||||
|
|
||||||
private final OMRequest omRequest;
|
private OMRequest omRequest;
|
||||||
|
|
||||||
public OMClientRequest(OMRequest omRequest) {
|
public OMClientRequest(OMRequest omRequest) {
|
||||||
Preconditions.checkNotNull(omRequest);
|
Preconditions.checkNotNull(omRequest);
|
||||||
|
@ -69,7 +69,8 @@ public OMClientRequest(OMRequest omRequest) {
|
||||||
*/
|
*/
|
||||||
public OMRequest preExecute(OzoneManager ozoneManager)
|
public OMRequest preExecute(OzoneManager ozoneManager)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
return getOmRequest().toBuilder().setUserInfo(getUserInfo()).build();
|
omRequest = getOmRequest().toBuilder().setUserInfo(getUserInfo()).build();
|
||||||
|
return omRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -210,4 +211,5 @@ public Map<String, String> buildVolumeAuditMap(String volume) {
|
||||||
auditMap.put(OzoneConsts.VOLUME, volume);
|
auditMap.put(OzoneConsts.VOLUME, volume);
|
||||||
return auditMap;
|
return auditMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,6 +97,7 @@ public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
|
||||||
}
|
}
|
||||||
|
|
||||||
newCreateBucketRequest.setBucketInfo(newBucketInfo.build());
|
newCreateBucketRequest.setBucketInfo(newBucketInfo.build());
|
||||||
|
|
||||||
return getOmRequest().toBuilder().setUserInfo(getUserInfo())
|
return getOmRequest().toBuilder().setUserInfo(getUserInfo())
|
||||||
.setCreateBucketRequest(newCreateBucketRequest.build()).build();
|
.setCreateBucketRequest(newCreateBucketRequest.build()).build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,20 +73,15 @@ public OMBucketSetPropertyRequest(OMRequest omRequest) {
|
||||||
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
long transactionLogIndex) {
|
long transactionLogIndex) {
|
||||||
|
|
||||||
|
|
||||||
SetBucketPropertyRequest setBucketPropertyRequest =
|
SetBucketPropertyRequest setBucketPropertyRequest =
|
||||||
getOmRequest().getSetBucketPropertyRequest();
|
getOmRequest().getSetBucketPropertyRequest();
|
||||||
|
|
||||||
Preconditions.checkNotNull(setBucketPropertyRequest);
|
Preconditions.checkNotNull(setBucketPropertyRequest);
|
||||||
|
|
||||||
OMMetrics omMetrics = ozoneManager.getOmMetrics();
|
OMMetrics omMetrics = ozoneManager.getMetrics();
|
||||||
|
|
||||||
// This will never be null, on a real Ozone cluster. For tests this might
|
|
||||||
// be null. using mockito, to set omMetrics object, but still getting
|
|
||||||
// null. For now added this not null check.
|
|
||||||
//TODO: Removed not null check from here, once tests got fixed.
|
|
||||||
if (omMetrics != null) {
|
|
||||||
omMetrics.incNumBucketUpdates();
|
omMetrics.incNumBucketUpdates();
|
||||||
}
|
|
||||||
|
|
||||||
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
|
||||||
|
@ -113,13 +108,11 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
volumeName, bucketName, null);
|
volumeName, bucketName, null);
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
if (omMetrics != null) {
|
|
||||||
omMetrics.incNumBucketUpdateFails();
|
|
||||||
}
|
|
||||||
auditLog(auditLogger, buildAuditMessage(OMAction.UPDATE_BUCKET,
|
|
||||||
omBucketArgs.toAuditMap(), ex, userInfo));
|
|
||||||
LOG.error("Setting bucket property failed for bucket:{} in volume:{}",
|
LOG.error("Setting bucket property failed for bucket:{} in volume:{}",
|
||||||
bucketName, volumeName, ex);
|
bucketName, volumeName, ex);
|
||||||
|
omMetrics.incNumBucketUpdateFails();
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.UPDATE_BUCKET,
|
||||||
|
omBucketArgs.toAuditMap(), ex, userInfo));
|
||||||
return new OMBucketSetPropertyResponse(omBucketInfo,
|
return new OMBucketSetPropertyResponse(omBucketInfo,
|
||||||
createErrorOMResponse(omResponse, ex));
|
createErrorOMResponse(omResponse, ex));
|
||||||
}
|
}
|
||||||
|
@ -204,11 +197,9 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
SetBucketPropertyResponse.newBuilder().build());
|
SetBucketPropertyResponse.newBuilder().build());
|
||||||
return new OMBucketSetPropertyResponse(omBucketInfo, omResponse.build());
|
return new OMBucketSetPropertyResponse(omBucketInfo, omResponse.build());
|
||||||
} else {
|
} else {
|
||||||
if (omMetrics != null) {
|
|
||||||
omMetrics.incNumBucketUpdateFails();
|
|
||||||
}
|
|
||||||
LOG.error("Setting bucket property failed for bucket:{} in volume:{}",
|
LOG.error("Setting bucket property failed for bucket:{} in volume:{}",
|
||||||
bucketName, volumeName, exception);
|
bucketName, volumeName, exception);
|
||||||
|
omMetrics.incNumBucketUpdateFails();
|
||||||
return new OMBucketSetPropertyResponse(omBucketInfo,
|
return new OMBucketSetPropertyResponse(omBucketInfo,
|
||||||
createErrorOMResponse(omResponse, exception));
|
createErrorOMResponse(omResponse, exception));
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,196 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.OMAction;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeCreateResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetrics;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||||
|
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.OzoneObj;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeResponse;
|
||||||
|
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
|
||||||
|
.VolumeInfo;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeList;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles volume create request.
|
||||||
|
*/
|
||||||
|
public class OMVolumeCreateRequest extends OMClientRequest
|
||||||
|
implements OMVolumeRequest {
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMVolumeCreateRequest.class);
|
||||||
|
|
||||||
|
public OMVolumeCreateRequest(OMRequest omRequest) {
|
||||||
|
super(omRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMRequest preExecute(OzoneManager ozoneManager) throws IOException {
|
||||||
|
|
||||||
|
VolumeInfo volumeInfo =
|
||||||
|
getOmRequest().getCreateVolumeRequest().getVolumeInfo();
|
||||||
|
|
||||||
|
// Set creation time
|
||||||
|
VolumeInfo updatedVolumeInfo =
|
||||||
|
volumeInfo.toBuilder().setCreationTime(Time.now()).build();
|
||||||
|
|
||||||
|
|
||||||
|
return getOmRequest().toBuilder().setCreateVolumeRequest(
|
||||||
|
CreateVolumeRequest.newBuilder().setVolumeInfo(updatedVolumeInfo))
|
||||||
|
.setUserInfo(getUserInfo())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
|
long transactionLogIndex) {
|
||||||
|
|
||||||
|
CreateVolumeRequest createVolumeRequest =
|
||||||
|
getOmRequest().getCreateVolumeRequest();
|
||||||
|
Preconditions.checkNotNull(createVolumeRequest);
|
||||||
|
VolumeInfo volumeInfo = createVolumeRequest.getVolumeInfo();
|
||||||
|
|
||||||
|
OMMetrics omMetrics = ozoneManager.getMetrics();
|
||||||
|
omMetrics.incNumVolumeCreates();
|
||||||
|
|
||||||
|
String volume = volumeInfo.getVolume();
|
||||||
|
String owner = volumeInfo.getOwnerName();
|
||||||
|
|
||||||
|
OMResponse.Builder omResponse = OMResponse.newBuilder().setCmdType(
|
||||||
|
OzoneManagerProtocolProtos.Type.CreateVolume).setStatus(
|
||||||
|
OzoneManagerProtocolProtos.Status.OK).setSuccess(true);
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs = null;
|
||||||
|
|
||||||
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
|
||||||
|
AuditLogger auditLogger = ozoneManager.getAuditLogger();
|
||||||
|
OzoneManagerProtocolProtos.UserInfo userInfo = getOmRequest().getUserInfo();
|
||||||
|
|
||||||
|
// Doing this here, so we can do protobuf conversion outside of lock.
|
||||||
|
try {
|
||||||
|
omVolumeArgs = OmVolumeArgs.getFromProtobuf(volumeInfo);
|
||||||
|
// check Acl
|
||||||
|
if (ozoneManager.getAclsEnabled()) {
|
||||||
|
checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
|
||||||
|
OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.CREATE, volume,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
omMetrics.incNumVolumeCreateFails();
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.CREATE_VOLUME,
|
||||||
|
buildVolumeAuditMap(volume), ex, userInfo));
|
||||||
|
LOG.error("Volume creation failed for user:{} volume:{}", owner, volume,
|
||||||
|
ex);
|
||||||
|
return new OMVolumeCreateResponse(omVolumeArgs, null,
|
||||||
|
createErrorOMResponse(omResponse, ex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String dbUserKey = omMetadataManager.getUserKey(owner);
|
||||||
|
String dbVolumeKey = omMetadataManager.getVolumeKey(volume);
|
||||||
|
VolumeList volumeList = null;
|
||||||
|
|
||||||
|
// acquire lock.
|
||||||
|
omMetadataManager.getLock().acquireUserLock(owner);
|
||||||
|
omMetadataManager.getLock().acquireVolumeLock(volume);
|
||||||
|
|
||||||
|
IOException exception = null;
|
||||||
|
try {
|
||||||
|
OmVolumeArgs dbVolumeArgs =
|
||||||
|
omMetadataManager.getVolumeTable().get(dbVolumeKey);
|
||||||
|
|
||||||
|
// Validation: Check if volume already exists
|
||||||
|
if (dbVolumeArgs != null) {
|
||||||
|
LOG.debug("volume:{} already exists", omVolumeArgs.getVolume());
|
||||||
|
throw new OMException("Volume already exists",
|
||||||
|
OMException.ResultCodes.VOLUME_ALREADY_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
volumeList = omMetadataManager.getUserTable().get(dbUserKey);
|
||||||
|
volumeList = addVolumeToOwnerList(volumeList,
|
||||||
|
volume, owner, ozoneManager.getMaxUserVolumeCount());
|
||||||
|
|
||||||
|
// Update cache: Update user and volume cache.
|
||||||
|
omMetadataManager.getUserTable().addCacheEntry(new CacheKey<>(dbUserKey),
|
||||||
|
new CacheValue<>(Optional.of(volumeList), transactionLogIndex));
|
||||||
|
|
||||||
|
omMetadataManager.getVolumeTable().addCacheEntry(
|
||||||
|
new CacheKey<>(dbVolumeKey),
|
||||||
|
new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex));
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
exception = ex;
|
||||||
|
} finally {
|
||||||
|
omMetadataManager.getLock().releaseVolumeLock(volumeInfo.getVolume());
|
||||||
|
omMetadataManager.getLock().releaseUserLock(dbUserKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performing audit logging outside of the lock.
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.CREATE_VOLUME,
|
||||||
|
omVolumeArgs.toAuditMap(), exception, userInfo));
|
||||||
|
|
||||||
|
// return response after releasing lock.
|
||||||
|
if (exception == null) {
|
||||||
|
LOG.debug("created volume:{} for user:{}", omVolumeArgs.getVolume(),
|
||||||
|
owner);
|
||||||
|
omMetrics.incNumVolumes();
|
||||||
|
omResponse.setCreateVolumeResponse(CreateVolumeResponse.newBuilder()
|
||||||
|
.build());
|
||||||
|
return new OMVolumeCreateResponse(omVolumeArgs, volumeList,
|
||||||
|
omResponse.build());
|
||||||
|
} else {
|
||||||
|
LOG.error("Volume creation failed for user:{} volume:{}", owner,
|
||||||
|
volumeInfo.getVolume(), exception);
|
||||||
|
omMetrics.incNumVolumeCreateFails();
|
||||||
|
return new OMVolumeCreateResponse(omVolumeArgs, volumeList,
|
||||||
|
createErrorOMResponse(omResponse, exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
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.OzoneManager;
|
||||||
|
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetrics;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeCreateResponse;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.OzoneObj;
|
||||||
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeDeleteResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.DeleteVolumeRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.DeleteVolumeResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles volume delete request.
|
||||||
|
*/
|
||||||
|
public class OMVolumeDeleteRequest extends OMClientRequest
|
||||||
|
implements OMVolumeRequest {
|
||||||
|
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMVolumeDeleteRequest.class);
|
||||||
|
|
||||||
|
public OMVolumeDeleteRequest(OMRequest omRequest) {
|
||||||
|
super(omRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
|
long transactionLogIndex) {
|
||||||
|
|
||||||
|
DeleteVolumeRequest deleteVolumeRequest =
|
||||||
|
getOmRequest().getDeleteVolumeRequest();
|
||||||
|
Preconditions.checkNotNull(deleteVolumeRequest);
|
||||||
|
|
||||||
|
String volume = deleteVolumeRequest.getVolumeName();
|
||||||
|
|
||||||
|
OMMetrics omMetrics = ozoneManager.getMetrics();
|
||||||
|
omMetrics.incNumVolumeDeletes();
|
||||||
|
|
||||||
|
OMResponse.Builder omResponse = OMResponse.newBuilder().setCmdType(
|
||||||
|
OzoneManagerProtocolProtos.Type.DeleteVolume).setStatus(
|
||||||
|
OzoneManagerProtocolProtos.Status.OK).setSuccess(true);
|
||||||
|
|
||||||
|
AuditLogger auditLogger = ozoneManager.getAuditLogger();
|
||||||
|
OzoneManagerProtocolProtos.UserInfo userInfo = getOmRequest().getUserInfo();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// check Acl
|
||||||
|
if (ozoneManager.getAclsEnabled()) {
|
||||||
|
checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
|
||||||
|
OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.DELETE, volume,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Volume deletion failed for volume:{}", volume, ex);
|
||||||
|
omMetrics.incNumVolumeDeleteFails();
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.DELETE_VOLUME,
|
||||||
|
buildVolumeAuditMap(volume), ex, userInfo));
|
||||||
|
return new OMVolumeCreateResponse(null, null,
|
||||||
|
createErrorOMResponse(omResponse, ex));
|
||||||
|
}
|
||||||
|
|
||||||
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs = null;
|
||||||
|
String owner = null;
|
||||||
|
|
||||||
|
omMetadataManager.getLock().acquireVolumeLock(volume);
|
||||||
|
try {
|
||||||
|
owner = getVolumeInfo(omMetadataManager, volume).getOwnerName();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Volume deletion failed for volume:{}", volume, ex);
|
||||||
|
omMetrics.incNumVolumeDeleteFails();
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.DELETE_VOLUME,
|
||||||
|
buildVolumeAuditMap(volume), ex, userInfo));
|
||||||
|
return new OMVolumeDeleteResponse(null, null, null,
|
||||||
|
createErrorOMResponse(omResponse, ex));
|
||||||
|
} finally {
|
||||||
|
omMetadataManager.getLock().releaseVolumeLock(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release and reacquire lock for now it will not be a problem for now, as
|
||||||
|
// applyTransaction serializes the operation's.
|
||||||
|
// TODO: Revisit this logic once HDDS-1672 checks in.
|
||||||
|
|
||||||
|
// We cannot acquire user lock holding volume lock, so released volume
|
||||||
|
// lock, and acquiring user and volume lock.
|
||||||
|
|
||||||
|
omMetadataManager.getLock().acquireUserLock(owner);
|
||||||
|
omMetadataManager.getLock().acquireVolumeLock(volume);
|
||||||
|
|
||||||
|
String dbUserKey = omMetadataManager.getUserKey(owner);
|
||||||
|
String dbVolumeKey = omMetadataManager.getVolumeKey(volume);
|
||||||
|
|
||||||
|
IOException exception = null;
|
||||||
|
OzoneManagerProtocolProtos.VolumeList newVolumeList = null;
|
||||||
|
try {
|
||||||
|
if (!omMetadataManager.isVolumeEmpty(volume)) {
|
||||||
|
LOG.debug("volume:{} is not empty", volume);
|
||||||
|
throw new OMException(OMException.ResultCodes.VOLUME_NOT_EMPTY);
|
||||||
|
}
|
||||||
|
|
||||||
|
newVolumeList = omMetadataManager.getUserTable().get(owner);
|
||||||
|
|
||||||
|
// delete the volume from the owner list
|
||||||
|
// as well as delete the volume entry
|
||||||
|
newVolumeList = delVolumeFromOwnerList(newVolumeList, volume, owner);
|
||||||
|
|
||||||
|
omMetadataManager.getUserTable().addCacheEntry(new CacheKey<>(dbUserKey),
|
||||||
|
new CacheValue<>(Optional.of(newVolumeList), transactionLogIndex));
|
||||||
|
|
||||||
|
omMetadataManager.getVolumeTable().addCacheEntry(
|
||||||
|
new CacheKey<>(dbVolumeKey), new CacheValue<>(Optional.absent(),
|
||||||
|
transactionLogIndex));
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
exception = ex;
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
omMetadataManager.getLock().releaseVolumeLock(volume);
|
||||||
|
omMetadataManager.getLock().releaseUserLock(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performing audit logging outside of the lock.
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.DELETE_VOLUME,
|
||||||
|
buildVolumeAuditMap(volume), exception, userInfo));
|
||||||
|
|
||||||
|
// return response after releasing lock.
|
||||||
|
if (exception == null) {
|
||||||
|
LOG.debug("Volume deleted for user:{} volume:{}", owner, volume);
|
||||||
|
omMetrics.decNumVolumes();
|
||||||
|
omResponse.setDeleteVolumeResponse(
|
||||||
|
DeleteVolumeResponse.newBuilder().build());
|
||||||
|
return new OMVolumeDeleteResponse(volume, owner, newVolumeList,
|
||||||
|
omResponse.build());
|
||||||
|
} else {
|
||||||
|
LOG.error("Volume deletion failed for user:{} volume:{}",
|
||||||
|
owner, volume, exception);
|
||||||
|
omMetrics.incNumVolumeDeleteFails();
|
||||||
|
return new OMVolumeDeleteResponse(null, null, null,
|
||||||
|
createErrorOMResponse(omResponse, exception));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return volume info for the specified volume. This method should be
|
||||||
|
* called after acquiring volume lock.
|
||||||
|
* @param omMetadataManager
|
||||||
|
* @param volume
|
||||||
|
* @return OmVolumeArgs
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private OmVolumeArgs getVolumeInfo(OMMetadataManager omMetadataManager,
|
||||||
|
String volume) throws IOException {
|
||||||
|
|
||||||
|
String dbVolumeKey = omMetadataManager.getVolumeKey(volume);
|
||||||
|
OmVolumeArgs volumeArgs =
|
||||||
|
omMetadataManager.getVolumeTable().get(dbVolumeKey);
|
||||||
|
if (volumeArgs == null) {
|
||||||
|
throw new OMException("Volume " + volume + " is not found",
|
||||||
|
OMException.ResultCodes.VOLUME_NOT_FOUND);
|
||||||
|
}
|
||||||
|
return volumeArgs;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeList;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines common methods required for volume requests.
|
||||||
|
*/
|
||||||
|
public interface OMVolumeRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete volume from user volume list. This method should be called after
|
||||||
|
* acquiring user lock.
|
||||||
|
* @param volumeList - current volume list owned by user.
|
||||||
|
* @param volume - volume which needs to deleted from the volume list.
|
||||||
|
* @param owner
|
||||||
|
* @return VolumeList - updated volume list for the user.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
default VolumeList delVolumeFromOwnerList(VolumeList volumeList,
|
||||||
|
String volume, String owner) throws IOException {
|
||||||
|
|
||||||
|
List<String> prevVolList = new ArrayList<>();
|
||||||
|
|
||||||
|
if (volumeList != null) {
|
||||||
|
prevVolList.addAll(volumeList.getVolumeNamesList());
|
||||||
|
} else {
|
||||||
|
// No Volumes for this user
|
||||||
|
throw new OMException("User not found: " + owner,
|
||||||
|
OMException.ResultCodes.USER_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the volume from the list
|
||||||
|
prevVolList.remove(volume);
|
||||||
|
VolumeList newVolList = VolumeList.newBuilder()
|
||||||
|
.addAllVolumeNames(prevVolList).build();
|
||||||
|
return newVolList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add volume to user volume list. This method should be called after
|
||||||
|
* acquiring user lock.
|
||||||
|
* @param volumeList - current volume list owned by user.
|
||||||
|
* @param volume - volume which needs to be added to this list.
|
||||||
|
* @param owner
|
||||||
|
* @param maxUserVolumeCount
|
||||||
|
* @return VolumeList - which is updated volume list.
|
||||||
|
* @throws OMException - if user has volumes greater than
|
||||||
|
* maxUserVolumeCount, an exception is thrown.
|
||||||
|
*/
|
||||||
|
default VolumeList addVolumeToOwnerList(
|
||||||
|
VolumeList volumeList, String volume, String owner,
|
||||||
|
long maxUserVolumeCount) throws IOException {
|
||||||
|
|
||||||
|
// Check the volume count
|
||||||
|
if (volumeList != null &&
|
||||||
|
volumeList.getVolumeNamesList().size() >= maxUserVolumeCount) {
|
||||||
|
throw new OMException("Too many volumes for user:" + owner,
|
||||||
|
OMException.ResultCodes.USER_TOO_MANY_VOLUMES);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> prevVolList = new ArrayList<>();
|
||||||
|
if (volumeList != null) {
|
||||||
|
prevVolList.addAll(volumeList.getVolumeNamesList());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the new volume to the list
|
||||||
|
prevVolList.add(volume);
|
||||||
|
VolumeList newVolList = VolumeList.newBuilder()
|
||||||
|
.addAllVolumeNames(prevVolList).build();
|
||||||
|
|
||||||
|
return newVolList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,212 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.OMAction;
|
||||||
|
import org.apache.hadoop.ozone.OzoneConsts;
|
||||||
|
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.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeCreateResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeSetOwnerResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
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
|
||||||
|
.SetVolumePropertyRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.SetVolumePropertyResponse;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.OzoneObj;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle set owner request for volume.
|
||||||
|
*/
|
||||||
|
public class OMVolumeSetOwnerRequest extends OMClientRequest
|
||||||
|
implements OMVolumeRequest {
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMVolumeSetOwnerRequest.class);
|
||||||
|
|
||||||
|
public OMVolumeSetOwnerRequest(OMRequest omRequest) {
|
||||||
|
super(omRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
|
long transactionLogIndex) {
|
||||||
|
|
||||||
|
SetVolumePropertyRequest setVolumePropertyRequest =
|
||||||
|
getOmRequest().getSetVolumePropertyRequest();
|
||||||
|
|
||||||
|
Preconditions.checkNotNull(setVolumePropertyRequest);
|
||||||
|
|
||||||
|
OMResponse.Builder omResponse = OMResponse.newBuilder().setCmdType(
|
||||||
|
OzoneManagerProtocolProtos.Type.SetVolumeProperty).setStatus(
|
||||||
|
OzoneManagerProtocolProtos.Status.OK).setSuccess(true);
|
||||||
|
|
||||||
|
// In production this will never happen, this request will be called only
|
||||||
|
// when we have ownerName in setVolumePropertyRequest.
|
||||||
|
if (!setVolumePropertyRequest.hasOwnerName()) {
|
||||||
|
omResponse.setStatus(OzoneManagerProtocolProtos.Status.INVALID_REQUEST)
|
||||||
|
.setSuccess(false);
|
||||||
|
return new OMVolumeSetOwnerResponse(null, null, null, null,
|
||||||
|
omResponse.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
OMMetrics omMetrics = ozoneManager.getMetrics();
|
||||||
|
omMetrics.incNumVolumeUpdates();
|
||||||
|
String volume = setVolumePropertyRequest.getVolumeName();
|
||||||
|
String newOwner = setVolumePropertyRequest.getOwnerName();
|
||||||
|
|
||||||
|
AuditLogger auditLogger = ozoneManager.getAuditLogger();
|
||||||
|
OzoneManagerProtocolProtos.UserInfo userInfo = getOmRequest().getUserInfo();
|
||||||
|
|
||||||
|
Map<String, String> auditMap = buildVolumeAuditMap(volume);
|
||||||
|
auditMap.put(OzoneConsts.OWNER, newOwner);
|
||||||
|
try {
|
||||||
|
// check Acl
|
||||||
|
if (ozoneManager.getAclsEnabled()) {
|
||||||
|
checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
|
||||||
|
OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.WRITE_ACL,
|
||||||
|
volume, null, null);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Changing volume ownership failed for user:{} volume:{}",
|
||||||
|
newOwner, volume);
|
||||||
|
omMetrics.incNumVolumeUpdateFails();
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.SET_OWNER, auditMap,
|
||||||
|
ex, userInfo));
|
||||||
|
return new OMVolumeCreateResponse(null, null,
|
||||||
|
createErrorOMResponse(omResponse, ex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long maxUserVolumeCount = ozoneManager.getMaxUserVolumeCount();
|
||||||
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
String dbVolumeKey = omMetadataManager.getVolumeKey(volume);
|
||||||
|
String oldOwner = null;
|
||||||
|
OzoneManagerProtocolProtos.VolumeList oldOwnerVolumeList = null;
|
||||||
|
OzoneManagerProtocolProtos.VolumeList newOwnerVolumeList = null;
|
||||||
|
OmVolumeArgs omVolumeArgs = null;
|
||||||
|
IOException exception = null;
|
||||||
|
|
||||||
|
omMetadataManager.getLock().acquireUserLock(newOwner);
|
||||||
|
omMetadataManager.getLock().acquireVolumeLock(volume);
|
||||||
|
|
||||||
|
boolean needToreleaseOldOwnerLock = false;
|
||||||
|
try {
|
||||||
|
omVolumeArgs = omMetadataManager.getVolumeTable().get(dbVolumeKey);
|
||||||
|
|
||||||
|
if (omVolumeArgs == null) {
|
||||||
|
LOG.debug("Changing volume ownership failed for user:{} volume:{}",
|
||||||
|
newOwner, volume);
|
||||||
|
throw new OMException("Volume " + volume + " is not found",
|
||||||
|
OMException.ResultCodes.VOLUME_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
oldOwner = omVolumeArgs.getOwnerName();
|
||||||
|
|
||||||
|
|
||||||
|
// Release and reacquire lock for now it will not be a problem, as
|
||||||
|
// applyTransaction serializes the operation's.
|
||||||
|
// TODO: Revisit this logic once HDDS-1672 checks in.
|
||||||
|
|
||||||
|
// releasing volume lock, as to acquire user lock we need to release
|
||||||
|
// volume lock.
|
||||||
|
omMetadataManager.getLock().releaseVolumeLock(volume);
|
||||||
|
omMetadataManager.getLock().acquireUserLock(oldOwner);
|
||||||
|
omMetadataManager.getLock().acquireVolumeLock(volume);
|
||||||
|
|
||||||
|
needToreleaseOldOwnerLock = true;
|
||||||
|
oldOwnerVolumeList =
|
||||||
|
omMetadataManager.getUserTable().get(oldOwner);
|
||||||
|
|
||||||
|
oldOwnerVolumeList = delVolumeFromOwnerList(
|
||||||
|
oldOwnerVolumeList, volume, oldOwner);
|
||||||
|
|
||||||
|
|
||||||
|
newOwnerVolumeList = omMetadataManager.getUserTable().get(newOwner);
|
||||||
|
newOwnerVolumeList = addVolumeToOwnerList(
|
||||||
|
newOwnerVolumeList, volume, newOwner, maxUserVolumeCount);
|
||||||
|
|
||||||
|
// Set owner with new owner name.
|
||||||
|
omVolumeArgs.setOwnerName(newOwner);
|
||||||
|
|
||||||
|
// Update cache.
|
||||||
|
omMetadataManager.getUserTable().addCacheEntry(
|
||||||
|
new CacheKey<>(omMetadataManager.getUserKey(newOwner)),
|
||||||
|
new CacheValue<>(Optional.of(newOwnerVolumeList),
|
||||||
|
transactionLogIndex));
|
||||||
|
omMetadataManager.getUserTable().addCacheEntry(
|
||||||
|
new CacheKey<>(omMetadataManager.getUserKey(oldOwner)),
|
||||||
|
new CacheValue<>(Optional.of(oldOwnerVolumeList),
|
||||||
|
transactionLogIndex));
|
||||||
|
omMetadataManager.getVolumeTable().addCacheEntry(
|
||||||
|
new CacheKey<>(dbVolumeKey),
|
||||||
|
new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex));
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
exception = ex;
|
||||||
|
} finally {
|
||||||
|
omMetadataManager.getLock().releaseVolumeLock(volume);
|
||||||
|
omMetadataManager.getLock().releaseUserLock(newOwner);
|
||||||
|
if (needToreleaseOldOwnerLock) {
|
||||||
|
omMetadataManager.getLock().releaseUserLock(oldOwner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performing audit logging outside of the lock.
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.SET_OWNER, auditMap,
|
||||||
|
exception, userInfo));
|
||||||
|
|
||||||
|
// return response after releasing lock.
|
||||||
|
if (exception == null) {
|
||||||
|
LOG.debug("Successfully changed Owner of Volume {} from {} -> {}", volume,
|
||||||
|
oldOwner, newOwner);
|
||||||
|
omResponse.setSetVolumePropertyResponse(
|
||||||
|
SetVolumePropertyResponse.newBuilder().build());
|
||||||
|
return new OMVolumeSetOwnerResponse(oldOwner, oldOwnerVolumeList,
|
||||||
|
newOwnerVolumeList, omVolumeArgs, omResponse.build());
|
||||||
|
} else {
|
||||||
|
LOG.error("Changing volume ownership failed for user:{} volume:{}",
|
||||||
|
newOwner, volume, exception);
|
||||||
|
omMetrics.incNumVolumeUpdateFails();
|
||||||
|
return new OMVolumeSetOwnerResponse(null, null, null, null,
|
||||||
|
createErrorOMResponse(omResponse, exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
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.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.OMAction;
|
||||||
|
import org.apache.hadoop.ozone.OzoneConsts;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetrics;
|
||||||
|
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeSetQuotaResponse;
|
||||||
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeCreateResponse;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
|
||||||
|
import org.apache.hadoop.ozone.security.acl.OzoneObj;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
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
|
||||||
|
.SetVolumePropertyRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.SetVolumePropertyResponse;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles set Quota request for volume.
|
||||||
|
*/
|
||||||
|
public class OMVolumeSetQuotaRequest extends OMClientRequest {
|
||||||
|
private static final Logger LOG =
|
||||||
|
LoggerFactory.getLogger(OMVolumeSetQuotaRequest.class);
|
||||||
|
|
||||||
|
public OMVolumeSetQuotaRequest(OMRequest omRequest) {
|
||||||
|
super(omRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager,
|
||||||
|
long transactionLogIndex) {
|
||||||
|
|
||||||
|
SetVolumePropertyRequest setVolumePropertyRequest =
|
||||||
|
getOmRequest().getSetVolumePropertyRequest();
|
||||||
|
|
||||||
|
Preconditions.checkNotNull(setVolumePropertyRequest);
|
||||||
|
|
||||||
|
OMResponse.Builder omResponse = OMResponse.newBuilder().setCmdType(
|
||||||
|
OzoneManagerProtocolProtos.Type.SetVolumeProperty).setStatus(
|
||||||
|
OzoneManagerProtocolProtos.Status.OK).setSuccess(true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// In production this will never happen, this request will be called only
|
||||||
|
// when we have quota in bytes is set in setVolumePropertyRequest.
|
||||||
|
if (!setVolumePropertyRequest.hasQuotaInBytes()) {
|
||||||
|
omResponse.setStatus(OzoneManagerProtocolProtos.Status.INVALID_REQUEST)
|
||||||
|
.setSuccess(false);
|
||||||
|
return new OMVolumeSetQuotaResponse(null,
|
||||||
|
omResponse.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
String volume = setVolumePropertyRequest.getVolumeName();
|
||||||
|
OMMetrics omMetrics = ozoneManager.getMetrics();
|
||||||
|
omMetrics.incNumVolumeUpdates();
|
||||||
|
|
||||||
|
AuditLogger auditLogger = ozoneManager.getAuditLogger();
|
||||||
|
OzoneManagerProtocolProtos.UserInfo userInfo = getOmRequest().getUserInfo();
|
||||||
|
Map<String, String> auditMap = buildVolumeAuditMap(volume);
|
||||||
|
auditMap.put(OzoneConsts.QUOTA,
|
||||||
|
String.valueOf(setVolumePropertyRequest.getQuotaInBytes()));
|
||||||
|
|
||||||
|
try {
|
||||||
|
// check Acl
|
||||||
|
if (ozoneManager.getAclsEnabled()) {
|
||||||
|
checkAcls(ozoneManager, OzoneObj.ResourceType.VOLUME,
|
||||||
|
OzoneObj.StoreType.OZONE, IAccessAuthorizer.ACLType.WRITE, volume,
|
||||||
|
null, null);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LOG.error("Changing volume quota failed for volume:{} quota:{}", volume,
|
||||||
|
setVolumePropertyRequest.getQuotaInBytes(), ex);
|
||||||
|
omMetrics.incNumVolumeUpdateFails();
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.SET_QUOTA, auditMap,
|
||||||
|
ex, userInfo));
|
||||||
|
return new OMVolumeCreateResponse(null, null,
|
||||||
|
createErrorOMResponse(omResponse, ex));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OMMetadataManager omMetadataManager = ozoneManager.getMetadataManager();
|
||||||
|
|
||||||
|
IOException exception = null;
|
||||||
|
OmVolumeArgs omVolumeArgs = null;
|
||||||
|
|
||||||
|
omMetadataManager.getLock().acquireVolumeLock(volume);
|
||||||
|
try {
|
||||||
|
String dbVolumeKey = omMetadataManager.getVolumeKey(volume);
|
||||||
|
omVolumeArgs = omMetadataManager.getVolumeTable().get(dbVolumeKey);
|
||||||
|
|
||||||
|
if (omVolumeArgs == null) {
|
||||||
|
LOG.debug("volume:{} does not exist", volume);
|
||||||
|
throw new OMException(OMException.ResultCodes.VOLUME_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
omVolumeArgs.setQuotaInBytes(setVolumePropertyRequest.getQuotaInBytes());
|
||||||
|
|
||||||
|
// update cache.
|
||||||
|
omMetadataManager.getVolumeTable().addCacheEntry(
|
||||||
|
new CacheKey<>(dbVolumeKey),
|
||||||
|
new CacheValue<>(Optional.of(omVolumeArgs), transactionLogIndex));
|
||||||
|
|
||||||
|
} catch (IOException ex) {
|
||||||
|
exception = ex;
|
||||||
|
} finally {
|
||||||
|
omMetadataManager.getLock().releaseVolumeLock(volume);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Performing audit logging outside of the lock.
|
||||||
|
auditLog(auditLogger, buildAuditMessage(OMAction.SET_QUOTA, auditMap,
|
||||||
|
exception, userInfo));
|
||||||
|
|
||||||
|
// return response after releasing lock.
|
||||||
|
if (exception == null) {
|
||||||
|
omResponse.setSetVolumePropertyResponse(
|
||||||
|
SetVolumePropertyResponse.newBuilder().build());
|
||||||
|
return new OMVolumeSetQuotaResponse(omVolumeArgs, omResponse.build());
|
||||||
|
} else {
|
||||||
|
omMetrics.incNumVolumeUpdateFails();
|
||||||
|
LOG.error("Changing volume quota failed for volume:{} quota:{}", volume,
|
||||||
|
setVolumePropertyRequest.getQuotaInBytes(), exception);
|
||||||
|
return new OMVolumeSetQuotaResponse(null,
|
||||||
|
createErrorOMResponse(omResponse, exception));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* 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 contains classes related to volume requests.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.request.volume;
|
|
@ -45,6 +45,8 @@ public OMBucketCreateResponse(OmBucketInfo omBucketInfo,
|
||||||
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
BatchOperation batchOperation) throws IOException {
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
String dbBucketKey =
|
String dbBucketKey =
|
||||||
omMetadataManager.getBucketKey(omBucketInfo.getVolumeName(),
|
omMetadataManager.getBucketKey(omBucketInfo.getVolumeName(),
|
||||||
|
|
|
@ -44,6 +44,9 @@ public OMBucketDeleteResponse(
|
||||||
@Override
|
@Override
|
||||||
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
BatchOperation batchOperation) throws IOException {
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
String dbBucketKey =
|
String dbBucketKey =
|
||||||
omMetadataManager.getBucketKey(volumeName, bucketName);
|
omMetadataManager.getBucketKey(volumeName, bucketName);
|
||||||
|
|
|
@ -42,6 +42,9 @@ public OMBucketSetPropertyResponse(OmBucketInfo omBucketInfo,
|
||||||
@Override
|
@Override
|
||||||
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
BatchOperation batchOperation) throws IOException {
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
String dbBucketKey =
|
String dbBucketKey =
|
||||||
omMetadataManager.getBucketKey(omBucketInfo.getVolumeName(),
|
omMetadataManager.getBucketKey(omBucketInfo.getVolumeName(),
|
||||||
|
|
|
@ -16,12 +16,15 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.om.response;
|
package org.apache.hadoop.ozone.om.response.volume;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
.OMResponse;
|
.OMResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
@ -47,21 +50,22 @@ public OMVolumeCreateResponse(OmVolumeArgs omVolumeArgs,
|
||||||
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
BatchOperation batchOperation) throws IOException {
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
String dbVolumeKey =
|
String dbVolumeKey =
|
||||||
omMetadataManager.getVolumeKey(omVolumeArgs.getVolume());
|
omMetadataManager.getVolumeKey(omVolumeArgs.getVolume());
|
||||||
String dbUserKey =
|
String dbUserKey =
|
||||||
omMetadataManager.getUserKey(omVolumeArgs.getOwnerName());
|
omMetadataManager.getUserKey(omVolumeArgs.getOwnerName());
|
||||||
|
|
||||||
omMetadataManager.getVolumeTable().putWithBatch(batchOperation, dbVolumeKey,
|
omMetadataManager.getVolumeTable().putWithBatch(batchOperation,
|
||||||
omVolumeArgs);
|
dbVolumeKey, omVolumeArgs);
|
||||||
omMetadataManager.getUserTable().putWithBatch(batchOperation, dbUserKey,
|
omMetadataManager.getUserTable().putWithBatch(batchOperation, dbUserKey,
|
||||||
volumeList);
|
volumeList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public VolumeList getVolumeList() {
|
|
||||||
return volumeList;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
public OmVolumeArgs getOmVolumeArgs() {
|
public OmVolumeArgs getOmVolumeArgs() {
|
||||||
return omVolumeArgs;
|
return omVolumeArgs;
|
||||||
}
|
}
|
|
@ -16,11 +16,13 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.om.response;
|
package org.apache.hadoop.ozone.om.response.volume;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
.OMResponse;
|
.OMResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
@ -46,6 +48,10 @@ public OMVolumeDeleteResponse(String volume, String owner,
|
||||||
@Override
|
@Override
|
||||||
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
BatchOperation batchOperation) throws IOException {
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
String dbUserKey = omMetadataManager.getUserKey(owner);
|
String dbUserKey = omMetadataManager.getUserKey(owner);
|
||||||
VolumeList volumeList = updatedVolumeList;
|
VolumeList volumeList = updatedVolumeList;
|
||||||
if (updatedVolumeList.getVolumeNamesList().size() == 0) {
|
if (updatedVolumeList.getVolumeNamesList().size() == 0) {
|
||||||
|
@ -58,6 +64,7 @@ public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
omMetadataManager.getVolumeTable().deleteWithBatch(batchOperation,
|
omMetadataManager.getVolumeTable().deleteWithBatch(batchOperation,
|
||||||
omMetadataManager.getVolumeKey(volume));
|
omMetadataManager.getVolumeKey(volume));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeList;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.utils.db.BatchOperation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response for set owner request.
|
||||||
|
*/
|
||||||
|
public class OMVolumeSetOwnerResponse extends OMClientResponse {
|
||||||
|
|
||||||
|
private String oldOwner;
|
||||||
|
private VolumeList oldOwnerVolumeList;
|
||||||
|
private VolumeList newOwnerVolumeList;
|
||||||
|
private OmVolumeArgs newOwnerVolumeArgs;
|
||||||
|
|
||||||
|
public OMVolumeSetOwnerResponse(String oldOwner,
|
||||||
|
VolumeList oldOwnerVolumeList, VolumeList newOwnerVolumeList,
|
||||||
|
OmVolumeArgs newOwnerVolumeArgs, OMResponse omResponse) {
|
||||||
|
super(omResponse);
|
||||||
|
this.oldOwner = oldOwner;
|
||||||
|
this.oldOwnerVolumeList = oldOwnerVolumeList;
|
||||||
|
this.newOwnerVolumeList = newOwnerVolumeList;
|
||||||
|
this.newOwnerVolumeArgs = newOwnerVolumeArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
|
String oldOwnerKey = omMetadataManager.getUserKey(oldOwner);
|
||||||
|
String newOwnerKey =
|
||||||
|
omMetadataManager.getUserKey(newOwnerVolumeArgs.getOwnerName());
|
||||||
|
if (oldOwnerVolumeList.getVolumeNamesList().size() == 0) {
|
||||||
|
omMetadataManager.getUserTable().deleteWithBatch(batchOperation,
|
||||||
|
oldOwnerKey);
|
||||||
|
} else {
|
||||||
|
omMetadataManager.getUserTable().putWithBatch(batchOperation,
|
||||||
|
oldOwnerKey, oldOwnerVolumeList);
|
||||||
|
}
|
||||||
|
omMetadataManager.getUserTable().putWithBatch(batchOperation, newOwnerKey,
|
||||||
|
newOwnerVolumeList);
|
||||||
|
|
||||||
|
String dbVolumeKey =
|
||||||
|
omMetadataManager.getVolumeKey(newOwnerVolumeArgs.getVolume());
|
||||||
|
omMetadataManager.getVolumeTable().putWithBatch(batchOperation,
|
||||||
|
dbVolumeKey, newOwnerVolumeArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.om.OMMetadataManager;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
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 java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response for set quota request.
|
||||||
|
*/
|
||||||
|
public class OMVolumeSetQuotaResponse extends OMClientResponse {
|
||||||
|
private OmVolumeArgs omVolumeArgs;
|
||||||
|
|
||||||
|
public OMVolumeSetQuotaResponse(OmVolumeArgs omVolumeArgs,
|
||||||
|
OMResponse omResponse) {
|
||||||
|
super(omResponse);
|
||||||
|
this.omVolumeArgs = omVolumeArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addToDBBatch(OMMetadataManager omMetadataManager,
|
||||||
|
BatchOperation batchOperation) throws IOException {
|
||||||
|
|
||||||
|
// For OmResponse with failure, this should do nothing. This method is
|
||||||
|
// not called in failure scenario in OM code.
|
||||||
|
if (getOMResponse().getStatus() == OzoneManagerProtocolProtos.Status.OK) {
|
||||||
|
omMetadataManager.getVolumeTable().putWithBatch(batchOperation,
|
||||||
|
omMetadataManager.getVolumeKey(omVolumeArgs.getVolume()),
|
||||||
|
omVolumeArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/**
|
||||||
|
* 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 contains classes related to volume requests.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.response.volume;
|
|
@ -96,23 +96,10 @@ public OMResponse handleApplyTransaction(OMRequest omRequest,
|
||||||
long transactionLogIndex) {
|
long transactionLogIndex) {
|
||||||
LOG.debug("Received OMRequest: {}, ", omRequest);
|
LOG.debug("Received OMRequest: {}, ", omRequest);
|
||||||
Type cmdType = omRequest.getCmdType();
|
Type cmdType = omRequest.getCmdType();
|
||||||
OMResponse.Builder responseBuilder =
|
|
||||||
OMResponse.newBuilder().setCmdType(cmdType)
|
|
||||||
.setStatus(Status.OK);
|
|
||||||
try {
|
|
||||||
switch (cmdType) {
|
switch (cmdType) {
|
||||||
case CreateVolume:
|
case CreateVolume:
|
||||||
responseBuilder.setCreateVolumeResponse(
|
|
||||||
handleCreateVolumeApply(omRequest));
|
|
||||||
break;
|
|
||||||
case SetVolumeProperty:
|
case SetVolumeProperty:
|
||||||
responseBuilder.setSetVolumePropertyResponse(
|
|
||||||
handleSetVolumePropertyApply(omRequest));
|
|
||||||
break;
|
|
||||||
case DeleteVolume:
|
case DeleteVolume:
|
||||||
responseBuilder.setDeleteVolumeResponse(
|
|
||||||
handleDeleteVolumeApply(omRequest));
|
|
||||||
break;
|
|
||||||
case CreateBucket:
|
case CreateBucket:
|
||||||
case DeleteBucket:
|
case DeleteBucket:
|
||||||
case SetBucketProperty:
|
case SetBucketProperty:
|
||||||
|
@ -139,15 +126,6 @@ public OMResponse handleApplyTransaction(OMRequest omRequest,
|
||||||
// here.
|
// here.
|
||||||
return handle(omRequest);
|
return handle(omRequest);
|
||||||
}
|
}
|
||||||
responseBuilder.setSuccess(true);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
responseBuilder.setSuccess(false);
|
|
||||||
responseBuilder.setStatus(exceptionToResponseStatus(ex));
|
|
||||||
if (ex.getMessage() != null) {
|
|
||||||
responseBuilder.setMessage(ex.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return responseBuilder.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
|
import org.apache.hadoop.ozone.om.OmMetadataManagerImpl;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
|
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
import org.apache.hadoop.ozone.om.response.OMVolumeCreateResponse;
|
import org.apache.hadoop.ozone.om.response.volume.OMVolumeCreateResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
.CreateBucketResponse;
|
.CreateBucketResponse;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
package org.apache.hadoop.ozone.om.request;
|
package org.apache.hadoop.ozone.om.request;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
@ -28,6 +29,10 @@
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
|
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
|
||||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.SetVolumePropertyRequest;
|
||||||
import org.apache.hadoop.util.Time;
|
import org.apache.hadoop.util.Time;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,21 +65,34 @@ public static void addVolumeAndBucketToDB(String volumeName,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add's volume creation entry to OM DB.
|
* Add volume creation entry to OM DB.
|
||||||
* @param volumeName
|
* @param volumeName
|
||||||
* @param omMetadataManager
|
* @param omMetadataManager
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public static void addVolumeToDB(String volumeName,
|
public static void addVolumeToDB(String volumeName,
|
||||||
OMMetadataManager omMetadataManager) throws Exception {
|
OMMetadataManager omMetadataManager) throws Exception {
|
||||||
|
addVolumeToDB(volumeName, UUID.randomUUID().toString(), omMetadataManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add volume creation entry to OM DB.
|
||||||
|
* @param volumeName
|
||||||
|
* @param ownerName
|
||||||
|
* @param omMetadataManager
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void addVolumeToDB(String volumeName, String ownerName,
|
||||||
|
OMMetadataManager omMetadataManager) throws Exception {
|
||||||
OmVolumeArgs omVolumeArgs =
|
OmVolumeArgs omVolumeArgs =
|
||||||
OmVolumeArgs.newBuilder().setCreationTime(Time.now())
|
OmVolumeArgs.newBuilder().setCreationTime(Time.now())
|
||||||
.setVolume(volumeName).setAdminName(UUID.randomUUID().toString())
|
.setVolume(volumeName).setAdminName(ownerName)
|
||||||
.setOwnerName(UUID.randomUUID().toString()).build();
|
.setOwnerName(ownerName).build();
|
||||||
omMetadataManager.getVolumeTable().put(
|
omMetadataManager.getVolumeTable().put(
|
||||||
omMetadataManager.getVolumeKey(volumeName), omVolumeArgs);
|
omMetadataManager.getVolumeKey(volumeName), omVolumeArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static OzoneManagerProtocolProtos.OMRequest createBucketRequest(
|
public static OzoneManagerProtocolProtos.OMRequest createBucketRequest(
|
||||||
String bucketName, String volumeName, boolean isVersionEnabled,
|
String bucketName, String volumeName, boolean isVersionEnabled,
|
||||||
OzoneManagerProtocolProtos.StorageTypeProto storageTypeProto) {
|
OzoneManagerProtocolProtos.StorageTypeProto storageTypeProto) {
|
||||||
|
@ -103,4 +121,56 @@ public static List< HddsProtos.KeyValue> getMetadataList() {
|
||||||
return metadataList;
|
return metadataList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add user to user table.
|
||||||
|
* @param volumeName
|
||||||
|
* @param ownerName
|
||||||
|
* @param omMetadataManager
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void addUserToDB(String volumeName, String ownerName,
|
||||||
|
OMMetadataManager omMetadataManager) throws Exception {
|
||||||
|
OzoneManagerProtocolProtos.VolumeList volumeList =
|
||||||
|
OzoneManagerProtocolProtos.VolumeList.newBuilder()
|
||||||
|
.addVolumeNames(volumeName).build();
|
||||||
|
omMetadataManager.getUserTable().put(
|
||||||
|
omMetadataManager.getUserKey(ownerName), volumeList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create OMRequest for set volume property request with owner set.
|
||||||
|
* @param volumeName
|
||||||
|
* @param newOwner
|
||||||
|
* @return OMRequest
|
||||||
|
*/
|
||||||
|
public static OMRequest createSetVolumePropertyRequest(String volumeName,
|
||||||
|
String newOwner) {
|
||||||
|
SetVolumePropertyRequest setVolumePropertyRequest =
|
||||||
|
SetVolumePropertyRequest.newBuilder().setVolumeName(volumeName)
|
||||||
|
.setOwnerName(newOwner).build();
|
||||||
|
|
||||||
|
return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
|
||||||
|
.setSetVolumePropertyRequest(setVolumePropertyRequest).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create OMRequest for set volume property request with quota set.
|
||||||
|
* @param volumeName
|
||||||
|
* @param quota
|
||||||
|
* @return OMRequest
|
||||||
|
*/
|
||||||
|
public static OMRequest createSetVolumePropertyRequest(String volumeName,
|
||||||
|
long quota) {
|
||||||
|
SetVolumePropertyRequest setVolumePropertyRequest =
|
||||||
|
SetVolumePropertyRequest.newBuilder().setVolumeName(volumeName)
|
||||||
|
.setQuotaInBytes(quota).build();
|
||||||
|
|
||||||
|
return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
|
||||||
|
.setSetVolumePropertyRequest(setVolumePropertyRequest).build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.hadoop.test.GenericTestUtils;
|
||||||
|
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.AuditMessage;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
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.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeInfo;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests create volume request.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeCreateRequest {
|
||||||
|
@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);
|
||||||
|
when(ozoneManager.getMaxUserVolumeCount()).thenReturn(10L);
|
||||||
|
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 = UUID.randomUUID().toString();
|
||||||
|
String adminName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = UUID.randomUUID().toString();
|
||||||
|
doPreExecute(volumeName, adminName, ownerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithZeroMaxUserVolumeCount()
|
||||||
|
throws Exception {
|
||||||
|
when(ozoneManager.getMaxUserVolumeCount()).thenReturn(0L);
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String adminName = "user1";
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
OMRequest originalRequest = createVolumeRequest(volumeName, adminName,
|
||||||
|
ownerName);
|
||||||
|
|
||||||
|
OMVolumeCreateRequest omVolumeCreateRequest =
|
||||||
|
new OMVolumeCreateRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
try {
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeCreateRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
} catch (IllegalArgumentException ex){
|
||||||
|
GenericTestUtils.assertExceptionContains("should be greater than zero",
|
||||||
|
ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheSuccess() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String adminName = "user1";
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
OMRequest originalRequest = createVolumeRequest(volumeName, adminName,
|
||||||
|
ownerName);
|
||||||
|
|
||||||
|
OMVolumeCreateRequest omVolumeCreateRequest =
|
||||||
|
new OMVolumeCreateRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
String volumeKey = omMetadataManager.getVolumeKey(volumeName);
|
||||||
|
String ownerKey = omMetadataManager.getUserKey(ownerName);
|
||||||
|
|
||||||
|
// As we have not still called validateAndUpdateCache, get() should
|
||||||
|
// return null.
|
||||||
|
|
||||||
|
Assert.assertNull(omMetadataManager.getVolumeTable().get(volumeKey));
|
||||||
|
Assert.assertNull(omMetadataManager.getUserTable().get(ownerKey));
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeCreateRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.OK,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
|
||||||
|
// Get volumeInfo from request.
|
||||||
|
VolumeInfo volumeInfo = omVolumeCreateRequest.getOmRequest()
|
||||||
|
.getCreateVolumeRequest().getVolumeInfo();
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs =
|
||||||
|
omMetadataManager.getVolumeTable().get(volumeKey);
|
||||||
|
// As request is valid volume table should not have entry.
|
||||||
|
Assert.assertNotNull(omVolumeArgs);
|
||||||
|
|
||||||
|
// Check data from table and request.
|
||||||
|
Assert.assertEquals(volumeInfo.getVolume(), omVolumeArgs.getVolume());
|
||||||
|
Assert.assertEquals(volumeInfo.getOwnerName(), omVolumeArgs.getOwnerName());
|
||||||
|
Assert.assertEquals(volumeInfo.getAdminName(), omVolumeArgs.getAdminName());
|
||||||
|
Assert.assertEquals(volumeInfo.getCreationTime(),
|
||||||
|
omVolumeArgs.getCreationTime());
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.VolumeList volumeList = omMetadataManager
|
||||||
|
.getUserTable().get(ownerKey);
|
||||||
|
Assert.assertNotNull(volumeList);
|
||||||
|
Assert.assertEquals(volumeName, volumeList.getVolumeNames(0));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithVolumeAlreadyExists()
|
||||||
|
throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String adminName = "user1";
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
TestOMRequestUtils.addVolumeToDB(volumeName, omMetadataManager);
|
||||||
|
|
||||||
|
OMRequest originalRequest = createVolumeRequest(volumeName, adminName,
|
||||||
|
ownerName);
|
||||||
|
|
||||||
|
OMVolumeCreateRequest omVolumeCreateRequest =
|
||||||
|
new OMVolumeCreateRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeCreateRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeCreateRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.VOLUME_ALREADY_EXISTS,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
// Check really if we have a volume with the specified volume name.
|
||||||
|
Assert.assertNotNull(omMetadataManager.getVolumeTable().get(
|
||||||
|
omMetadataManager.getVolumeKey(volumeName)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void doPreExecute(String volumeName,
|
||||||
|
String adminName, String ownerName) throws Exception {
|
||||||
|
|
||||||
|
OMRequest originalRequest = createVolumeRequest(volumeName, adminName,
|
||||||
|
ownerName);
|
||||||
|
|
||||||
|
OMVolumeCreateRequest omVolumeCreateRequest =
|
||||||
|
new OMVolumeCreateRequest(originalRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedRequest = omVolumeCreateRequest.preExecute(ozoneManager);
|
||||||
|
verifyRequest(modifiedRequest, originalRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify modifiedOmRequest and originalRequest.
|
||||||
|
* @param modifiedRequest
|
||||||
|
* @param originalRequest
|
||||||
|
*/
|
||||||
|
private void verifyRequest(OMRequest modifiedRequest,
|
||||||
|
OMRequest originalRequest) {
|
||||||
|
VolumeInfo original = originalRequest.getCreateVolumeRequest()
|
||||||
|
.getVolumeInfo();
|
||||||
|
VolumeInfo updated = modifiedRequest.getCreateVolumeRequest()
|
||||||
|
.getVolumeInfo();
|
||||||
|
|
||||||
|
Assert.assertEquals(original.getAdminName(), updated.getAdminName());
|
||||||
|
Assert.assertEquals(original.getVolume(), updated.getVolume());
|
||||||
|
Assert.assertEquals(original.getOwnerName(),
|
||||||
|
updated.getOwnerName());
|
||||||
|
Assert.assertNotEquals(original.getCreationTime(),
|
||||||
|
updated.getCreationTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create OMRequest for create volume.
|
||||||
|
* @param volumeName
|
||||||
|
* @param adminName
|
||||||
|
* @param ownerName
|
||||||
|
* @return OMRequest
|
||||||
|
*/
|
||||||
|
private OMRequest createVolumeRequest(String volumeName, String adminName,
|
||||||
|
String ownerName) {
|
||||||
|
VolumeInfo volumeInfo = VolumeInfo.newBuilder().setVolume(volumeName)
|
||||||
|
.setAdminName(adminName).setOwnerName(ownerName).build();
|
||||||
|
CreateVolumeRequest createVolumeRequest =
|
||||||
|
CreateVolumeRequest.newBuilder().setVolumeInfo(volumeInfo).build();
|
||||||
|
|
||||||
|
return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateVolume)
|
||||||
|
.setCreateVolumeRequest(createVolumeRequest).build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,222 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
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.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditMessage;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmBucketInfo;
|
||||||
|
import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheKey;
|
||||||
|
import org.apache.hadoop.utils.db.cache.CacheValue;
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
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.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.DeleteVolumeRequest;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests delete volume request.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeDeleteRequest {
|
||||||
|
@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 = 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.getMetadataManager()).thenReturn(omMetadataManager);
|
||||||
|
when(ozoneManager.getMetrics()).thenReturn(omMetrics);
|
||||||
|
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 = UUID.randomUUID().toString();
|
||||||
|
String ownerName = UUID.randomUUID().toString();
|
||||||
|
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||||
|
|
||||||
|
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||||
|
new OMVolumeDeleteRequest(originalRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedRequest = omVolumeDeleteRequest.preExecute(ozoneManager);
|
||||||
|
Assert.assertNotEquals(originalRequest, modifiedRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheSuccess() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||||
|
|
||||||
|
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||||
|
new OMVolumeDeleteRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeDeleteRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
// Add volume and user to DB
|
||||||
|
TestOMRequestUtils.addVolumeToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
TestOMRequestUtils.addUserToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
|
||||||
|
String volumeKey = omMetadataManager.getVolumeKey(volumeName);
|
||||||
|
String ownerKey = omMetadataManager.getUserKey(ownerName);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.assertNotNull(omMetadataManager.getVolumeTable().get(volumeKey));
|
||||||
|
Assert.assertNotNull(omMetadataManager.getUserTable().get(ownerKey));
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeDeleteRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.OK,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Assert.assertTrue(omMetadataManager.getUserTable().get(ownerKey)
|
||||||
|
.getVolumeNamesList().size() == 0);
|
||||||
|
// As now volume is deleted, table should not have those entries.
|
||||||
|
Assert.assertNull(omMetadataManager.getVolumeTable().get(volumeKey));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithVolumeNotFound()
|
||||||
|
throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||||
|
|
||||||
|
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||||
|
new OMVolumeDeleteRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeDeleteRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeDeleteRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithVolumeNotEmpty() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||||
|
|
||||||
|
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||||
|
new OMVolumeDeleteRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeDeleteRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
// Add some bucket to bucket table cache.
|
||||||
|
String bucketName = UUID.randomUUID().toString();
|
||||||
|
String bucketKey = omMetadataManager.getBucketKey(volumeName, bucketName);
|
||||||
|
|
||||||
|
OmBucketInfo omBucketInfo = OmBucketInfo.newBuilder()
|
||||||
|
.setVolumeName(volumeName).setBucketName(bucketName).build();
|
||||||
|
omMetadataManager.getBucketTable().addCacheEntry(new CacheKey<>(bucketKey),
|
||||||
|
new CacheValue<>(Optional.of(omBucketInfo), 1L));
|
||||||
|
|
||||||
|
// Add user and volume to DB.
|
||||||
|
TestOMRequestUtils.addUserToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
TestOMRequestUtils.addVolumeToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeDeleteRequest.validateAndUpdateCache(ozoneManager, 1L);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.VOLUME_NOT_EMPTY,
|
||||||
|
omResponse.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create OMRequest for delete volume.
|
||||||
|
* @param volumeName
|
||||||
|
* @param ownerName
|
||||||
|
* @return OMRequest
|
||||||
|
*/
|
||||||
|
private OMRequest deleteVolumeRequest(String volumeName,
|
||||||
|
String ownerName) {
|
||||||
|
DeleteVolumeRequest deleteVolumeRequest =
|
||||||
|
DeleteVolumeRequest.newBuilder().setVolumeName(volumeName)
|
||||||
|
.setOwner(ownerName).build();
|
||||||
|
|
||||||
|
return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.DeleteVolume)
|
||||||
|
.setDeleteVolumeRequest(deleteVolumeRequest).build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
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.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditMessage;
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
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.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests set volume property request.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeSetOwnerRequest {
|
||||||
|
@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);
|
||||||
|
when(ozoneManager.getMaxUserVolumeCount()).thenReturn(10L);
|
||||||
|
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 = UUID.randomUUID().toString();
|
||||||
|
String newOwner = "user1";
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName, newOwner);
|
||||||
|
|
||||||
|
OMVolumeSetQuotaRequest omVolumeSetQuotaRequest =
|
||||||
|
new OMVolumeSetQuotaRequest(originalRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedRequest = omVolumeSetQuotaRequest.preExecute(
|
||||||
|
ozoneManager);
|
||||||
|
Assert.assertNotEquals(modifiedRequest, originalRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheSuccess() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
TestOMRequestUtils.addUserToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
TestOMRequestUtils.addVolumeToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
|
||||||
|
String newOwner = "user2";
|
||||||
|
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName, newOwner);
|
||||||
|
|
||||||
|
OMVolumeSetOwnerRequest omVolumeSetOwnerRequest =
|
||||||
|
new OMVolumeSetOwnerRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeSetOwnerRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
String volumeKey = omMetadataManager.getVolumeKey(volumeName);
|
||||||
|
String ownerKey = omMetadataManager.getUserKey(ownerName);
|
||||||
|
String newOwnerKey = omMetadataManager.getUserKey(newOwner);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeSetOwnerRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getSetVolumePropertyResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.OK,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
|
||||||
|
String fromDBOwner = omMetadataManager
|
||||||
|
.getVolumeTable().get(volumeKey).getOwnerName();
|
||||||
|
Assert.assertEquals(newOwner, fromDBOwner);
|
||||||
|
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.VolumeList newOwnerVolumeList =
|
||||||
|
omMetadataManager.getUserTable().get(newOwnerKey);
|
||||||
|
|
||||||
|
Assert.assertNotNull(newOwnerVolumeList);
|
||||||
|
Assert.assertEquals(volumeName,
|
||||||
|
newOwnerVolumeList.getVolumeNamesList().get(0));
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.VolumeList oldOwnerVolumeList =
|
||||||
|
omMetadataManager.getUserTable().get(
|
||||||
|
omMetadataManager.getUserKey(ownerKey));
|
||||||
|
|
||||||
|
Assert.assertNotNull(oldOwnerVolumeList);
|
||||||
|
Assert.assertTrue(oldOwnerVolumeList.getVolumeNamesList().size() == 0);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithVolumeNotFound()
|
||||||
|
throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName,
|
||||||
|
ownerName);
|
||||||
|
|
||||||
|
OMVolumeSetOwnerRequest omVolumeSetOwnerRequest =
|
||||||
|
new OMVolumeSetOwnerRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeSetOwnerRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeSetOwnerRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidRequest() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
// create request with quota set.
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName,
|
||||||
|
100L);
|
||||||
|
|
||||||
|
OMVolumeSetOwnerRequest omVolumeSetOwnerRequest =
|
||||||
|
new OMVolumeSetOwnerRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeSetOwnerRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeSetOwnerRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.INVALID_REQUEST,
|
||||||
|
omResponse.getStatus());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,195 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditLogger;
|
||||||
|
import org.apache.hadoop.ozone.audit.AuditMessage;
|
||||||
|
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.om.request.TestOMRequestUtils;
|
||||||
|
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||||
|
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.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.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMRequest;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests set volume property request.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeSetQuotaRequest {
|
||||||
|
@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 = UUID.randomUUID().toString();
|
||||||
|
long quota = 100L;
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName, quota);
|
||||||
|
|
||||||
|
OMVolumeSetQuotaRequest omVolumeSetQuotaRequest =
|
||||||
|
new OMVolumeSetQuotaRequest(originalRequest);
|
||||||
|
|
||||||
|
OMRequest modifiedRequest = omVolumeSetQuotaRequest.preExecute(
|
||||||
|
ozoneManager);
|
||||||
|
Assert.assertNotEquals(modifiedRequest, originalRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheSuccess() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
long quotaSet = 100L;
|
||||||
|
|
||||||
|
TestOMRequestUtils.addUserToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
TestOMRequestUtils.addVolumeToDB(volumeName, ownerName, omMetadataManager);
|
||||||
|
|
||||||
|
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName, quotaSet);
|
||||||
|
|
||||||
|
OMVolumeSetQuotaRequest omVolumeSetQuotaRequest =
|
||||||
|
new OMVolumeSetQuotaRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeSetQuotaRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
String volumeKey = omMetadataManager.getVolumeKey(volumeName);
|
||||||
|
|
||||||
|
|
||||||
|
// Get Quota before validateAndUpdateCache.
|
||||||
|
OmVolumeArgs omVolumeArgs =
|
||||||
|
omMetadataManager.getVolumeTable().get(volumeKey);
|
||||||
|
// As request is valid volume table should not have entry.
|
||||||
|
Assert.assertNotNull(omVolumeArgs);
|
||||||
|
long quotaBeforeSet = omVolumeArgs.getQuotaInBytes();
|
||||||
|
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeSetQuotaRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getSetVolumePropertyResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.OK,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
|
||||||
|
long quotaAfterSet = omMetadataManager
|
||||||
|
.getVolumeTable().get(volumeKey).getQuotaInBytes();
|
||||||
|
Assert.assertEquals(quotaSet, quotaAfterSet);
|
||||||
|
Assert.assertNotEquals(quotaBeforeSet, quotaAfterSet);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testValidateAndUpdateCacheWithVolumeNotFound()
|
||||||
|
throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
String ownerName = "user1";
|
||||||
|
long quota = 100L;
|
||||||
|
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName, quota);
|
||||||
|
|
||||||
|
OMVolumeSetQuotaRequest omVolumeSetQuotaRequest =
|
||||||
|
new OMVolumeSetQuotaRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeSetQuotaRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeSetQuotaRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND,
|
||||||
|
omResponse.getStatus());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInvalidRequest() throws Exception {
|
||||||
|
String volumeName = UUID.randomUUID().toString();
|
||||||
|
|
||||||
|
// create request with owner set.
|
||||||
|
OMRequest originalRequest =
|
||||||
|
TestOMRequestUtils.createSetVolumePropertyRequest(volumeName,
|
||||||
|
"user1");
|
||||||
|
|
||||||
|
// Creating OMVolumeSetQuotaRequest with SetProperty request set with owner.
|
||||||
|
OMVolumeSetQuotaRequest omVolumeSetQuotaRequest =
|
||||||
|
new OMVolumeSetQuotaRequest(originalRequest);
|
||||||
|
|
||||||
|
omVolumeSetQuotaRequest.preExecute(ozoneManager);
|
||||||
|
|
||||||
|
OMClientResponse omClientResponse =
|
||||||
|
omVolumeSetQuotaRequest.validateAndUpdateCache(ozoneManager, 1);
|
||||||
|
|
||||||
|
OzoneManagerProtocolProtos.OMResponse omResponse =
|
||||||
|
omClientResponse.getOMResponse();
|
||||||
|
Assert.assertNotNull(omResponse.getCreateVolumeResponse());
|
||||||
|
Assert.assertEquals(OzoneManagerProtocolProtos.Status.INVALID_REQUEST,
|
||||||
|
omResponse.getStatus());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/**
|
||||||
|
* 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 contains test classes for volume requests.
|
||||||
|
*/
|
||||||
|
package org.apache.hadoop.ozone.om.request.volume;
|
|
@ -0,0 +1,125 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
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.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeList;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
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 java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class tests OMVolumeCreateResponse.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeCreateResponse {
|
||||||
|
|
||||||
|
@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 userName = "user1";
|
||||||
|
VolumeList volumeList = VolumeList.newBuilder()
|
||||||
|
.addVolumeNames(volumeName).build();
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateVolume)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setSuccess(true)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs = OmVolumeArgs.newBuilder()
|
||||||
|
.setOwnerName(userName).setAdminName(userName)
|
||||||
|
.setVolume(volumeName).setCreationTime(Time.now()).build();
|
||||||
|
OMVolumeCreateResponse omVolumeCreateResponse =
|
||||||
|
new OMVolumeCreateResponse(omVolumeArgs, volumeList, omResponse);
|
||||||
|
|
||||||
|
omVolumeCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
|
||||||
|
// Do manual commit and see whether addToBatch is successful or not.
|
||||||
|
omMetadataManager.getStore().commitBatchOperation(batchOperation);
|
||||||
|
|
||||||
|
Assert.assertEquals(omVolumeArgs,
|
||||||
|
omMetadataManager.getVolumeTable().get(
|
||||||
|
omMetadataManager.getVolumeKey(volumeName)));
|
||||||
|
|
||||||
|
Assert.assertEquals(volumeList,
|
||||||
|
omMetadataManager.getUserTable().get(
|
||||||
|
omMetadataManager.getUserKey(userName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToDBBatchNoOp() throws Exception {
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateVolume)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.VOLUME_ALREADY_EXISTS)
|
||||||
|
.setSuccess(false)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMVolumeCreateResponse omVolumeCreateResponse =
|
||||||
|
new OMVolumeCreateResponse(null, null, omResponse);
|
||||||
|
|
||||||
|
try {
|
||||||
|
omVolumeCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
Assert.assertTrue(omMetadataManager.countRowsInTable(
|
||||||
|
omMetadataManager.getVolumeTable()) == 0);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
fail("testAddToDBBatchFailure failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,130 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
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.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeList;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
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 java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class tests OMVolumeCreateResponse.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeDeleteResponse {
|
||||||
|
|
||||||
|
@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 userName = "user1";
|
||||||
|
VolumeList volumeList = VolumeList.newBuilder()
|
||||||
|
.addVolumeNames(volumeName).build();
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.DeleteVolume)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setSuccess(true)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs = OmVolumeArgs.newBuilder()
|
||||||
|
.setOwnerName(userName).setAdminName(userName)
|
||||||
|
.setVolume(volumeName).setCreationTime(Time.now()).build();
|
||||||
|
OMVolumeCreateResponse omVolumeCreateResponse =
|
||||||
|
new OMVolumeCreateResponse(omVolumeArgs, volumeList, omResponse);
|
||||||
|
|
||||||
|
// As we are deleting updated volume list should be empty.
|
||||||
|
VolumeList updatedVolumeList = VolumeList.newBuilder().build();
|
||||||
|
OMVolumeDeleteResponse omVolumeDeleteResponse =
|
||||||
|
new OMVolumeDeleteResponse(volumeName, userName, updatedVolumeList,
|
||||||
|
omResponse);
|
||||||
|
|
||||||
|
omVolumeCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
omVolumeDeleteResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
|
||||||
|
// Do manual commit and see whether addToBatch is successful or not.
|
||||||
|
omMetadataManager.getStore().commitBatchOperation(batchOperation);
|
||||||
|
|
||||||
|
Assert.assertNull(null,
|
||||||
|
omMetadataManager.getVolumeTable().get(
|
||||||
|
omMetadataManager.getVolumeKey(volumeName)));
|
||||||
|
|
||||||
|
Assert.assertEquals(null,
|
||||||
|
omMetadataManager.getUserTable().get(
|
||||||
|
omMetadataManager.getUserKey(userName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToDBBatchNoOp() throws Exception {
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.DeleteVolume)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND)
|
||||||
|
.setSuccess(false)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMVolumeDeleteResponse omVolumeDeleteResponse =
|
||||||
|
new OMVolumeDeleteResponse(null, null, null, omResponse);
|
||||||
|
|
||||||
|
try {
|
||||||
|
omVolumeDeleteResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
fail("testAddToDBBatchFailure failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
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.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.VolumeList;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
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 java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class tests OMVolumeCreateResponse.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeSetOwnerResponse {
|
||||||
|
|
||||||
|
@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 oldOwner = "user1";
|
||||||
|
VolumeList volumeList = VolumeList.newBuilder()
|
||||||
|
.addVolumeNames(volumeName).build();
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setSuccess(true)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs = OmVolumeArgs.newBuilder()
|
||||||
|
.setOwnerName(oldOwner).setAdminName(oldOwner)
|
||||||
|
.setVolume(volumeName).setCreationTime(Time.now()).build();
|
||||||
|
OMVolumeCreateResponse omVolumeCreateResponse =
|
||||||
|
new OMVolumeCreateResponse(omVolumeArgs, volumeList, omResponse);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String newOwner = "user2";
|
||||||
|
VolumeList newOwnerVolumeList = VolumeList.newBuilder()
|
||||||
|
.addVolumeNames(volumeName).build();
|
||||||
|
VolumeList oldOwnerVolumeList = VolumeList.newBuilder().build();
|
||||||
|
OmVolumeArgs newOwnerVolumeArgs = OmVolumeArgs.newBuilder()
|
||||||
|
.setOwnerName(newOwner).setAdminName(newOwner)
|
||||||
|
.setVolume(volumeName).setCreationTime(omVolumeArgs.getCreationTime())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMVolumeSetOwnerResponse omVolumeSetOwnerResponse =
|
||||||
|
new OMVolumeSetOwnerResponse(oldOwner, oldOwnerVolumeList,
|
||||||
|
newOwnerVolumeList, newOwnerVolumeArgs, omResponse);
|
||||||
|
|
||||||
|
omVolumeCreateResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
omVolumeSetOwnerResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
|
||||||
|
// Do manual commit and see whether addToBatch is successful or not.
|
||||||
|
omMetadataManager.getStore().commitBatchOperation(batchOperation);
|
||||||
|
|
||||||
|
|
||||||
|
Assert.assertEquals(newOwnerVolumeArgs,
|
||||||
|
omMetadataManager.getVolumeTable().get(
|
||||||
|
omMetadataManager.getVolumeKey(volumeName)));
|
||||||
|
|
||||||
|
Assert.assertEquals(volumeList,
|
||||||
|
omMetadataManager.getUserTable().get(
|
||||||
|
omMetadataManager.getUserKey(newOwner)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToDBBatchNoOp() throws Exception {
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND)
|
||||||
|
.setSuccess(false)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMVolumeSetOwnerResponse omVolumeSetOwnerResponse =
|
||||||
|
new OMVolumeSetOwnerResponse(null, null, null, null, omResponse);
|
||||||
|
|
||||||
|
try {
|
||||||
|
omVolumeSetOwnerResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
Assert.assertTrue(omMetadataManager.countRowsInTable(
|
||||||
|
omMetadataManager.getVolumeTable()) == 0);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
fail("testAddToDBBatchFailure failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
* 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.volume;
|
||||||
|
|
||||||
|
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
|
||||||
|
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.OmVolumeArgs;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.CreateVolumeResponse;
|
||||||
|
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||||
|
.OMResponse;
|
||||||
|
import org.apache.hadoop.util.Time;
|
||||||
|
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 java.io.IOException;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class tests OMVolumeCreateResponse.
|
||||||
|
*/
|
||||||
|
public class TestOMVolumeSetQuotaResponse {
|
||||||
|
|
||||||
|
@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 userName = "user1";
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.SetVolumeProperty)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.OK)
|
||||||
|
.setSuccess(true)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OmVolumeArgs omVolumeArgs = OmVolumeArgs.newBuilder()
|
||||||
|
.setOwnerName(userName).setAdminName(userName)
|
||||||
|
.setVolume(volumeName).setCreationTime(Time.now()).build();
|
||||||
|
OMVolumeSetQuotaResponse omVolumeSetQuotaResponse =
|
||||||
|
new OMVolumeSetQuotaResponse(omVolumeArgs, omResponse);
|
||||||
|
|
||||||
|
omVolumeSetQuotaResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
|
||||||
|
// Do manual commit and see whether addToBatch is successful or not.
|
||||||
|
omMetadataManager.getStore().commitBatchOperation(batchOperation);
|
||||||
|
|
||||||
|
Assert.assertEquals(omVolumeArgs,
|
||||||
|
omMetadataManager.getVolumeTable().get(
|
||||||
|
omMetadataManager.getVolumeKey(volumeName)));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAddToDBBatchNoOp() throws Exception {
|
||||||
|
|
||||||
|
OMResponse omResponse = OMResponse.newBuilder()
|
||||||
|
.setCmdType(OzoneManagerProtocolProtos.Type.CreateVolume)
|
||||||
|
.setStatus(OzoneManagerProtocolProtos.Status.VOLUME_NOT_FOUND)
|
||||||
|
.setSuccess(false)
|
||||||
|
.setCreateVolumeResponse(CreateVolumeResponse.getDefaultInstance())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
OMVolumeSetQuotaResponse omVolumeSetQuotaResponse =
|
||||||
|
new OMVolumeSetQuotaResponse(null, omResponse);
|
||||||
|
|
||||||
|
try {
|
||||||
|
omVolumeSetQuotaResponse.addToDBBatch(omMetadataManager, batchOperation);
|
||||||
|
Assert.assertTrue(omMetadataManager.countRowsInTable(
|
||||||
|
omMetadataManager.getVolumeTable()) == 0);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
fail("testAddToDBBatchFailure failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue