001/* 002 * Copyright (c) 2023 Chris K Wensel <[email protected]>. All Rights Reserved. 003 * 004 * This Source Code Form is subject to the terms of the Mozilla Public 005 * License, v. 2.0. If a copy of the MPL was not distributed with this 006 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 007 */ 008 009package clusterless.commons.naming; 010 011import java.util.Objects; 012 013/** 014 * Creates an identifier to use as an export/import key for provider output/export values. 015 * <p/> 016 * <pre> 017 * aws:qualifier:[stage:]scopeName:scopeVersion:resourceNS:resourceType:resourceName 018 * </pre> 019 * <p/> 020 * Where the qualifier represents the type of value being exported/imported: 021 * - id 022 * - name 023 * - arn 024 * <p/> 025 * Where stage is the stage of the deployment, such as dev, test, prod, etc. It is optional. 026 * <p/> 027 * scopeName and scopeVersion are analogous to project names and versions. 028 * <p/> 029 * Resources are identified by a namespace, type, and name. 030 * <p/> 031 * 032 * <pre> 033 * ref:aws:id:project-a:20230101:core:compute:spot 034 * ref:aws:id:dev:project-a:20230101:core:compute:spot 035 * </pre> 036 */ 037public final class Ref { 038 public static Ref ref() { 039 return new Ref(); 040 } 041 042 public static Ref idRef() { 043 return new Ref().withQualifier(Qualifier.Id); 044 } 045 046 public static Ref arnRef() { 047 return new Ref().withQualifier(Qualifier.Arn); 048 } 049 050 public static Ref nameRef() { 051 return new Ref().withQualifier(Qualifier.Name); 052 } 053 054 public static boolean isRef(String value) { 055 return value != null && value.startsWith("ref:"); 056 } 057 058 public static String provider(String value) { 059 return value != null ? value.split(":")[1] : null; 060 } 061 062 final Fixed provider; 063 final Qualifier qualifier; 064 final Stage stage; 065 final Fixed scope; 066 final Version scopeVersion; 067 final Fixed resourceNs; 068 final Fixed resourceType; 069 final Fixed resourceName; 070 071 public Ref() { 072 provider = Fixed.fixedNull(); 073 qualifier = null; 074 stage = Stage.nullStage(); 075 scope = Fixed.fixedNull(); 076 scopeVersion = Version.versionNull(); 077 resourceNs = Fixed.fixedNull(); 078 resourceType = Fixed.fixedNull(); 079 resourceName = Fixed.fixedNull(); 080 } 081 082 private Ref(Fixed provider, Qualifier qualifier, Stage stage, Fixed scope, Version scopeVersion, Fixed resourceNs, Fixed resourceType, Fixed resourceName) { 083 this.provider = provider; 084 this.qualifier = qualifier; 085 this.stage = stage == null ? Stage.nullStage() : stage.asLower(); 086 this.scope = scope; 087 this.scopeVersion = scopeVersion; 088 this.resourceNs = resourceNs; 089 this.resourceType = resourceType; 090 this.resourceName = resourceName; 091 } 092 093 public Ref withProvider(String provider) { 094 Objects.requireNonNull(provider); 095 return withProvider(Label.of(provider)); 096 } 097 098 public Ref withProvider(Label provider) { 099 Objects.requireNonNull(provider); 100 return withProvider(Fixed.of(provider.lowerHyphen())); 101 } 102 103 public Ref withProvider(Fixed provider) { 104 Label.requireNonEmpty(provider); 105 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 106 } 107 108 public Ref withStage(Stage stage) { 109 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 110 } 111 112 public Ref withScope(String scope) { 113 return withScope(Label.of(scope)); 114 } 115 116 public Ref withScope(Label scope) { 117 return withScope(Fixed.of(scope.lowerHyphen())); 118 } 119 120 public Ref withScope(Fixed scope) { 121 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 122 } 123 124 public Ref withScopeVersion(String scopeVersion) { 125 return withScopeVersion(Version.of(scopeVersion)); 126 } 127 128 public Ref withScopeVersion(Fixed scopeVersion) { 129 return withScopeVersion(Version.of(scopeVersion.lowerHyphen())); 130 } 131 132 public Ref withScopeVersion(Version scopeVersion) { 133 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 134 } 135 136 public Ref withResourceNs(String resourceNs) { 137 return withResourceNs(Label.of(resourceNs)); 138 } 139 140 public Ref withResourceNs(Label resourceNs) { 141 return withResourceNs(Fixed.of(resourceNs.lowerHyphen())); 142 } 143 144 public Ref withResourceNs(Fixed resourceNs) { 145 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 146 } 147 148 public Ref withResourceType(String resourceType) { 149 return withResourceType(Label.of(resourceType)); 150 } 151 152 public Ref withResourceType(Label resourceType) { 153 return withResourceType(Fixed.of(resourceType.lowerHyphen())); 154 } 155 156 public Ref withResourceType(Fixed resourceType) { 157 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 158 } 159 160 public Ref withResourceName(String resourceName) { 161 return withResourceName(Label.of(resourceName)); 162 } 163 164 public Ref withResourceName(Label resourceName) { 165 return withResourceName(Fixed.of(resourceName.lowerHyphen())); 166 } 167 168 public Ref withResourceName(Fixed resourceName) { 169 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 170 } 171 172 public Ref withQualifier(Qualifier qualifier) { 173 return new Ref(provider, qualifier, stage, scope, scopeVersion, resourceNs, resourceType, resourceName); 174 } 175 176 public Label provider() { 177 return provider; 178 } 179 180 public Stage stage() { 181 return stage; 182 } 183 184 public Fixed scope() { 185 return scope; 186 } 187 188 public Fixed scopeVersion() { 189 return scopeVersion; 190 } 191 192 public Fixed resourceNs() { 193 return resourceNs; 194 } 195 196 public Fixed resourceType() { 197 return resourceType; 198 } 199 200 public Fixed resourceName() { 201 return resourceName; 202 } 203 204 public Qualifier qualifier() { 205 return qualifier; 206 } 207 208 public Label resourceLabel() { 209 requireNonNull(resourceNs, "resourceNs required"); 210 requireNonNull(resourceType, "resourceType required"); 211 requireNonNull(resourceName, "resourceName required"); 212 213 return Label.NULL 214 .with(resourceNs) 215 .with(Label.of(resourceType.value())) 216 .with(resourceName); 217 } 218 219 public Label label() { 220 requireNonNull(provider, "provider required"); 221 requireNonNull(qualifier, "qualifier required"); 222 requireNonNull(scope, "scope required"); 223 requireNonNull(scopeVersion, "scopeVersion required"); 224 requireNonNull(resourceNs, "resourceNs required"); 225 requireNonNull(resourceType, "resourceType required"); 226 requireNonNull(resourceName, "resourceName required"); 227 228 return Label.of("ref") 229 .with(provider) 230 .with(qualifier) 231 .with(stage) 232 .with(scope) 233 .with(scopeVersion) 234 .with(resourceNs) 235 .with(resourceType) 236 .with(resourceName); 237 } 238 239 private static void requireNonNull(Label label, String message) { 240 Objects.requireNonNull(label, message); 241 242 if (label.isNull()) { 243 throw new NullPointerException(message); 244 } 245 } 246 247 248 public String exportName() { 249 return label().lowerColonPath(); 250 } 251 252 @Override 253 public String toString() { 254 return Label.of("ref") 255 .with(provider) 256 .with(qualifier) 257 .with(stage) 258 .with(scope) 259 .with(scopeVersion) 260 .with(resourceNs) 261 .with(resourceType) 262 .with(resourceName).lowerColonPath(); 263 } 264 265 @Override 266 public boolean equals(Object o) { 267 if (this == o) return true; 268 if (o == null || getClass() != o.getClass()) return false; 269 Ref ref = (Ref) o; 270 return Objects.equals(provider, ref.provider) && Objects.equals(stage, ref.stage) && Objects.equals(scope, ref.scope) && Objects.equals(scopeVersion, ref.scopeVersion) && Objects.equals(resourceNs, ref.resourceNs) && Objects.equals(resourceType, ref.resourceType) && Objects.equals(resourceName, ref.resourceName) && qualifier == ref.qualifier; 271 } 272 273 @Override 274 public int hashCode() { 275 return Objects.hash(provider, stage, scope, scopeVersion, resourceNs, resourceType, resourceName, qualifier); 276 } 277 278 public enum Qualifier implements Label.EnumLabel { 279 Name, 280 Id, 281 Arn; 282 } 283}