blob: ca4bdb0ffef512b1046560be2044a95b9799b8ce [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.BitSet;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.hadoop.hdds.protocol.StorageType;
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.BucketInfo;
import org.apache.hadoop.ozone.protocolPB.OMPBHelper;
import com.google.common.base.Preconditions;
/**
* A class that encapsulates Bucket Info.
*/
public final class OmBucketInfo extends WithObjectID implements Auditable {
/**
* Name of the volume in which the bucket belongs to.
*/
private final String volumeName;
/**
* Name of the bucket.
*/
private final String bucketName;
/**
* ACL Information.
*/
private List<OzoneAcl> acls;
/**
* Bucket Version flag.
*/
private Boolean isVersionEnabled;
/**
* Type of storage to be used for this bucket.
* [RAM_DISK, SSD, DISK, ARCHIVE]
*/
private StorageType storageType;
/**
* Creation time of bucket.
*/
private final long creationTime;
/**
* modification time of bucket.
*/
private long modificationTime;
/**
* Bucket encryption key info if encryption is enabled.
*/
private BucketEncryptionKeyInfo bekInfo;
private final String sourceVolume;
private final String sourceBucket;
private long usedBytes;
private long usedNamespace;
private long quotaInBytes;
private long quotaInNamespace;
/**
* Private constructor, constructed via builder.
* @param volumeName - Volume name.
* @param bucketName - Bucket name.
* @param acls - list of ACLs.
* @param isVersionEnabled - Bucket version flag.
* @param storageType - Storage type to be used.
* @param creationTime - Bucket creation time.
* @param modificationTime - Bucket modification time.
* @param metadata - metadata.
* @param bekInfo - bucket encryption key info.
* @param sourceVolume - source volume for bucket links, null otherwise
* @param sourceBucket - source bucket for bucket links, null otherwise
* @param usedBytes - Bucket Quota Usage in bytes.
* @param quotaInBytes Bucket quota in bytes.
* @param quotaInNamespace Bucket quota in counts.
*/
@SuppressWarnings("checkstyle:ParameterNumber")
private OmBucketInfo(String volumeName,
String bucketName,
List<OzoneAcl> acls,
boolean isVersionEnabled,
StorageType storageType,
long creationTime,
long modificationTime,
long objectID,
long updateID,
Map<String, String> metadata,
BucketEncryptionKeyInfo bekInfo,
String sourceVolume,
String sourceBucket,
long usedBytes,
long usedNamespace,
long quotaInBytes,
long quotaInNamespace) {
this.volumeName = volumeName;
this.bucketName = bucketName;
this.acls = acls;
this.isVersionEnabled = isVersionEnabled;
this.storageType = storageType;
this.creationTime = creationTime;
this.modificationTime = modificationTime;
this.objectID = objectID;
this.updateID = updateID;
this.metadata = metadata;
this.bekInfo = bekInfo;
this.sourceVolume = sourceVolume;
this.sourceBucket = sourceBucket;
this.usedBytes = usedBytes;
this.usedNamespace = usedNamespace;
this.quotaInBytes = quotaInBytes;
this.quotaInNamespace = quotaInNamespace;
}
/**
* Returns the Volume Name.
* @return String.
*/
public String getVolumeName() {
return volumeName;
}
/**
* Returns the Bucket Name.
* @return String
*/
public String getBucketName() {
return bucketName;
}
/**
* Returns the ACL's associated with this bucket.
* @return {@literal List<OzoneAcl>}
*/
public List<OzoneAcl> getAcls() {
return acls;
}
/**
* Add an ozoneAcl to list of existing Acl set.
* @param ozoneAcl
* @return true - if successfully added, false if not added or acl is
* already existing in the acl list.
*/
public boolean addAcl(OzoneAcl ozoneAcl) {
return OzoneAclUtil.addAcl(acls, ozoneAcl);
}
/**
* Remove acl from existing acl list.
* @param ozoneAcl
* @return true - if successfully removed, false if not able to remove due
* to that acl is not in the existing acl list.
*/
public boolean removeAcl(OzoneAcl ozoneAcl) {
return OzoneAclUtil.removeAcl(acls, ozoneAcl);
}
/**
* Reset the existing acl list.
* @param ozoneAcls
* @return true - if successfully able to reset.
*/
public boolean setAcls(List<OzoneAcl> ozoneAcls) {
return OzoneAclUtil.setAcl(acls, ozoneAcls);
}
/**
* Returns true if bucket version is enabled, else false.
* @return isVersionEnabled
*/
public boolean getIsVersionEnabled() {
return isVersionEnabled;
}
/**
* Returns the type of storage to be used.
* @return StorageType
*/
public StorageType getStorageType() {
return storageType;
}
/**
* Returns creation time.
*
* @return long
*/
public long getCreationTime() {
return creationTime;
}
/**
* Returns modification time.
* @return long
*/
public long getModificationTime() {
return modificationTime;
}
/**
* Returns bucket encryption key info.
* @return bucket encryption key info
*/
public BucketEncryptionKeyInfo getEncryptionKeyInfo() {
return bekInfo;
}
public String getSourceVolume() {
return sourceVolume;
}
public String getSourceBucket() {
return sourceBucket;
}
public long getUsedBytes() {
return usedBytes;
}
public long getUsedNamespace() {
return usedNamespace;
}
public void incrUsedBytes(long bytes) {
this.usedBytes += bytes;
}
public void incrUsedNamespace(long namespaceToUse) {
this.usedNamespace += namespaceToUse;
}
public long getQuotaInBytes() {
return quotaInBytes;
}
public long getQuotaInNamespace() {
return quotaInNamespace;
}
public boolean isLink() {
return sourceVolume != null && sourceBucket != null;
}
/**
* Returns new builder class that builds a OmBucketInfo.
*
* @return Builder
*/
public static Builder newBuilder() {
return new Builder();
}
@Override
public Map<String, String> toAuditMap() {
Map<String, String> auditMap = new LinkedHashMap<>();
auditMap.put(OzoneConsts.VOLUME, this.volumeName);
auditMap.put(OzoneConsts.BUCKET, this.bucketName);
auditMap.put(OzoneConsts.GDPR_FLAG,
this.metadata.get(OzoneConsts.GDPR_FLAG));
auditMap.put(OzoneConsts.ACLS,
(this.acls != null) ? this.acls.toString() : null);
auditMap.put(OzoneConsts.IS_VERSION_ENABLED,
String.valueOf(this.isVersionEnabled));
auditMap.put(OzoneConsts.STORAGE_TYPE,
(this.storageType != null) ? this.storageType.name() : null);
auditMap.put(OzoneConsts.CREATION_TIME, String.valueOf(this.creationTime));
auditMap.put(OzoneConsts.BUCKET_ENCRYPTION_KEY,
(bekInfo != null) ? bekInfo.getKeyName() : null);
auditMap.put(OzoneConsts.MODIFICATION_TIME,
String.valueOf(this.modificationTime));
if (isLink()) {
auditMap.put(OzoneConsts.SOURCE_VOLUME, sourceVolume);
auditMap.put(OzoneConsts.SOURCE_BUCKET, sourceBucket);
}
auditMap.put(OzoneConsts.USED_BYTES, String.valueOf(this.usedBytes));
auditMap.put(OzoneConsts.USED_NAMESPACE,
String.valueOf(this.usedNamespace));
return auditMap;
}
/**
* Return a new copy of the object.
*/
public OmBucketInfo copyObject() {
Builder builder = toBuilder();
if (bekInfo != null) {
builder.setBucketEncryptionKey(bekInfo.copy());
}
builder.acls.clear();
acls.forEach(acl -> builder.addAcl(new OzoneAcl(acl.getType(),
acl.getName(), (BitSet) acl.getAclBitSet().clone(),
acl.getAclScope())));
return builder.build();
}
public Builder toBuilder() {
return new Builder()
.setVolumeName(volumeName)
.setBucketName(bucketName)
.setStorageType(storageType)
.setIsVersionEnabled(isVersionEnabled)
.setCreationTime(creationTime)
.setModificationTime(modificationTime)
.setObjectID(objectID)
.setUpdateID(updateID)
.setBucketEncryptionKey(bekInfo)
.setSourceVolume(sourceVolume)
.setSourceBucket(sourceBucket)
.setAcls(acls)
.addAllMetadata(metadata)
.setUsedBytes(usedBytes)
.setUsedNamespace(usedNamespace)
.setQuotaInBytes(quotaInBytes)
.setQuotaInNamespace(quotaInNamespace);
}
/**
* Builder for OmBucketInfo.
*/
public static class Builder {
private String volumeName;
private String bucketName;
private List<OzoneAcl> acls;
private Boolean isVersionEnabled;
private StorageType storageType;
private long creationTime;
private long modificationTime;
private long objectID;
private long updateID;
private Map<String, String> metadata;
private BucketEncryptionKeyInfo bekInfo;
private String sourceVolume;
private String sourceBucket;
private long usedBytes;
private long usedNamespace;
private long quotaInBytes;
private long quotaInNamespace;
public Builder() {
//Default values
this.acls = new ArrayList<>();
this.isVersionEnabled = false;
this.storageType = StorageType.DISK;
this.metadata = new HashMap<>();
this.quotaInBytes = OzoneConsts.QUOTA_RESET;
this.quotaInNamespace = OzoneConsts.QUOTA_RESET;
}
public Builder setVolumeName(String volume) {
this.volumeName = volume;
return this;
}
public Builder setBucketName(String bucket) {
this.bucketName = bucket;
return this;
}
public Builder setAcls(List<OzoneAcl> listOfAcls) {
if (listOfAcls != null) {
this.acls.addAll(listOfAcls);
}
return this;
}
public Builder addAcl(OzoneAcl ozoneAcl) {
if (ozoneAcl != null) {
this.acls.add(ozoneAcl);
}
return this;
}
public Builder setIsVersionEnabled(Boolean versionFlag) {
this.isVersionEnabled = versionFlag;
return this;
}
public Builder setStorageType(StorageType storage) {
this.storageType = storage;
return this;
}
public Builder setCreationTime(long createdOn) {
this.creationTime = createdOn;
return this;
}
public Builder setModificationTime(long modifiedOn) {
this.modificationTime = modifiedOn;
return this;
}
public Builder setObjectID(long obId) {
this.objectID = obId;
return this;
}
public Builder setUpdateID(long id) {
this.updateID = id;
return this;
}
public Builder addMetadata(String key, String value) {
metadata.put(key, value);
return this;
}
public Builder addAllMetadata(Map<String, String> additionalMetadata) {
if (additionalMetadata != null) {
metadata.putAll(additionalMetadata);
}
return this;
}
public Builder setBucketEncryptionKey(
BucketEncryptionKeyInfo info) {
this.bekInfo = info;
return this;
}
public Builder setSourceVolume(String volume) {
this.sourceVolume = volume;
return this;
}
public Builder setSourceBucket(String bucket) {
this.sourceBucket = bucket;
return this;
}
public Builder setUsedBytes(long quotaUsage) {
this.usedBytes = quotaUsage;
return this;
}
public Builder setUsedNamespace(long quotaUsage) {
this.usedNamespace = quotaUsage;
return this;
}
public Builder setQuotaInBytes(long quota) {
this.quotaInBytes = quota;
return this;
}
public Builder setQuotaInNamespace(long quota) {
this.quotaInNamespace = quota;
return this;
}
/**
* Constructs the OmBucketInfo.
* @return instance of OmBucketInfo.
*/
public OmBucketInfo build() {
Preconditions.checkNotNull(volumeName);
Preconditions.checkNotNull(bucketName);
Preconditions.checkNotNull(acls);
Preconditions.checkNotNull(isVersionEnabled);
Preconditions.checkNotNull(storageType);
return new OmBucketInfo(volumeName, bucketName, acls, isVersionEnabled,
storageType, creationTime, modificationTime, objectID, updateID,
metadata, bekInfo, sourceVolume, sourceBucket, usedBytes,
usedNamespace, quotaInBytes, quotaInNamespace);
}
}
/**
* Creates BucketInfo protobuf from OmBucketInfo.
*/
public BucketInfo getProtobuf() {
BucketInfo.Builder bib = BucketInfo.newBuilder()
.setVolumeName(volumeName)
.setBucketName(bucketName)
.addAllAcls(OzoneAclUtil.toProtobuf(acls))
.setIsVersionEnabled(isVersionEnabled)
.setStorageType(storageType.toProto())
.setCreationTime(creationTime)
.setModificationTime(modificationTime)
.setObjectID(objectID)
.setUpdateID(updateID)
.setUsedBytes(usedBytes)
.setUsedNamespace(usedNamespace)
.addAllMetadata(KeyValueUtil.toProtobuf(metadata))
.setQuotaInBytes(quotaInBytes)
.setQuotaInNamespace(quotaInNamespace);
if (bekInfo != null && bekInfo.getKeyName() != null) {
bib.setBeinfo(OMPBHelper.convert(bekInfo));
}
if (sourceVolume != null) {
bib.setSourceVolume(sourceVolume);
}
if (sourceBucket != null) {
bib.setSourceBucket(sourceBucket);
}
return bib.build();
}
/**
* Parses BucketInfo protobuf and creates OmBucketInfo.
* @param bucketInfo
* @return instance of OmBucketInfo
*/
public static OmBucketInfo getFromProtobuf(BucketInfo bucketInfo) {
OmBucketInfo.Builder obib = OmBucketInfo.newBuilder()
.setVolumeName(bucketInfo.getVolumeName())
.setBucketName(bucketInfo.getBucketName())
.setAcls(bucketInfo.getAclsList().stream().map(
OzoneAcl::fromProtobuf).collect(Collectors.toList()))
.setIsVersionEnabled(bucketInfo.getIsVersionEnabled())
.setStorageType(StorageType.valueOf(bucketInfo.getStorageType()))
.setCreationTime(bucketInfo.getCreationTime())
.setUsedBytes(bucketInfo.getUsedBytes())
.setModificationTime(bucketInfo.getModificationTime())
.setQuotaInBytes(bucketInfo.getQuotaInBytes())
.setUsedNamespace(bucketInfo.getUsedNamespace())
.setQuotaInNamespace(bucketInfo.getQuotaInNamespace());
if (bucketInfo.hasObjectID()) {
obib.setObjectID(bucketInfo.getObjectID());
}
if (bucketInfo.hasUpdateID()) {
obib.setUpdateID(bucketInfo.getUpdateID());
}
if (bucketInfo.getMetadataList() != null) {
obib.addAllMetadata(KeyValueUtil
.getFromProtobuf(bucketInfo.getMetadataList()));
}
if (bucketInfo.hasBeinfo()) {
obib.setBucketEncryptionKey(OMPBHelper.convert(bucketInfo.getBeinfo()));
}
if (bucketInfo.hasSourceVolume()) {
obib.setSourceVolume(bucketInfo.getSourceVolume());
}
if (bucketInfo.hasSourceBucket()) {
obib.setSourceBucket(bucketInfo.getSourceBucket());
}
return obib.build();
}
@Override
public String getObjectInfo() {
String sourceInfo = sourceVolume != null && sourceBucket != null
? ", source='" + sourceVolume + "/" + sourceBucket + "'"
: "";
return "OMBucketInfo{" +
"volume='" + volumeName + "'" +
", bucket='" + bucketName + "'" +
", isVersionEnabled='" + isVersionEnabled + "'" +
", storageType='" + storageType + "'" +
", creationTime='" + creationTime + "'" +
", usedBytes='" + usedBytes + "'" +
", usedNamespace='" + usedNamespace + "'" +
", quotaInBytes='" + quotaInBytes + "'" +
", quotaInNamespace='" + quotaInNamespace + '\'' +
sourceInfo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
OmBucketInfo that = (OmBucketInfo) o;
return creationTime == that.creationTime &&
modificationTime == that.modificationTime &&
volumeName.equals(that.volumeName) &&
bucketName.equals(that.bucketName) &&
Objects.equals(acls, that.acls) &&
Objects.equals(isVersionEnabled, that.isVersionEnabled) &&
storageType == that.storageType &&
objectID == that.objectID &&
updateID == that.updateID &&
usedBytes == that.usedBytes &&
usedNamespace == that.usedNamespace &&
Objects.equals(sourceVolume, that.sourceVolume) &&
Objects.equals(sourceBucket, that.sourceBucket) &&
Objects.equals(metadata, that.metadata) &&
Objects.equals(bekInfo, that.bekInfo);
}
@Override
public int hashCode() {
return Objects.hash(volumeName, bucketName);
}
@Override
public String toString() {
return "OmBucketInfo{" +
"volumeName='" + volumeName + "'" +
", bucketName='" + bucketName + "'" +
", acls=" + acls +
", isVersionEnabled=" + isVersionEnabled +
", storageType=" + storageType +
", creationTime=" + creationTime +
", bekInfo=" + bekInfo +
", sourceVolume='" + sourceVolume + "'" +
", sourceBucket='" + sourceBucket + "'" +
", objectID=" + objectID +
", updateID=" + updateID +
", metadata=" + metadata +
", usedBytes=" + usedBytes +
", usedNamespace=" + usedNamespace +
", quotaInBytes=" + quotaInBytes +
", quotaInNamespace=" + quotaInNamespace +
'}';
}
}