HDDS-1675. Cleanup Volume Request 2 phase old code. (#964)
This commit is contained in:
parent
303a7f8a39
commit
0541322c9a
@ -1,49 +0,0 @@
|
||||
/**
|
||||
* 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.helpers;
|
||||
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeList;
|
||||
|
||||
/**
|
||||
* OM response for delete volume request for a ozone volume.
|
||||
*/
|
||||
public class OmDeleteVolumeResponse {
|
||||
private String volume;
|
||||
private String owner;
|
||||
private VolumeList updatedVolumeList;
|
||||
|
||||
public OmDeleteVolumeResponse(String volume, String owner,
|
||||
VolumeList updatedVolumeList) {
|
||||
this.volume = volume;
|
||||
this.owner = owner;
|
||||
this.updatedVolumeList = updatedVolumeList;
|
||||
}
|
||||
|
||||
public String getVolume() {
|
||||
return volume;
|
||||
}
|
||||
|
||||
public String getOwner() {
|
||||
return owner;
|
||||
}
|
||||
|
||||
public VolumeList getUpdatedVolumeList() {
|
||||
return updatedVolumeList;
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/**
|
||||
* 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.helpers;
|
||||
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeList;
|
||||
|
||||
/**
|
||||
* OM response for owner change request for a ozone volume.
|
||||
*/
|
||||
public class OmVolumeOwnerChangeResponse {
|
||||
private VolumeList originalOwnerVolumeList;
|
||||
private VolumeList newOwnerVolumeList;
|
||||
private OmVolumeArgs newOwnerVolumeArgs;
|
||||
private String originalOwner;
|
||||
|
||||
public OmVolumeOwnerChangeResponse(VolumeList originalOwnerVolumeList,
|
||||
VolumeList newOwnerVolumeList, OmVolumeArgs newOwnerVolumeArgs,
|
||||
String originalOwner) {
|
||||
this.originalOwnerVolumeList = originalOwnerVolumeList;
|
||||
this.newOwnerVolumeList = newOwnerVolumeList;
|
||||
this.newOwnerVolumeArgs = newOwnerVolumeArgs;
|
||||
this.originalOwner = originalOwner;
|
||||
}
|
||||
|
||||
public String getOriginalOwner() {
|
||||
return originalOwner;
|
||||
}
|
||||
|
||||
public VolumeList getOriginalOwnerVolumeList() {
|
||||
return originalOwnerVolumeList;
|
||||
}
|
||||
|
||||
public VolumeList getNewOwnerVolumeList() {
|
||||
return newOwnerVolumeList;
|
||||
}
|
||||
|
||||
public OmVolumeArgs getNewOwnerVolumeArgs() {
|
||||
return newOwnerVolumeArgs;
|
||||
}
|
||||
}
|
@ -18,13 +18,8 @@
|
||||
|
||||
package org.apache.hadoop.ozone.om.protocol;
|
||||
|
||||
import org.apache.hadoop.ozone.om.helpers.OmDeleteVolumeResponse;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmKeyArgs;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmMultipartInfo;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeOwnerChangeResponse;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeList;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -54,76 +49,4 @@ public interface OzoneManagerHAProtocol {
|
||||
OmMultipartInfo applyInitiateMultipartUpload(OmKeyArgs omKeyArgs,
|
||||
String multipartUploadID) throws IOException;
|
||||
|
||||
/**
|
||||
* Start Create Volume Transaction.
|
||||
* @param omVolumeArgs
|
||||
* @return VolumeList
|
||||
* @throws IOException
|
||||
*/
|
||||
VolumeList startCreateVolume(OmVolumeArgs omVolumeArgs) throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Create Volume changes to OM DB.
|
||||
* @param omVolumeArgs
|
||||
* @param volumeList
|
||||
* @throws IOException
|
||||
*/
|
||||
void applyCreateVolume(OmVolumeArgs omVolumeArgs,
|
||||
VolumeList volumeList) throws IOException;
|
||||
|
||||
/**
|
||||
* Start setOwner Transaction.
|
||||
* @param volume
|
||||
* @param owner
|
||||
* @return OmVolumeOwnerChangeResponse
|
||||
* @throws IOException
|
||||
*/
|
||||
OmVolumeOwnerChangeResponse startSetOwner(String volume,
|
||||
String owner) throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Set Quota changes to OM DB.
|
||||
* @param oldOwner
|
||||
* @param oldOwnerVolumeList
|
||||
* @param newOwnerVolumeList
|
||||
* @param newOwnerVolumeArgs
|
||||
* @throws IOException
|
||||
*/
|
||||
void applySetOwner(String oldOwner, VolumeList oldOwnerVolumeList,
|
||||
VolumeList newOwnerVolumeList, OmVolumeArgs newOwnerVolumeArgs)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Start Set Quota Transaction.
|
||||
* @param volume
|
||||
* @param quota
|
||||
* @return OmVolumeArgs
|
||||
* @throws IOException
|
||||
*/
|
||||
OmVolumeArgs startSetQuota(String volume, long quota) throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Set Quota Changes to OM DB.
|
||||
* @param omVolumeArgs
|
||||
* @throws IOException
|
||||
*/
|
||||
void applySetQuota(OmVolumeArgs omVolumeArgs) throws IOException;
|
||||
|
||||
/**
|
||||
* Start Delete Volume Transaction.
|
||||
* @param volume
|
||||
* @return OmDeleteVolumeResponse
|
||||
* @throws IOException
|
||||
*/
|
||||
OmDeleteVolumeResponse startDeleteVolume(String volume) throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Delete Volume changes to OM DB.
|
||||
* @param volume
|
||||
* @param owner
|
||||
* @param newVolumeList
|
||||
* @throws IOException
|
||||
*/
|
||||
void applyDeleteVolume(String volume, String owner,
|
||||
VolumeList newVolumeList) throws IOException;
|
||||
}
|
||||
|
@ -307,7 +307,6 @@ message UserInfo {
|
||||
*/
|
||||
message CreateVolumeRequest {
|
||||
required VolumeInfo volumeInfo = 1;
|
||||
optional VolumeList volumeList = 2;
|
||||
}
|
||||
|
||||
message CreateVolumeResponse {
|
||||
@ -325,10 +324,6 @@ message SetVolumePropertyRequest {
|
||||
required string volumeName = 1;
|
||||
optional string ownerName = 2;
|
||||
optional uint64 quotaInBytes = 3;
|
||||
optional string originalOwner = 4;
|
||||
optional VolumeList oldOwnerVolumeList = 5;
|
||||
optional VolumeList newOwnerVolumeList = 6;
|
||||
optional VolumeInfo volumeInfo = 7;
|
||||
}
|
||||
|
||||
message SetVolumePropertyResponse {
|
||||
@ -365,8 +360,6 @@ message InfoVolumeResponse {
|
||||
*/
|
||||
message DeleteVolumeRequest {
|
||||
required string volumeName = 1;
|
||||
optional string owner = 2;
|
||||
optional VolumeList volumeList = 3;
|
||||
}
|
||||
|
||||
message DeleteVolumeResponse {
|
||||
|
@ -87,11 +87,11 @@ public void testVolumeOps() throws IOException {
|
||||
ozoneManager, "volumeManager");
|
||||
VolumeManager mockVm = Mockito.spy(volumeManager);
|
||||
|
||||
Mockito.doReturn(null).when(mockVm).createVolume(null);
|
||||
Mockito.doReturn(null).when(mockVm).deleteVolume(null);
|
||||
Mockito.doNothing().when(mockVm).createVolume(null);
|
||||
Mockito.doNothing().when(mockVm).deleteVolume(null);
|
||||
Mockito.doReturn(null).when(mockVm).getVolumeInfo(null);
|
||||
Mockito.doReturn(true).when(mockVm).checkVolumeAccess(null, null);
|
||||
Mockito.doReturn(null).when(mockVm).setOwner(null, null);
|
||||
Mockito.doNothing().when(mockVm).setOwner(null, null);
|
||||
Mockito.doReturn(null).when(mockVm).listVolumes(null, null, null, 0);
|
||||
|
||||
HddsWhiteboxTestUtils.setInternalState(
|
||||
|
@ -65,8 +65,6 @@ public class BucketManagerImpl implements BucketManager {
|
||||
private final OMMetadataManager metadataManager;
|
||||
private final KeyProviderCryptoExtension kmsProvider;
|
||||
|
||||
private final boolean isRatisEnabled;
|
||||
|
||||
/**
|
||||
* Constructs BucketManager.
|
||||
*
|
||||
@ -85,7 +83,6 @@ public BucketManagerImpl(OMMetadataManager metadataManager,
|
||||
KeyProviderCryptoExtension kmsProvider, boolean isRatisEnabled) {
|
||||
this.metadataManager = metadataManager;
|
||||
this.kmsProvider = kmsProvider;
|
||||
this.isRatisEnabled = isRatisEnabled;
|
||||
}
|
||||
|
||||
KeyProviderCryptoExtension getKMSProvider() {
|
||||
|
@ -77,15 +77,11 @@
|
||||
import org.apache.hadoop.ozone.OzoneIllegalArgumentException;
|
||||
import org.apache.hadoop.ozone.OzoneSecurityUtil;
|
||||
import org.apache.hadoop.ozone.om.ha.OMFailoverProxyProvider;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmDeleteVolumeResponse;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeOwnerChangeResponse;
|
||||
import org.apache.hadoop.ozone.om.helpers.S3SecretValue;
|
||||
import org.apache.hadoop.ozone.om.protocol.OzoneManagerServerProtocol;
|
||||
import org.apache.hadoop.ozone.om.snapshot.OzoneManagerSnapshotProvider;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.KeyArgs;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeList;
|
||||
import org.apache.hadoop.ozone.security.OzoneSecurityException;
|
||||
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
|
||||
import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
|
||||
@ -1721,79 +1717,6 @@ public void createVolume(OmVolumeArgs args) throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolumeList startCreateVolume(OmVolumeArgs args) throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
if(isAclEnabled) {
|
||||
checkAcls(ResourceType.VOLUME, StoreType.OZONE, ACLType.CREATE,
|
||||
args.getVolume(), null, null);
|
||||
}
|
||||
VolumeList volumeList = volumeManager.createVolume(args);
|
||||
return volumeList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyCreateVolume(OmVolumeArgs omVolumeArgs,
|
||||
VolumeList volumeList) throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
volumeManager.applyCreateVolume(omVolumeArgs, volumeList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OmVolumeOwnerChangeResponse startSetOwner(String volume,
|
||||
String owner) throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
if (isAclEnabled) {
|
||||
checkAcls(ResourceType.VOLUME, StoreType.OZONE, ACLType.WRITE_ACL, volume,
|
||||
null, null);
|
||||
}
|
||||
return volumeManager.setOwner(volume, owner);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySetOwner(String oldOwner, VolumeList oldOwnerVolumeList,
|
||||
VolumeList newOwnerVolumeList, OmVolumeArgs newOwnerVolumeArgs)
|
||||
throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
volumeManager.applySetOwner(oldOwner, oldOwnerVolumeList,
|
||||
newOwnerVolumeList, newOwnerVolumeArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OmVolumeArgs startSetQuota(String volume, long quota)
|
||||
throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
if (isAclEnabled) {
|
||||
checkAcls(ResourceType.VOLUME, StoreType.OZONE, ACLType.WRITE_ACL, volume,
|
||||
null, null);
|
||||
}
|
||||
return volumeManager.setQuota(volume, quota);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySetQuota(OmVolumeArgs omVolumeArgs) throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
volumeManager.applySetQuota(omVolumeArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public OmDeleteVolumeResponse startDeleteVolume(String volume)
|
||||
throws IOException {
|
||||
if(isAclEnabled) {
|
||||
checkAcls(ResourceType.VOLUME, StoreType.OZONE, ACLType.DELETE, volume,
|
||||
null, null);
|
||||
}
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
return volumeManager.deleteVolume(volume);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyDeleteVolume(String volume, String owner,
|
||||
VolumeList newVolumeList) throws IOException {
|
||||
// TODO: Need to add metrics and Audit log for HA requests
|
||||
volumeManager.applyDeleteVolume(volume, owner, newVolumeList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if current caller has acl permissions.
|
||||
*
|
||||
|
@ -55,7 +55,6 @@ public class S3BucketManagerImpl implements S3BucketManager {
|
||||
private final OMMetadataManager omMetadataManager;
|
||||
private final VolumeManager volumeManager;
|
||||
private final BucketManager bucketManager;
|
||||
private final boolean isRatisEnabled;
|
||||
|
||||
/**
|
||||
* Construct an S3 Bucket Manager Object.
|
||||
@ -72,9 +71,6 @@ public S3BucketManagerImpl(
|
||||
this.omMetadataManager = omMetadataManager;
|
||||
this.volumeManager = volumeManager;
|
||||
this.bucketManager = bucketManager;
|
||||
isRatisEnabled = configuration.getBoolean(
|
||||
OMConfigKeys.OZONE_OM_RATIS_ENABLE_KEY,
|
||||
OMConfigKeys.OZONE_OM_RATIS_ENABLE_DEFAULT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -176,12 +172,9 @@ public boolean createOzoneVolumeIfNeeded(String userName)
|
||||
}
|
||||
|
||||
OmVolumeArgs args = builder.build();
|
||||
if (isRatisEnabled) {
|
||||
// When ratis is enabled we need to call apply also.
|
||||
volumeManager.applyCreateVolume(args, volumeManager.createVolume(args));
|
||||
} else {
|
||||
|
||||
volumeManager.createVolume(args);
|
||||
}
|
||||
|
||||
} catch (OMException exp) {
|
||||
newVolumeCreate = false;
|
||||
if (exp.getResult().compareTo(VOLUME_ALREADY_EXISTS) == 0) {
|
||||
|
@ -16,13 +16,9 @@
|
||||
*/
|
||||
package org.apache.hadoop.ozone.om;
|
||||
|
||||
import org.apache.hadoop.ozone.om.helpers.OmDeleteVolumeResponse;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeOwnerChangeResponse;
|
||||
import org.apache.hadoop.ozone.protocol.proto
|
||||
.OzoneManagerProtocolProtos.OzoneAclInfo;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeList;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
@ -36,18 +32,9 @@ public interface VolumeManager extends IOzoneAcl {
|
||||
* Create a new volume.
|
||||
* @param args - Volume args to create a volume
|
||||
*/
|
||||
VolumeList createVolume(OmVolumeArgs args)
|
||||
void createVolume(OmVolumeArgs args)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Create Volume changes to OM DB.
|
||||
* @param omVolumeArgs
|
||||
* @param volumeList
|
||||
* @throws IOException
|
||||
*/
|
||||
void applyCreateVolume(OmVolumeArgs omVolumeArgs,
|
||||
VolumeList volumeList) throws IOException;
|
||||
|
||||
/**
|
||||
* Changes the owner of a volume.
|
||||
*
|
||||
@ -55,19 +42,7 @@ void applyCreateVolume(OmVolumeArgs omVolumeArgs,
|
||||
* @param owner - Name of the owner.
|
||||
* @throws IOException
|
||||
*/
|
||||
OmVolumeOwnerChangeResponse setOwner(String volume, String owner)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Set Owner changes to OM DB.
|
||||
* @param oldOwner
|
||||
* @param oldOwnerVolumeList
|
||||
* @param newOwnerVolumeList
|
||||
* @param newOwnerVolumeArgs
|
||||
* @throws IOException
|
||||
*/
|
||||
void applySetOwner(String oldOwner, VolumeList oldOwnerVolumeList,
|
||||
VolumeList newOwnerVolumeList, OmVolumeArgs newOwnerVolumeArgs)
|
||||
void setOwner(String volume, String owner)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
@ -77,14 +52,7 @@ void applySetOwner(String oldOwner, VolumeList oldOwnerVolumeList,
|
||||
* @param quota - Quota in bytes.
|
||||
* @throws IOException
|
||||
*/
|
||||
OmVolumeArgs setQuota(String volume, long quota) throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Set Quota changes to OM DB.
|
||||
* @param omVolumeArgs
|
||||
* @throws IOException
|
||||
*/
|
||||
void applySetQuota(OmVolumeArgs omVolumeArgs) throws IOException;
|
||||
void setQuota(String volume, long quota) throws IOException;
|
||||
|
||||
/**
|
||||
* Gets the volume information.
|
||||
@ -100,17 +68,7 @@ void applySetOwner(String oldOwner, VolumeList oldOwnerVolumeList,
|
||||
* @param volume - Name of the volume.
|
||||
* @throws IOException
|
||||
*/
|
||||
OmDeleteVolumeResponse deleteVolume(String volume) throws IOException;
|
||||
|
||||
/**
|
||||
* Apply Delete Volume changes to OM DB.
|
||||
* @param volume
|
||||
* @param owner
|
||||
* @param newVolumeList
|
||||
* @throws IOException
|
||||
*/
|
||||
void applyDeleteVolume(String volume, String owner,
|
||||
VolumeList newVolumeList) throws IOException;
|
||||
void deleteVolume(String volume) throws IOException;
|
||||
|
||||
/**
|
||||
* Checks if the specified user with a role can access this volume.
|
||||
|
@ -27,9 +27,7 @@
|
||||
import org.apache.hadoop.ozone.OzoneAcl;
|
||||
import org.apache.hadoop.ozone.OzoneConfigKeys;
|
||||
import org.apache.hadoop.ozone.om.exceptions.OMException;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmDeleteVolumeResponse;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeOwnerChangeResponse;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneAclInfo;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeList;
|
||||
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
|
||||
@ -57,9 +55,9 @@ public class VolumeManagerImpl implements VolumeManager {
|
||||
|
||||
private final OMMetadataManager metadataManager;
|
||||
private final int maxUserVolumeCount;
|
||||
private final boolean isRatisEnabled;
|
||||
private final boolean aclEnabled;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param conf - Ozone configuration.
|
||||
@ -70,9 +68,6 @@ public VolumeManagerImpl(OMMetadataManager metadataManager,
|
||||
this.metadataManager = metadataManager;
|
||||
this.maxUserVolumeCount = conf.getInt(OZONE_OM_USER_MAX_VOLUME,
|
||||
OZONE_OM_USER_MAX_VOLUME_DEFAULT);
|
||||
isRatisEnabled = conf.getBoolean(
|
||||
OMConfigKeys.OZONE_OM_RATIS_ENABLE_KEY,
|
||||
OMConfigKeys.OZONE_OM_RATIS_ENABLE_DEFAULT);
|
||||
aclEnabled = conf.getBoolean(OzoneConfigKeys.OZONE_ACL_ENABLED,
|
||||
OzoneConfigKeys.OZONE_ACL_ENABLED_DEFAULT);
|
||||
}
|
||||
@ -125,10 +120,9 @@ private VolumeList delVolumeFromOwnerList(String volume, String owner)
|
||||
/**
|
||||
* Creates a volume.
|
||||
* @param omVolumeArgs - OmVolumeArgs.
|
||||
* @return VolumeList
|
||||
*/
|
||||
@Override
|
||||
public VolumeList createVolume(OmVolumeArgs omVolumeArgs) throws IOException {
|
||||
public void createVolume(OmVolumeArgs omVolumeArgs) throws IOException {
|
||||
Preconditions.checkNotNull(omVolumeArgs);
|
||||
|
||||
boolean acquiredUserLock = false;
|
||||
@ -156,13 +150,12 @@ public VolumeList createVolume(OmVolumeArgs omVolumeArgs) throws IOException {
|
||||
// Set creation time
|
||||
omVolumeArgs.setCreationTime(System.currentTimeMillis());
|
||||
|
||||
if (!isRatisEnabled) {
|
||||
|
||||
createVolumeCommitToDB(omVolumeArgs, volumeList, dbVolumeKey,
|
||||
dbUserKey);
|
||||
}
|
||||
|
||||
LOG.debug("created volume:{} user:{}", omVolumeArgs.getVolume(),
|
||||
omVolumeArgs.getOwnerName());
|
||||
return volumeList;
|
||||
} catch (IOException ex) {
|
||||
if (!(ex instanceof OMException)) {
|
||||
LOG.error("Volume creation failed for user:{} volume:{}",
|
||||
@ -179,22 +172,6 @@ public VolumeList createVolume(OmVolumeArgs omVolumeArgs) throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyCreateVolume(OmVolumeArgs omVolumeArgs,
|
||||
VolumeList volumeList) throws IOException {
|
||||
// Do we need to hold lock in apply Transactions requests?
|
||||
String dbVolumeKey = metadataManager.getVolumeKey(omVolumeArgs.getVolume());
|
||||
String dbUserKey = metadataManager.getUserKey(omVolumeArgs.getOwnerName());
|
||||
try {
|
||||
createVolumeCommitToDB(omVolumeArgs, volumeList, dbVolumeKey, dbUserKey);
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Volume creation failed for user:{} volume:{}",
|
||||
omVolumeArgs.getOwnerName(), omVolumeArgs.getVolume(), ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void createVolumeCommitToDB(OmVolumeArgs omVolumeArgs,
|
||||
VolumeList volumeList, String dbVolumeKey, String dbUserKey)
|
||||
throws IOException {
|
||||
@ -220,7 +197,7 @@ private void createVolumeCommitToDB(OmVolumeArgs omVolumeArgs,
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public OmVolumeOwnerChangeResponse setOwner(String volume, String owner)
|
||||
public void setOwner(String volume, String owner)
|
||||
throws IOException {
|
||||
Preconditions.checkNotNull(volume);
|
||||
Preconditions.checkNotNull(owner);
|
||||
@ -252,12 +229,8 @@ public OmVolumeOwnerChangeResponse setOwner(String volume, String owner)
|
||||
VolumeList newOwnerVolumeList = addVolumeToOwnerList(volume, newOwner);
|
||||
|
||||
volumeArgs.setOwnerName(owner);
|
||||
if (!isRatisEnabled) {
|
||||
setOwnerCommitToDB(oldOwnerVolumeList, newOwnerVolumeList,
|
||||
volumeArgs, owner);
|
||||
}
|
||||
return new OmVolumeOwnerChangeResponse(oldOwnerVolumeList,
|
||||
newOwnerVolumeList, volumeArgs, originalOwner);
|
||||
} catch (IOException ex) {
|
||||
if (!(ex instanceof OMException)) {
|
||||
LOG.error("Changing volume ownership failed for user:{} volume:{}",
|
||||
@ -272,21 +245,6 @@ public OmVolumeOwnerChangeResponse setOwner(String volume, String owner)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySetOwner(String oldOwner, VolumeList oldOwnerVolumeList,
|
||||
VolumeList newOwnerVolumeList, OmVolumeArgs newOwnerVolumeArgs)
|
||||
throws IOException {
|
||||
try {
|
||||
setOwnerCommitToDB(oldOwnerVolumeList, newOwnerVolumeList,
|
||||
newOwnerVolumeArgs, oldOwner);
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Changing volume ownership failed for user:{} volume:{}",
|
||||
newOwnerVolumeArgs.getOwnerName(), newOwnerVolumeArgs.getVolume(),
|
||||
ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void setOwnerCommitToDB(VolumeList oldOwnerVolumeList,
|
||||
VolumeList newOwnerVolumeList, OmVolumeArgs newOwnerVolumeArgs,
|
||||
@ -318,11 +276,10 @@ private void setOwnerCommitToDB(VolumeList oldOwnerVolumeList,
|
||||
* @param volume - Name of the volume.
|
||||
* @param quota - Quota in bytes.
|
||||
*
|
||||
* @return OmVolumeArgs
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public OmVolumeArgs setQuota(String volume, long quota) throws IOException {
|
||||
public void setQuota(String volume, long quota) throws IOException {
|
||||
Preconditions.checkNotNull(volume);
|
||||
metadataManager.getLock().acquireLock(VOLUME_LOCK, volume);
|
||||
try {
|
||||
@ -336,13 +293,9 @@ public OmVolumeArgs setQuota(String volume, long quota) throws IOException {
|
||||
|
||||
Preconditions.checkState(volume.equals(volumeArgs.getVolume()));
|
||||
|
||||
|
||||
volumeArgs.setQuotaInBytes(quota);
|
||||
|
||||
if (!isRatisEnabled) {
|
||||
metadataManager.getVolumeTable().put(dbVolumeKey, volumeArgs);
|
||||
}
|
||||
return volumeArgs;
|
||||
} catch (IOException ex) {
|
||||
if (!(ex instanceof OMException)) {
|
||||
LOG.error("Changing volume quota failed for volume:{} quota:{}", volume,
|
||||
@ -354,19 +307,6 @@ public OmVolumeArgs setQuota(String volume, long quota) throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applySetQuota(OmVolumeArgs omVolumeArgs) throws IOException {
|
||||
try {
|
||||
String dbVolumeKey = metadataManager.getVolumeKey(
|
||||
omVolumeArgs.getVolume());
|
||||
metadataManager.getVolumeTable().put(dbVolumeKey, omVolumeArgs);
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Changing volume quota failed for volume:{} quota:{}",
|
||||
omVolumeArgs.getVolume(), omVolumeArgs.getQuotaInBytes(), ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the volume information.
|
||||
* @param volume - Volume name.
|
||||
@ -402,12 +342,10 @@ public OmVolumeArgs getVolumeInfo(String volume) throws IOException {
|
||||
* Deletes an existing empty volume.
|
||||
*
|
||||
* @param volume - Name of the volume.
|
||||
*
|
||||
* @return OmDeleteVolumeResponse
|
||||
* @throws IOException
|
||||
*/
|
||||
@Override
|
||||
public OmDeleteVolumeResponse deleteVolume(String volume) throws IOException {
|
||||
public void deleteVolume(String volume) throws IOException {
|
||||
Preconditions.checkNotNull(volume);
|
||||
String owner = null;
|
||||
boolean acquiredUserLock = false;
|
||||
@ -435,11 +373,8 @@ public OmDeleteVolumeResponse deleteVolume(String volume) throws IOException {
|
||||
VolumeList newVolumeList = delVolumeFromOwnerList(volume,
|
||||
volumeArgs.getOwnerName());
|
||||
|
||||
if (!isRatisEnabled) {
|
||||
deleteVolumeCommitToDB(newVolumeList,
|
||||
volume, owner);
|
||||
}
|
||||
return new OmDeleteVolumeResponse(volume, owner, newVolumeList);
|
||||
|
||||
deleteVolumeCommitToDB(newVolumeList, volume, owner);
|
||||
} catch (IOException ex) {
|
||||
if (!(ex instanceof OMException)) {
|
||||
LOG.error("Delete volume failed for volume:{}", volume, ex);
|
||||
@ -454,17 +389,6 @@ public OmDeleteVolumeResponse deleteVolume(String volume) throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyDeleteVolume(String volume, String owner,
|
||||
VolumeList newVolumeList) throws IOException {
|
||||
try {
|
||||
deleteVolumeCommitToDB(newVolumeList, volume, owner);
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Delete volume failed for volume:{}", volume,
|
||||
ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteVolumeCommitToDB(VolumeList newVolumeList,
|
||||
String volume, String owner) throws IOException {
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
package org.apache.hadoop.ozone.protocolPB;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.OMRequest;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
@ -29,15 +27,6 @@
|
||||
*/
|
||||
public interface OzoneManagerHARequestHandler extends RequestHandler {
|
||||
|
||||
/**
|
||||
* Handle start Transaction Requests from OzoneManager StateMachine.
|
||||
* @param omRequest
|
||||
* @return OMRequest - New OM Request which will be applied during apply
|
||||
* Transaction
|
||||
* @throws IOException
|
||||
*/
|
||||
OMRequest handleStartTransaction(OMRequest omRequest) throws IOException;
|
||||
|
||||
/**
|
||||
* Handle Apply Transaction Requests from OzoneManager StateMachine.
|
||||
* @param omRequest
|
||||
|
@ -17,41 +17,19 @@
|
||||
|
||||
package org.apache.hadoop.ozone.protocolPB;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.hadoop.ozone.om.OzoneManager;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmDeleteVolumeResponse;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeArgs;
|
||||
import org.apache.hadoop.ozone.om.helpers.OmVolumeOwnerChangeResponse;
|
||||
import org.apache.hadoop.ozone.om.ratis.OzoneManagerDoubleBuffer;
|
||||
import org.apache.hadoop.ozone.om.ratis.utils.OzoneManagerRatisUtils;
|
||||
import org.apache.hadoop.ozone.om.request.OMClientRequest;
|
||||
import org.apache.hadoop.ozone.om.response.OMClientResponse;
|
||||
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
|
||||
.CreateVolumeResponse;
|
||||
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.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.SetVolumePropertyRequest;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.SetVolumePropertyResponse;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.Status;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.Type;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeInfo;
|
||||
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
|
||||
.VolumeList;
|
||||
|
||||
/**
|
||||
* Command Handler for OM requests. OM State Machine calls this handler for
|
||||
@ -68,28 +46,6 @@ public OzoneManagerHARequestHandlerImpl(OzoneManager om,
|
||||
this.ozoneManagerDoubleBuffer = ozoneManagerDoubleBuffer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OMRequest handleStartTransaction(OMRequest omRequest)
|
||||
throws IOException {
|
||||
LOG.debug("Received OMRequest: {}, ", omRequest);
|
||||
Type cmdType = omRequest.getCmdType();
|
||||
OMRequest newOmRequest = null;
|
||||
switch (cmdType) {
|
||||
case CreateVolume:
|
||||
newOmRequest = handleCreateVolumeStart(omRequest);
|
||||
break;
|
||||
case SetVolumeProperty:
|
||||
newOmRequest = handleSetVolumePropertyStart(omRequest);
|
||||
break;
|
||||
case DeleteVolume:
|
||||
newOmRequest = handleDeleteVolumeStart(omRequest);
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Unrecognized Command Type:" + cmdType);
|
||||
}
|
||||
return newOmRequest;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public OMResponse handleApplyTransaction(OMRequest omRequest,
|
||||
@ -135,128 +91,4 @@ public OMResponse handleApplyTransaction(OMRequest omRequest,
|
||||
return handle(omRequest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private OMRequest handleCreateVolumeStart(OMRequest omRequest)
|
||||
throws IOException {
|
||||
VolumeInfo volumeInfo = omRequest.getCreateVolumeRequest().getVolumeInfo();
|
||||
OzoneManagerProtocolProtos.VolumeList volumeList =
|
||||
getOzoneManager().startCreateVolume(
|
||||
OmVolumeArgs.getFromProtobuf(volumeInfo));
|
||||
|
||||
CreateVolumeRequest createVolumeRequest =
|
||||
CreateVolumeRequest.newBuilder().setVolumeInfo(volumeInfo)
|
||||
.setVolumeList(volumeList).build();
|
||||
return omRequest.toBuilder().setCreateVolumeRequest(createVolumeRequest)
|
||||
.build();
|
||||
}
|
||||
|
||||
private CreateVolumeResponse handleCreateVolumeApply(OMRequest omRequest)
|
||||
throws IOException {
|
||||
OzoneManagerProtocolProtos.VolumeInfo volumeInfo =
|
||||
omRequest.getCreateVolumeRequest().getVolumeInfo();
|
||||
VolumeList volumeList =
|
||||
omRequest.getCreateVolumeRequest().getVolumeList();
|
||||
getOzoneManager().applyCreateVolume(
|
||||
OmVolumeArgs.getFromProtobuf(volumeInfo),
|
||||
volumeList);
|
||||
return CreateVolumeResponse.newBuilder().build();
|
||||
}
|
||||
|
||||
private OMRequest handleSetVolumePropertyStart(OMRequest omRequest)
|
||||
throws IOException {
|
||||
SetVolumePropertyRequest setVolumePropertyRequest =
|
||||
omRequest.getSetVolumePropertyRequest();
|
||||
String volume = setVolumePropertyRequest.getVolumeName();
|
||||
OMRequest newOmRequest = null;
|
||||
if (setVolumePropertyRequest.hasQuotaInBytes()) {
|
||||
long quota = setVolumePropertyRequest.getQuotaInBytes();
|
||||
OmVolumeArgs omVolumeArgs =
|
||||
getOzoneManager().startSetQuota(volume, quota);
|
||||
SetVolumePropertyRequest newSetVolumePropertyRequest =
|
||||
SetVolumePropertyRequest.newBuilder().setVolumeName(volume)
|
||||
.setVolumeInfo(omVolumeArgs.getProtobuf()).build();
|
||||
newOmRequest =
|
||||
omRequest.toBuilder().setSetVolumePropertyRequest(
|
||||
newSetVolumePropertyRequest).build();
|
||||
} else {
|
||||
String owner = setVolumePropertyRequest.getOwnerName();
|
||||
OmVolumeOwnerChangeResponse omVolumeOwnerChangeResponse =
|
||||
getOzoneManager().startSetOwner(volume, owner);
|
||||
// If volumeLists become large and as ratis writes the request to disk we
|
||||
// might take more space if the lists become very big in size. We might
|
||||
// need to revisit this if it becomes problem
|
||||
SetVolumePropertyRequest newSetVolumePropertyRequest =
|
||||
SetVolumePropertyRequest.newBuilder().setVolumeName(volume)
|
||||
.setOwnerName(owner)
|
||||
.setOriginalOwner(omVolumeOwnerChangeResponse.getOriginalOwner())
|
||||
.setNewOwnerVolumeList(
|
||||
omVolumeOwnerChangeResponse.getNewOwnerVolumeList())
|
||||
.setOldOwnerVolumeList(
|
||||
omVolumeOwnerChangeResponse.getOriginalOwnerVolumeList())
|
||||
.setVolumeInfo(
|
||||
omVolumeOwnerChangeResponse.getNewOwnerVolumeArgs()
|
||||
.getProtobuf()).build();
|
||||
newOmRequest =
|
||||
omRequest.toBuilder().setSetVolumePropertyRequest(
|
||||
newSetVolumePropertyRequest).build();
|
||||
}
|
||||
return newOmRequest;
|
||||
}
|
||||
|
||||
|
||||
private SetVolumePropertyResponse handleSetVolumePropertyApply(
|
||||
OMRequest omRequest) throws IOException {
|
||||
SetVolumePropertyRequest setVolumePropertyRequest =
|
||||
omRequest.getSetVolumePropertyRequest();
|
||||
|
||||
if (setVolumePropertyRequest.hasQuotaInBytes()) {
|
||||
getOzoneManager().applySetQuota(
|
||||
OmVolumeArgs.getFromProtobuf(
|
||||
setVolumePropertyRequest.getVolumeInfo()));
|
||||
} else {
|
||||
getOzoneManager().applySetOwner(
|
||||
setVolumePropertyRequest.getOriginalOwner(),
|
||||
setVolumePropertyRequest.getOldOwnerVolumeList(),
|
||||
setVolumePropertyRequest.getNewOwnerVolumeList(),
|
||||
OmVolumeArgs.getFromProtobuf(
|
||||
setVolumePropertyRequest.getVolumeInfo()));
|
||||
}
|
||||
return SetVolumePropertyResponse.newBuilder().build();
|
||||
}
|
||||
|
||||
private OMRequest handleDeleteVolumeStart(OMRequest omRequest)
|
||||
throws IOException {
|
||||
DeleteVolumeRequest deleteVolumeRequest =
|
||||
omRequest.getDeleteVolumeRequest();
|
||||
|
||||
String volume = deleteVolumeRequest.getVolumeName();
|
||||
|
||||
OmDeleteVolumeResponse omDeleteVolumeResponse =
|
||||
getOzoneManager().startDeleteVolume(volume);
|
||||
|
||||
DeleteVolumeRequest newDeleteVolumeRequest =
|
||||
DeleteVolumeRequest.newBuilder().setVolumeList(
|
||||
omDeleteVolumeResponse.getUpdatedVolumeList())
|
||||
.setVolumeName(omDeleteVolumeResponse.getVolume())
|
||||
.setOwner(omDeleteVolumeResponse.getOwner()).build();
|
||||
|
||||
return omRequest.toBuilder().setDeleteVolumeRequest(
|
||||
newDeleteVolumeRequest).build();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private DeleteVolumeResponse handleDeleteVolumeApply(OMRequest omRequest)
|
||||
throws IOException {
|
||||
|
||||
DeleteVolumeRequest deleteVolumeRequest =
|
||||
omRequest.getDeleteVolumeRequest();
|
||||
|
||||
getOzoneManager().applyDeleteVolume(
|
||||
deleteVolumeRequest.getVolumeName(), deleteVolumeRequest.getOwner(),
|
||||
deleteVolumeRequest.getVolumeList());
|
||||
|
||||
return DeleteVolumeResponse.newBuilder().build();
|
||||
}
|
||||
}
|
||||
|
@ -90,8 +90,7 @@ public void stop() {
|
||||
@Test
|
||||
public void testPreExecute() throws Exception {
|
||||
String volumeName = UUID.randomUUID().toString();
|
||||
String ownerName = UUID.randomUUID().toString();
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName);
|
||||
|
||||
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||
new OMVolumeDeleteRequest(originalRequest);
|
||||
@ -106,7 +105,7 @@ public void testValidateAndUpdateCacheSuccess() throws Exception {
|
||||
String volumeName = UUID.randomUUID().toString();
|
||||
String ownerName = "user1";
|
||||
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName);
|
||||
|
||||
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||
new OMVolumeDeleteRequest(originalRequest);
|
||||
@ -147,9 +146,7 @@ public void testValidateAndUpdateCacheSuccess() throws Exception {
|
||||
public void testValidateAndUpdateCacheWithVolumeNotFound()
|
||||
throws Exception {
|
||||
String volumeName = UUID.randomUUID().toString();
|
||||
String ownerName = "user1";
|
||||
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName);
|
||||
|
||||
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||
new OMVolumeDeleteRequest(originalRequest);
|
||||
@ -173,7 +170,7 @@ public void testValidateAndUpdateCacheWithVolumeNotEmpty() throws Exception {
|
||||
String volumeName = UUID.randomUUID().toString();
|
||||
String ownerName = "user1";
|
||||
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName, ownerName);
|
||||
OMRequest originalRequest = deleteVolumeRequest(volumeName);
|
||||
|
||||
OMVolumeDeleteRequest omVolumeDeleteRequest =
|
||||
new OMVolumeDeleteRequest(originalRequest);
|
||||
@ -206,14 +203,11 @@ public void testValidateAndUpdateCacheWithVolumeNotEmpty() throws Exception {
|
||||
/**
|
||||
* Create OMRequest for delete volume.
|
||||
* @param volumeName
|
||||
* @param ownerName
|
||||
* @return OMRequest
|
||||
*/
|
||||
private OMRequest deleteVolumeRequest(String volumeName,
|
||||
String ownerName) {
|
||||
private OMRequest deleteVolumeRequest(String volumeName) {
|
||||
DeleteVolumeRequest deleteVolumeRequest =
|
||||
DeleteVolumeRequest.newBuilder().setVolumeName(volumeName)
|
||||
.setOwner(ownerName).build();
|
||||
DeleteVolumeRequest.newBuilder().setVolumeName(volumeName).build();
|
||||
|
||||
return OMRequest.newBuilder().setClientId(UUID.randomUUID().toString())
|
||||
.setCmdType(OzoneManagerProtocolProtos.Type.DeleteVolume)
|
||||
|
Loading…
Reference in New Issue
Block a user