blob: d818df12298e3420ef6c1456fca4db6de08cbc08 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.ozone.om.helpers;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import com.google.common.collect.ImmutableList;
import org.apache.hadoop.hdds.utils.db.Codec;
import org.apache.hadoop.hdds.utils.db.CopyObject;
import org.apache.hadoop.hdds.utils.db.DelegatedCodec;
import org.apache.hadoop.hdds.utils.db.Proto2Codec;
import org.apache.hadoop.ozone.OzoneAcl;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.audit.Auditable;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OzoneAclInfo;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.VolumeInfo;
import com.google.common.base.Preconditions;
/**
* A class that encapsulates the OmVolumeArgs Args.
*/
public final class OmVolumeArgs extends WithObjectID
implements CopyObject<OmVolumeArgs>, Auditable {
private static final Codec<OmVolumeArgs> CODEC = new DelegatedCodec<>(
Proto2Codec.get(VolumeInfo.getDefaultInstance()),
OmVolumeArgs::getFromProtobuf,
OmVolumeArgs::getProtobuf);
public static Codec<OmVolumeArgs> getCodec() {
return CODEC;
}
private final String adminName;
private String ownerName;
private final String volume;
private long creationTime;
private long modificationTime;
private long quotaInBytes;
private long quotaInNamespace;
private long usedNamespace;
private List<OzoneAcl> acls;
/**
* Reference count on this Ozone volume.
*
* When reference count is larger than zero, it indicates that at least one
* "lock" is held on the volume by some Ozone feature (e.g. multi-tenancy).
* Volume delete operation will be denied in this case, and user should be
* prompted to release the lock first via the interface provided by that
* feature.
*
* Volumes created using CLI, ObjectStore API or upgraded from older OM DB
* will have reference count set to zero by default.
*/
private long refCount;
/**
* Private constructor, constructed via builder.
* @param adminName - Administrator's name.
* @param ownerName - Volume owner's name
* @param volume - volume name
* @param quotaInBytes - Volume Quota in bytes.
* @param quotaInNamespace - Volume Quota in counts.
* @param usedNamespace - Volume Namespace Quota Usage in counts.
* @param metadata - metadata map for custom key/value data.
* @param acls - list of volume acls.
* @param creationTime - Volume creation time.
* @param objectID - ID of this object.
* @param updateID - A sequence number that denotes the last update on this
* object. This is a monotonically increasing number.
*/
@SuppressWarnings({"checkstyle:ParameterNumber",
"This is invoked from a builder."})
private OmVolumeArgs(String adminName, String ownerName, String volume,
long quotaInBytes, long quotaInNamespace, long usedNamespace,
Map<String, String> metadata, List<OzoneAcl> acls, long creationTime,
long modificationTime, long objectID, long updateID, long refCount) {
this.adminName = adminName;
this.ownerName = ownerName;
this.volume = volume;
this.quotaInBytes = quotaInBytes;
this.quotaInNamespace = quotaInNamespace;
this.usedNamespace = usedNamespace;
setMetadata(metadata);
this.acls = acls;
this.creationTime = creationTime;
this.modificationTime = modificationTime;
setObjectID(objectID);
setUpdateID(updateID);
this.refCount = refCount;
}
public long getRefCount() {
Preconditions.checkState(refCount >= 0L, "refCount should not be negative");
return refCount;
}
/**
* Increase refCount by 1.
*/
public void incRefCount() {
this.refCount++;
}
/**
* Decrease refCount by 1.
*/
public void decRefCount() {
Preconditions.checkState(this.refCount > 0L,
"refCount should not become negative");
this.refCount--;
}
public void setOwnerName(String newOwner) {
this.ownerName = newOwner;
}
public void setQuotaInBytes(long quotaInBytes) {
this.quotaInBytes = quotaInBytes;
}
public void setQuotaInNamespace(long quotaInNamespace) {
this.quotaInNamespace = quotaInNamespace;
}
public void setCreationTime(long time) {
this.creationTime = time;
}
public void setModificationTime(long time) {
this.modificationTime = time;
}
public boolean addAcl(OzoneAcl ozoneAcl) {
return OzoneAclUtil.addAcl(acls, ozoneAcl);
}
public boolean setAcls(List<OzoneAcl> ozoneAcls) {
return OzoneAclUtil.setAcl(acls, ozoneAcls);
}
public boolean removeAcl(OzoneAcl ozoneAcl) {
return OzoneAclUtil.removeAcl(acls, ozoneAcl);
}
/**
* Returns the Admin Name.
* @return String.
*/
public String getAdminName() {
return adminName;
}
/**
* Returns the owner Name.
* @return String
*/
public String getOwnerName() {
return ownerName;
}
/**
* Returns the volume Name.
* @return String
*/
public String getVolume() {
return volume;
}
/**
* Returns creation time.
* @return long
*/
public long getCreationTime() {
return creationTime;
}
/**
* Returns modification time.
* @return long
*/
public long getModificationTime() {
return modificationTime;
}
/**
* Returns Quota in Bytes.
* @return long, Quota in bytes.
*/
public long getQuotaInBytes() {
return quotaInBytes;
}
/**
* Returns Quota in counts.
* @return long, Quota in counts.
*/
public long getQuotaInNamespace() {
return quotaInNamespace;
}
public List<OzoneAcl> getAcls() {
return ImmutableList.copyOf(acls);
}
public List<OzoneAcl> getDefaultAcls() {
List<OzoneAcl> defaultAcls = new ArrayList<>();
for (OzoneAcl acl : acls) {
if (acl.getAclScope() == OzoneAcl.AclScope.DEFAULT) {
defaultAcls.add(acl);
}
}
return defaultAcls;
}
/**
* increase used bucket namespace by n.
*/
public void incrUsedNamespace(long n) {
usedNamespace += n;
}
/**
* Returns used bucket namespace.
* @return usedNamespace
*/
public long getUsedNamespace() {
return usedNamespace;
}
/**
* Returns new builder class that builds a OmVolumeArgs.
*
* @return Builder
*/
public static Builder newBuilder() {
return new Builder();
}
@Override
public Map<String, String> toAuditMap() {
Map<String, String> auditMap = new LinkedHashMap<>();
auditMap.put(OzoneConsts.ADMIN, this.adminName);
auditMap.put(OzoneConsts.OWNER, this.ownerName);
auditMap.put(OzoneConsts.VOLUME, this.volume);
auditMap.put(OzoneConsts.CREATION_TIME, String.valueOf(this.creationTime));
auditMap.put(OzoneConsts.MODIFICATION_TIME,
String.valueOf(this.modificationTime));
auditMap.put(OzoneConsts.QUOTA_IN_BYTES, String.valueOf(this.quotaInBytes));
auditMap.put(OzoneConsts.QUOTA_IN_NAMESPACE,
String.valueOf(this.quotaInNamespace));
auditMap.put(OzoneConsts.USED_NAMESPACE,
String.valueOf(this.usedNamespace));
auditMap.put(OzoneConsts.OBJECT_ID, String.valueOf(this.getObjectID()));
auditMap.put(OzoneConsts.UPDATE_ID, String.valueOf(this.getUpdateID()));
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 Objects.equals(this.getObjectID(), that.getObjectID());
}
@Override
public int hashCode() {
return Objects.hash(getObjectID());
}
/**
* Builder for OmVolumeArgs.
*/
public static class Builder {
private String adminName;
private String ownerName;
private String volume;
private long creationTime;
private long modificationTime;
private long quotaInBytes;
private long quotaInNamespace;
private long usedNamespace;
private Map<String, String> metadata;
private List<OzoneAcl> acls;
private long objectID;
private long updateID;
private long refCount;
/**
* Sets the Object ID for this Object.
* Object ID are unique and immutable identifier for each object in the
* System.
* @param id - long
*/
public Builder setObjectID(long id) {
this.objectID = id;
return this;
}
/**
* Sets the update ID for this Object. Update IDs are monotonically
* increasing values which are updated each time there is an update.
* @param id - long
*/
public Builder setUpdateID(long id) {
this.updateID = id;
return this;
}
/**
* Constructs a builder.
*/
public Builder() {
metadata = new HashMap<>();
acls = new ArrayList();
quotaInBytes = OzoneConsts.QUOTA_RESET;
quotaInNamespace = OzoneConsts.QUOTA_RESET;
}
public Builder setAdminName(String admin) {
this.adminName = admin;
return this;
}
public Builder setOwnerName(String owner) {
this.ownerName = owner;
return this;
}
public Builder setVolume(String volumeName) {
this.volume = volumeName;
return this;
}
public Builder setCreationTime(long createdOn) {
this.creationTime = createdOn;
return this;
}
public Builder setModificationTime(long modifiedOn) {
this.modificationTime = modifiedOn;
return this;
}
public Builder setQuotaInBytes(long quotaBytes) {
this.quotaInBytes = quotaBytes;
return this;
}
public Builder setQuotaInNamespace(long quotaNamespace) {
this.quotaInNamespace = quotaNamespace;
return this;
}
public Builder setUsedNamespace(long namespaceUsage) {
this.usedNamespace = namespaceUsage;
return this;
}
public Builder addMetadata(String key, String value) {
metadata.put(key, value); // overwrite if present.
return this;
}
public Builder addAllMetadata(Map<String, String> additionalMetaData) {
if (additionalMetaData != null) {
metadata.putAll(additionalMetaData);
}
return this;
}
public Builder addOzoneAcls(OzoneAcl acl) {
OzoneAclUtil.addAcl(acls, acl);
return this;
}
public void setRefCount(long refCount) {
Preconditions.checkState(refCount >= 0L,
"refCount should not be negative");
this.refCount = refCount;
}
/**
* Constructs a CreateVolumeArgument.
* @return CreateVolumeArgs.
*/
public OmVolumeArgs build() {
Preconditions.checkNotNull(adminName);
Preconditions.checkNotNull(ownerName);
Preconditions.checkNotNull(volume);
return new OmVolumeArgs(adminName, ownerName, volume, quotaInBytes,
quotaInNamespace, usedNamespace, metadata, acls, creationTime,
modificationTime, objectID, updateID, refCount);
}
}
public VolumeInfo getProtobuf() {
List<OzoneAclInfo> aclList = OzoneAclUtil.toProtobuf(acls);
return VolumeInfo.newBuilder()
.setAdminName(adminName)
.setOwnerName(ownerName)
.setVolume(volume)
.setQuotaInBytes(quotaInBytes)
.setQuotaInNamespace(quotaInNamespace)
.setUsedNamespace(usedNamespace)
.addAllMetadata(KeyValueUtil.toProtobuf(getMetadata()))
.addAllVolumeAcls(aclList)
.setCreationTime(
creationTime == 0 ? System.currentTimeMillis() : creationTime)
.setModificationTime(modificationTime)
.setObjectID(getObjectID())
.setUpdateID(getUpdateID())
.setRefCount(refCount)
.build();
}
public static OmVolumeArgs getFromProtobuf(VolumeInfo volInfo) {
List<OzoneAcl> acls = OzoneAclUtil.fromProtobuf(
volInfo.getVolumeAclsList());
return new OmVolumeArgs(
volInfo.getAdminName(),
volInfo.getOwnerName(),
volInfo.getVolume(),
volInfo.getQuotaInBytes(),
volInfo.getQuotaInNamespace(),
volInfo.getUsedNamespace(),
KeyValueUtil.getFromProtobuf(volInfo.getMetadataList()),
acls,
volInfo.getCreationTime(),
volInfo.getModificationTime(),
volInfo.getObjectID(),
volInfo.getUpdateID(),
volInfo.getRefCount());
}
@Override
public String getObjectInfo() {
return "OMVolumeArgs{" +
"volume='" + volume + '\'' +
", admin='" + adminName + '\'' +
", owner='" + ownerName + '\'' +
", creationTime='" + creationTime + '\'' +
", quotaInBytes='" + quotaInBytes + '\'' +
", usedNamespace='" + usedNamespace + '\'' +
", refCount='" + refCount + '\'' +
'}';
}
@Override
public OmVolumeArgs copyObject() {
Map<String, String> cloneMetadata = new HashMap<>();
if (getMetadata() != null) {
cloneMetadata.putAll(getMetadata());
}
return new OmVolumeArgs(adminName, ownerName, volume, quotaInBytes,
quotaInNamespace, usedNamespace, cloneMetadata, new ArrayList<>(acls),
creationTime, modificationTime, getObjectID(), getUpdateID(), refCount);
}
}