@@ -113,13 +113,19 @@ static boolean isBasic(String typeName) {
113
113
static boolean isTrial (String typeName ) {
114
114
return TRIAL .getTypeName ().equals (typeName );
115
115
}
116
+
117
+ static boolean isEnterprise (String typeName ) {
118
+ return ENTERPRISE .getTypeName ().equals (typeName );
119
+ }
120
+
116
121
}
117
122
118
123
public static final int VERSION_START = 1 ;
119
124
public static final int VERSION_NO_FEATURE_TYPE = 2 ;
120
125
public static final int VERSION_START_DATE = 3 ;
121
126
public static final int VERSION_CRYPTO_ALGORITHMS = 4 ;
122
- public static final int VERSION_CURRENT = VERSION_CRYPTO_ALGORITHMS ;
127
+ public static final int VERSION_ENTERPRISE = 5 ;
128
+ public static final int VERSION_CURRENT = VERSION_ENTERPRISE ;
123
129
124
130
/**
125
131
* XContent param name to deserialize license(s) with
@@ -153,13 +159,14 @@ static boolean isTrial(String typeName) {
153
159
private final long expiryDate ;
154
160
private final long startDate ;
155
161
private final int maxNodes ;
162
+ private final int maxResourceUnits ;
156
163
private final OperationMode operationMode ;
157
164
158
165
/**
159
166
* Decouples operation mode of a license from the license type value.
160
167
* <p>
161
168
* Note: The mode indicates features that should be made available, but it does not indicate whether the license is active!
162
- *
169
+ * <p>
163
170
* The id byte is used for ordering operation modes
164
171
*/
165
172
public enum OperationMode {
@@ -176,13 +183,16 @@ public enum OperationMode {
176
183
this .id = id ;
177
184
}
178
185
179
- /** Returns non-zero positive number when <code>opMode1</code> is greater than <code>opMode2</code> */
186
+ /**
187
+ * Returns non-zero positive number when <code>opMode1</code> is greater than <code>opMode2</code>
188
+ */
180
189
public static int compare (OperationMode opMode1 , OperationMode opMode2 ) {
181
190
return Integer .compare (opMode1 .id , opMode2 .id );
182
191
}
183
192
184
193
/**
185
194
* Determine the operating mode for a license type
195
+ *
186
196
* @see LicenseType#resolve(License)
187
197
* @see #parse(String)
188
198
*/
@@ -211,6 +221,7 @@ public static OperationMode resolve(LicenseType type) {
211
221
* Parses an {@code OperatingMode} from a String.
212
222
* The string must name an operating mode, and not a licensing level (that is, it cannot parse old style license levels
213
223
* such as "dev" or "silver").
224
+ *
214
225
* @see #description()
215
226
*/
216
227
public static OperationMode parse (String mode ) {
@@ -227,8 +238,8 @@ public String description() {
227
238
}
228
239
}
229
240
230
- private License (int version , String uid , String issuer , String issuedTo , long issueDate , String type ,
231
- String subscriptionType , String feature , String signature , long expiryDate , int maxNodes , long startDate ) {
241
+ private License (int version , String uid , String issuer , String issuedTo , long issueDate , String type , String subscriptionType ,
242
+ String feature , String signature , long expiryDate , int maxNodes , int maxResourceUnits , long startDate ) {
232
243
this .version = version ;
233
244
this .uid = uid ;
234
245
this .issuer = issuer ;
@@ -246,6 +257,7 @@ private License(int version, String uid, String issuer, String issuedTo, long is
246
257
this .expiryDate = expiryDate ;
247
258
}
248
259
this .maxNodes = maxNodes ;
260
+ this .maxResourceUnits = maxResourceUnits ;
249
261
this .startDate = startDate ;
250
262
this .operationMode = OperationMode .resolve (LicenseType .resolve (this ));
251
263
validate ();
@@ -294,12 +306,21 @@ public long expiryDate() {
294
306
}
295
307
296
308
/**
297
- * @return the maximum number of nodes this license has been issued for
309
+ * @return the maximum number of nodes this license has been issued for, or {@code -1} if this license is not node based.
298
310
*/
299
311
public int maxNodes () {
300
312
return maxNodes ;
301
313
}
302
314
315
+ /**
316
+ * @return the maximum number of "resource units" this license has been issued for, or {@code -1} if this license is not resource based.
317
+ * A "resource unit" is a measure of computing power (RAM/CPU), the definition of which is maintained outside of the license format,
318
+ * or this class.
319
+ */
320
+ public int maxResourceUnits () {
321
+ return maxResourceUnits ;
322
+ }
323
+
303
324
/**
304
325
* @return a string representing the entity this licenses has been issued to
305
326
*/
@@ -386,20 +407,39 @@ private void validate() {
386
407
throw new IllegalStateException ("uid can not be null" );
387
408
} else if (feature == null && version == VERSION_START ) {
388
409
throw new IllegalStateException ("feature can not be null" );
389
- } else if (maxNodes == -1 ) {
390
- throw new IllegalStateException ("maxNodes has to be set" );
391
410
} else if (expiryDate == -1 ) {
392
411
throw new IllegalStateException ("expiryDate has to be set" );
393
412
} else if (expiryDate == LicenseService .BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS && LicenseType .isBasic (type ) == false ) {
394
413
throw new IllegalStateException ("only basic licenses are allowed to have no expiration" );
395
414
}
415
+
416
+ if (LicenseType .isEnterprise (type ) && version < VERSION_ENTERPRISE ) {
417
+ throw new IllegalStateException ("license type [" + type + "] is not a valid for version [" + version + "] licenses" );
418
+ }
419
+ validateLimits (type , maxNodes , maxResourceUnits );
420
+ }
421
+
422
+ private static void validateLimits (String type , int maxNodes , int maxResourceUnits ) {
423
+ if (LicenseType .isEnterprise (type )) {
424
+ if (maxResourceUnits == -1 ) {
425
+ throw new IllegalStateException ("maxResourceUnits must be set for enterprise licenses (type=[" + type + "])" );
426
+ } else if (maxNodes != -1 ) {
427
+ throw new IllegalStateException ("maxNodes may not be set for enterprise licenses (type=[" + type + "])" );
428
+ }
429
+ } else {
430
+ if (maxNodes == -1 ) {
431
+ throw new IllegalStateException ("maxNodes has to be set" );
432
+ } else if (maxResourceUnits != -1 ) {
433
+ throw new IllegalStateException ("maxResourceUnits may only be set for enterprise licenses (not permitted for type=[" +
434
+ type + "])" );
435
+ }
436
+ }
396
437
}
397
438
398
439
public static License readLicense (StreamInput in ) throws IOException {
399
440
int version = in .readVInt (); // Version for future extensibility
400
441
if (version > VERSION_CURRENT ) {
401
- throw new ElasticsearchException ("Unknown license version found, please upgrade all nodes to the latest elasticsearch-license" +
402
- " plugin" );
442
+ throw new ElasticsearchException ("Unknown license version found, please upgrade all nodes to the latest elasticsearch release" );
403
443
}
404
444
Builder builder = builder ();
405
445
builder .version (version );
@@ -414,6 +454,9 @@ public static License readLicense(StreamInput in) throws IOException {
414
454
}
415
455
builder .expiryDate (in .readLong ());
416
456
builder .maxNodes (in .readInt ());
457
+ if (version >= VERSION_ENTERPRISE ) {
458
+ builder .maxResourceUnits (in .readInt ());
459
+ }
417
460
builder .issuedTo (in .readString ());
418
461
builder .issuer (in .readString ());
419
462
builder .signature (in .readOptionalString ());
@@ -436,6 +479,9 @@ public void writeTo(StreamOutput out) throws IOException {
436
479
}
437
480
out .writeLong (expiryDate );
438
481
out .writeInt (maxNodes );
482
+ if (version >= VERSION_ENTERPRISE ) {
483
+ out .writeInt (maxResourceUnits );
484
+ }
439
485
out .writeString (issuedTo );
440
486
out .writeString (issuer );
441
487
out .writeOptionalString (signature );
@@ -496,7 +542,14 @@ public XContentBuilder toInnerXContent(XContentBuilder builder, Params params) t
496
542
if (expiryDate != LicenseService .BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS ) {
497
543
builder .timeField (Fields .EXPIRY_DATE_IN_MILLIS , Fields .EXPIRY_DATE , expiryDate );
498
544
}
499
- builder .field (Fields .MAX_NODES , maxNodes );
545
+
546
+ if (version >= VERSION_ENTERPRISE ) {
547
+ builder .field (Fields .MAX_NODES , maxNodes == -1 ? null : maxNodes );
548
+ builder .field (Fields .MAX_RESOURCE_UNITS , maxResourceUnits == -1 ? null : maxResourceUnits );
549
+ } else {
550
+ builder .field (Fields .MAX_NODES , maxNodes );
551
+ }
552
+
500
553
builder .field (Fields .ISSUED_TO , issuedTo );
501
554
builder .field (Fields .ISSUER , issuer );
502
555
if (!licenseSpecMode && !restViewMode && signature != null ) {
@@ -541,6 +594,8 @@ public static License fromXContent(XContentParser parser) throws IOException {
541
594
builder .startDate (parser .longValue ());
542
595
} else if (Fields .MAX_NODES .equals (currentFieldName )) {
543
596
builder .maxNodes (parser .intValue ());
597
+ } else if (Fields .MAX_RESOURCE_UNITS .equals (currentFieldName )) {
598
+ builder .maxResourceUnits (parser .intValue ());
544
599
} else if (Fields .ISSUED_TO .equals (currentFieldName )) {
545
600
builder .issuedTo (parser .text ());
546
601
} else if (Fields .ISSUER .equals (currentFieldName )) {
@@ -583,7 +638,7 @@ public static License fromXContent(XContentParser parser) throws IOException {
583
638
throw new ElasticsearchException ("malformed signature for license [" + builder .uid + "]" );
584
639
} else if (version > VERSION_CURRENT ) {
585
640
throw new ElasticsearchException ("Unknown license version found, please upgrade all nodes to the latest " +
586
- "elasticsearch-license plugin" );
641
+ "elasticsearch-license plugin" );
587
642
}
588
643
// signature version is the source of truth
589
644
builder .version (version );
@@ -615,8 +670,7 @@ public static License fromSource(BytesReference bytes, XContentType xContentType
615
670
// EMPTY is safe here because we don't call namedObject
616
671
try (InputStream byteStream = bytes .streamInput ();
617
672
XContentParser parser = xContentType .xContent ()
618
- .createParser (NamedXContentRegistry .EMPTY , LoggingDeprecationHandler .INSTANCE , byteStream ))
619
- {
673
+ .createParser (NamedXContentRegistry .EMPTY , LoggingDeprecationHandler .INSTANCE , byteStream )) {
620
674
License license = null ;
621
675
if (parser .nextToken () == XContentParser .Token .START_OBJECT ) {
622
676
if (parser .nextToken () == XContentParser .Token .FIELD_NAME ) {
@@ -665,7 +719,7 @@ public boolean equals(Object o) {
665
719
666
720
if (issueDate != license .issueDate ) return false ;
667
721
if (expiryDate != license .expiryDate ) return false ;
668
- if (startDate != license .startDate ) return false ;
722
+ if (startDate != license .startDate ) return false ;
669
723
if (maxNodes != license .maxNodes ) return false ;
670
724
if (version != license .version ) return false ;
671
725
if (uid != null ? !uid .equals (license .uid ) : license .uid != null ) return false ;
@@ -690,7 +744,7 @@ public int hashCode() {
690
744
result = 31 * result + (feature != null ? feature .hashCode () : 0 );
691
745
result = 31 * result + (signature != null ? signature .hashCode () : 0 );
692
746
result = 31 * result + (int ) (expiryDate ^ (expiryDate >>> 32 ));
693
- result = 31 * result + (int ) (startDate ^ (startDate >>> 32 ));
747
+ result = 31 * result + (int ) (startDate ^ (startDate >>> 32 ));
694
748
result = 31 * result + maxNodes ;
695
749
result = 31 * result + version ;
696
750
return result ;
@@ -709,6 +763,7 @@ public static final class Fields {
709
763
public static final String START_DATE_IN_MILLIS = "start_date_in_millis" ;
710
764
public static final String START_DATE = "start_date" ;
711
765
public static final String MAX_NODES = "max_nodes" ;
766
+ public static final String MAX_RESOURCE_UNITS = "max_resource_units" ;
712
767
public static final String ISSUED_TO = "issued_to" ;
713
768
public static final String ISSUER = "issuer" ;
714
769
public static final String VERSION = "version" ;
@@ -752,6 +807,7 @@ public static class Builder {
752
807
private long expiryDate = -1 ;
753
808
private long startDate = -1 ;
754
809
private int maxNodes = -1 ;
810
+ private int maxResourceUnits = -1 ;
755
811
756
812
public Builder uid (String uid ) {
757
813
this .uid = uid ;
@@ -807,6 +863,11 @@ public Builder maxNodes(int maxNodes) {
807
863
return this ;
808
864
}
809
865
866
+ public Builder maxResourceUnits (int maxUnits ) {
867
+ this .maxResourceUnits = maxUnits ;
868
+ return this ;
869
+ }
870
+
810
871
public Builder signature (String signature ) {
811
872
if (signature != null ) {
812
873
this .signature = signature ;
@@ -821,17 +882,18 @@ public Builder startDate(long startDate) {
821
882
822
883
public Builder fromLicenseSpec (License license , String signature ) {
823
884
return uid (license .uid ())
824
- .version (license .version ())
825
- .issuedTo (license .issuedTo ())
826
- .issueDate (license .issueDate ())
827
- .startDate (license .startDate ())
828
- .type (license .type ())
829
- .subscriptionType (license .subscriptionType )
830
- .feature (license .feature )
831
- .maxNodes (license .maxNodes ())
832
- .expiryDate (license .expiryDate ())
833
- .issuer (license .issuer ())
834
- .signature (signature );
885
+ .version (license .version ())
886
+ .issuedTo (license .issuedTo ())
887
+ .issueDate (license .issueDate ())
888
+ .startDate (license .startDate ())
889
+ .type (license .type ())
890
+ .subscriptionType (license .subscriptionType )
891
+ .feature (license .feature )
892
+ .maxNodes (license .maxNodes ())
893
+ .maxResourceUnits (license .maxResourceUnits ())
894
+ .expiryDate (license .expiryDate ())
895
+ .issuer (license .issuer ())
896
+ .signature (signature );
835
897
}
836
898
837
899
/**
@@ -840,15 +902,15 @@ public Builder fromLicenseSpec(License license, String signature) {
840
902
*/
841
903
public Builder fromPre20LicenseSpec (License pre20License ) {
842
904
return uid (pre20License .uid ())
843
- .issuedTo (pre20License .issuedTo ())
844
- .issueDate (pre20License .issueDate ())
845
- .maxNodes (pre20License .maxNodes ())
846
- .expiryDate (pre20License .expiryDate ());
905
+ .issuedTo (pre20License .issuedTo ())
906
+ .issueDate (pre20License .issueDate ())
907
+ .maxNodes (pre20License .maxNodes ())
908
+ .expiryDate (pre20License .expiryDate ());
847
909
}
848
910
849
911
public License build () {
850
912
return new License (version , uid , issuer , issuedTo , issueDate , type ,
851
- subscriptionType , feature , signature , expiryDate , maxNodes , startDate );
913
+ subscriptionType , feature , signature , expiryDate , maxNodes , maxResourceUnits , startDate );
852
914
}
853
915
854
916
public Builder validate () {
@@ -864,11 +926,10 @@ public Builder validate() {
864
926
throw new IllegalStateException ("uid can not be null" );
865
927
} else if (signature == null ) {
866
928
throw new IllegalStateException ("signature can not be null" );
867
- } else if (maxNodes == -1 ) {
868
- throw new IllegalStateException ("maxNodes has to be set" );
869
929
} else if (expiryDate == -1 ) {
870
930
throw new IllegalStateException ("expiryDate has to be set" );
871
931
}
932
+ validateLimits (type , maxNodes , maxResourceUnits );
872
933
return this ;
873
934
}
874
935
0 commit comments