github.com/minio/minio@v0.0.0-20240328213742-3f72439b8a27/internal/bucket/lifecycle/and.go (about) 1 // Copyright (c) 2015-2021 MinIO, Inc. 2 // 3 // This file is part of MinIO Object Storage stack 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package lifecycle 19 20 import ( 21 "encoding/xml" 22 ) 23 24 var errDuplicateTagKey = Errorf("Duplicate Tag Keys are not allowed") 25 26 // And - a tag to combine a prefix and multiple tags for lifecycle configuration rule. 27 type And struct { 28 XMLName xml.Name `xml:"And"` 29 ObjectSizeGreaterThan int64 `xml:"ObjectSizeGreaterThan,omitempty"` 30 ObjectSizeLessThan int64 `xml:"ObjectSizeLessThan,omitempty"` 31 Prefix Prefix `xml:"Prefix,omitempty"` 32 Tags []Tag `xml:"Tag,omitempty"` 33 } 34 35 // isEmpty returns true if Tags field is null 36 func (a And) isEmpty() bool { 37 return len(a.Tags) == 0 && !a.Prefix.set && 38 a.ObjectSizeGreaterThan == 0 && a.ObjectSizeLessThan == 0 39 } 40 41 // Validate - validates the And field 42 func (a And) Validate() error { 43 // > This is used in a Lifecycle Rule Filter to apply a logical AND to two or more predicates. 44 // ref: https://docs.aws.amazon.com/AmazonS3/latest/API/API_LifecycleRuleAndOperator.html 45 // i.e, predCount >= 2 46 var predCount int 47 if a.Prefix.set { 48 predCount++ 49 } 50 predCount += len(a.Tags) 51 if a.ObjectSizeGreaterThan > 0 { 52 predCount++ 53 } 54 if a.ObjectSizeLessThan > 0 { 55 predCount++ 56 } 57 58 if predCount < 2 { 59 return errXMLNotWellFormed 60 } 61 62 if a.ContainsDuplicateTag() { 63 return errDuplicateTagKey 64 } 65 for _, t := range a.Tags { 66 if err := t.Validate(); err != nil { 67 return err 68 } 69 } 70 71 if a.ObjectSizeGreaterThan < 0 || a.ObjectSizeLessThan < 0 { 72 return errXMLNotWellFormed 73 } 74 return nil 75 } 76 77 // ContainsDuplicateTag - returns true if duplicate keys are present in And 78 func (a And) ContainsDuplicateTag() bool { 79 x := make(map[string]struct{}, len(a.Tags)) 80 81 for _, t := range a.Tags { 82 if _, has := x[t.Key]; has { 83 return true 84 } 85 x[t.Key] = struct{}{} 86 } 87 88 return false 89 } 90 91 // BySize returns true when sz satisfies a 92 // ObjectSizeLessThan/ObjectSizeGreaterthan or a logical AND of these predicates 93 // Note: And combines size and other predicates like Tags, Prefix, etc. This 94 // method applies exclusively to size predicates only. 95 func (a And) BySize(sz int64) bool { 96 if a.ObjectSizeGreaterThan > 0 && 97 sz <= a.ObjectSizeGreaterThan { 98 return false 99 } 100 if a.ObjectSizeLessThan > 0 && 101 sz >= a.ObjectSizeLessThan { 102 return false 103 } 104 return true 105 }