@@ -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
@@ -159,13 +165,14 @@ static boolean isTrial(String typeName) {
159
165
private final long expiryDate ;
160
166
private final long startDate ;
161
167
private final int maxNodes ;
168
+ private final int maxResourceUnits ;
162
169
private final OperationMode operationMode ;
163
170
164
171
/**
165
172
* Decouples operation mode of a license from the license type value.
166
173
* <p>
167
174
* Note: The mode indicates features that should be made available, but it does not indicate whether the license is active!
168
- *
175
+ * <p>
169
176
* The id byte is used for ordering operation modes
170
177
*/
171
178
public enum OperationMode {
@@ -182,13 +189,16 @@ public enum OperationMode {
182
189
this .id = id ;
183
190
}
184
191
185
- /** Returns non-zero positive number when <code>opMode1</code> is greater than <code>opMode2</code> */
192
+ /**
193
+ * Returns non-zero positive number when <code>opMode1</code> is greater than <code>opMode2</code>
194
+ */
186
195
public static int compare (OperationMode opMode1 , OperationMode opMode2 ) {
187
196
return Integer .compare (opMode1 .id , opMode2 .id );
188
197
}
189
198
190
199
/**
191
200
* Determine the operating mode for a license type
201
+ *
192
202
* @see LicenseType#resolve(License)
193
203
* @see #parse(String)
194
204
*/
@@ -217,6 +227,7 @@ public static OperationMode resolve(LicenseType type) {
217
227
* Parses an {@code OperatingMode} from a String.
218
228
* The string must name an operating mode, and not a licensing level (that is, it cannot parse old style license levels
219
229
* such as "dev" or "silver").
230
+ *
220
231
* @see #description()
221
232
*/
222
233
public static OperationMode parse (String mode ) {
@@ -233,8 +244,8 @@ public String description() {
233
244
}
234
245
}
235
246
236
- private License (int version , String uid , String issuer , String issuedTo , long issueDate , String type ,
237
- String subscriptionType , String feature , String signature , long expiryDate , int maxNodes , long startDate ) {
247
+ private License (int version , String uid , String issuer , String issuedTo , long issueDate , String type , String subscriptionType ,
248
+ String feature , String signature , long expiryDate , int maxNodes , int maxResourceUnits , long startDate ) {
238
249
this .version = version ;
239
250
this .uid = uid ;
240
251
this .issuer = issuer ;
@@ -252,6 +263,7 @@ private License(int version, String uid, String issuer, String issuedTo, long is
252
263
this .expiryDate = expiryDate ;
253
264
}
254
265
this .maxNodes = maxNodes ;
266
+ this .maxResourceUnits = maxResourceUnits ;
255
267
this .startDate = startDate ;
256
268
this .operationMode = OperationMode .resolve (LicenseType .resolve (this ));
257
269
validate ();
@@ -300,12 +312,21 @@ public long expiryDate() {
300
312
}
301
313
302
314
/**
303
- * @return the maximum number of nodes this license has been issued for
315
+ * @return the maximum number of nodes this license has been issued for, or {@code -1} if this license is not node based.
304
316
*/
305
317
public int maxNodes () {
306
318
return maxNodes ;
307
319
}
308
320
321
+ /**
322
+ * @return the maximum number of "resource units" this license has been issued for, or {@code -1} if this license is not resource based.
323
+ * A "resource unit" is a measure of computing power (RAM/CPU), the definition of which is maintained outside of the license format,
324
+ * or this class.
325
+ */
326
+ public int maxResourceUnits () {
327
+ return maxResourceUnits ;
328
+ }
329
+
309
330
/**
310
331
* @return a string representing the entity this licenses has been issued to
311
332
*/
@@ -392,20 +413,39 @@ private void validate() {
392
413
throw new IllegalStateException ("uid can not be null" );
393
414
} else if (feature == null && version == VERSION_START ) {
394
415
throw new IllegalStateException ("feature can not be null" );
395
- } else if (maxNodes == -1 ) {
396
- throw new IllegalStateException ("maxNodes has to be set" );
397
416
} else if (expiryDate == -1 ) {
398
417
throw new IllegalStateException ("expiryDate has to be set" );
399
418
} else if (expiryDate == LicenseService .BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS && LicenseType .isBasic (type ) == false ) {
400
419
throw new IllegalStateException ("only basic licenses are allowed to have no expiration" );
401
420
}
421
+
422
+ if (LicenseType .isEnterprise (type ) && version < VERSION_ENTERPRISE ) {
423
+ throw new IllegalStateException ("license type [" + type + "] is not a valid for version [" + version + "] licenses" );
424
+ }
425
+ validateLimits (type , maxNodes , maxResourceUnits );
426
+ }
427
+
428
+ private static void validateLimits (String type , int maxNodes , int maxResourceUnits ) {
429
+ if (LicenseType .isEnterprise (type )) {
430
+ if (maxResourceUnits == -1 ) {
431
+ throw new IllegalStateException ("maxResourceUnits must be set for enterprise licenses (type=[" + type + "])" );
432
+ } else if (maxNodes != -1 ) {
433
+ throw new IllegalStateException ("maxNodes may not be set for enterprise licenses (type=[" + type + "])" );
434
+ }
435
+ } else {
436
+ if (maxNodes == -1 ) {
437
+ throw new IllegalStateException ("maxNodes has to be set" );
438
+ } else if (maxResourceUnits != -1 ) {
439
+ throw new IllegalStateException ("maxResourceUnits may only be set for enterprise licenses (not permitted for type=[" +
440
+ type + "])" );
441
+ }
442
+ }
402
443
}
403
444
404
445
public static License readLicense (StreamInput in ) throws IOException {
405
446
int version = in .readVInt (); // Version for future extensibility
406
447
if (version > VERSION_CURRENT ) {
407
- throw new ElasticsearchException ("Unknown license version found, please upgrade all nodes to the latest elasticsearch-license" +
408
- " plugin" );
448
+ throw new ElasticsearchException ("Unknown license version found, please upgrade all nodes to the latest elasticsearch release" );
409
449
}
410
450
Builder builder = builder ();
411
451
builder .version (version );
@@ -420,6 +460,9 @@ public static License readLicense(StreamInput in) throws IOException {
420
460
}
421
461
builder .expiryDate (in .readLong ());
422
462
builder .maxNodes (in .readInt ());
463
+ if (version >= VERSION_ENTERPRISE ) {
464
+ builder .maxResourceUnits (in .readInt ());
465
+ }
423
466
builder .issuedTo (in .readString ());
424
467
builder .issuer (in .readString ());
425
468
builder .signature (in .readOptionalString ());
@@ -442,6 +485,9 @@ public void writeTo(StreamOutput out) throws IOException {
442
485
}
443
486
out .writeLong (expiryDate );
444
487
out .writeInt (maxNodes );
488
+ if (version >= VERSION_ENTERPRISE ) {
489
+ out .writeInt (maxResourceUnits );
490
+ }
445
491
out .writeString (issuedTo );
446
492
out .writeString (issuer );
447
493
out .writeOptionalString (signature );
@@ -506,7 +552,16 @@ public XContentBuilder toInnerXContent(XContentBuilder builder, Params params) t
506
552
if (expiryDate != LicenseService .BASIC_SELF_GENERATED_LICENSE_EXPIRATION_MILLIS ) {
507
553
builder .timeField (Fields .EXPIRY_DATE_IN_MILLIS , Fields .EXPIRY_DATE , expiryDate );
508
554
}
509
- builder .field (Fields .MAX_NODES , maxNodes );
555
+
556
+ if (version >= VERSION_ENTERPRISE ) {
557
+ builder .field (Fields .MAX_NODES , maxNodes == -1 ? null : maxNodes );
558
+ builder .field (Fields .MAX_RESOURCE_UNITS , maxResourceUnits == -1 ? null : maxResourceUnits );
559
+ } else if (hideEnterprise && maxNodes == -1 ) {
560
+ builder .field (Fields .MAX_NODES , maxResourceUnits );
561
+ } else {
562
+ builder .field (Fields .MAX_NODES , maxNodes );
563
+ }
564
+
510
565
builder .field (Fields .ISSUED_TO , issuedTo );
511
566
builder .field (Fields .ISSUER , issuer );
512
567
if (!licenseSpecMode && !restViewMode && signature != null ) {
@@ -551,6 +606,8 @@ public static License fromXContent(XContentParser parser) throws IOException {
551
606
builder .startDate (parser .longValue ());
552
607
} else if (Fields .MAX_NODES .equals (currentFieldName )) {
553
608
builder .maxNodes (parser .intValue ());
609
+ } else if (Fields .MAX_RESOURCE_UNITS .equals (currentFieldName )) {
610
+ builder .maxResourceUnits (parser .intValue ());
554
611
} else if (Fields .ISSUED_TO .equals (currentFieldName )) {
555
612
builder .issuedTo (parser .text ());
556
613
} else if (Fields .ISSUER .equals (currentFieldName )) {
@@ -593,7 +650,7 @@ public static License fromXContent(XContentParser parser) throws IOException {
593
650
throw new ElasticsearchException ("malformed signature for license [" + builder .uid + "]" );
594
651
} else if (version > VERSION_CURRENT ) {
595
652
throw new ElasticsearchException ("Unknown license version found, please upgrade all nodes to the latest " +
596
- "elasticsearch-license plugin" );
653
+ "elasticsearch-license plugin" );
597
654
}
598
655
// signature version is the source of truth
599
656
builder .version (version );
@@ -625,8 +682,7 @@ public static License fromSource(BytesReference bytes, XContentType xContentType
625
682
// EMPTY is safe here because we don't call namedObject
626
683
try (InputStream byteStream = bytes .streamInput ();
627
684
XContentParser parser = xContentType .xContent ()
628
- .createParser (NamedXContentRegistry .EMPTY , LoggingDeprecationHandler .INSTANCE , byteStream ))
629
- {
685
+ .createParser (NamedXContentRegistry .EMPTY , LoggingDeprecationHandler .INSTANCE , byteStream )) {
630
686
License license = null ;
631
687
if (parser .nextToken () == XContentParser .Token .START_OBJECT ) {
632
688
if (parser .nextToken () == XContentParser .Token .FIELD_NAME ) {
@@ -675,7 +731,7 @@ public boolean equals(Object o) {
675
731
676
732
if (issueDate != license .issueDate ) return false ;
677
733
if (expiryDate != license .expiryDate ) return false ;
678
- if (startDate != license .startDate ) return false ;
734
+ if (startDate != license .startDate ) return false ;
679
735
if (maxNodes != license .maxNodes ) return false ;
680
736
if (version != license .version ) return false ;
681
737
if (uid != null ? !uid .equals (license .uid ) : license .uid != null ) return false ;
@@ -700,7 +756,7 @@ public int hashCode() {
700
756
result = 31 * result + (feature != null ? feature .hashCode () : 0 );
701
757
result = 31 * result + (signature != null ? signature .hashCode () : 0 );
702
758
result = 31 * result + (int ) (expiryDate ^ (expiryDate >>> 32 ));
703
- result = 31 * result + (int ) (startDate ^ (startDate >>> 32 ));
759
+ result = 31 * result + (int ) (startDate ^ (startDate >>> 32 ));
704
760
result = 31 * result + maxNodes ;
705
761
result = 31 * result + version ;
706
762
return result ;
@@ -719,6 +775,7 @@ public static final class Fields {
719
775
public static final String START_DATE_IN_MILLIS = "start_date_in_millis" ;
720
776
public static final String START_DATE = "start_date" ;
721
777
public static final String MAX_NODES = "max_nodes" ;
778
+ public static final String MAX_RESOURCE_UNITS = "max_resource_units" ;
722
779
public static final String ISSUED_TO = "issued_to" ;
723
780
public static final String ISSUER = "issuer" ;
724
781
public static final String VERSION = "version" ;
@@ -762,6 +819,7 @@ public static class Builder {
762
819
private long expiryDate = -1 ;
763
820
private long startDate = -1 ;
764
821
private int maxNodes = -1 ;
822
+ private int maxResourceUnits = -1 ;
765
823
766
824
public Builder uid (String uid ) {
767
825
this .uid = uid ;
@@ -817,6 +875,11 @@ public Builder maxNodes(int maxNodes) {
817
875
return this ;
818
876
}
819
877
878
+ public Builder maxResourceUnits (int maxUnits ) {
879
+ this .maxResourceUnits = maxUnits ;
880
+ return this ;
881
+ }
882
+
820
883
public Builder signature (String signature ) {
821
884
if (signature != null ) {
822
885
this .signature = signature ;
@@ -831,17 +894,18 @@ public Builder startDate(long startDate) {
831
894
832
895
public Builder fromLicenseSpec (License license , String signature ) {
833
896
return uid (license .uid ())
834
- .version (license .version ())
835
- .issuedTo (license .issuedTo ())
836
- .issueDate (license .issueDate ())
837
- .startDate (license .startDate ())
838
- .type (license .type ())
839
- .subscriptionType (license .subscriptionType )
840
- .feature (license .feature )
841
- .maxNodes (license .maxNodes ())
842
- .expiryDate (license .expiryDate ())
843
- .issuer (license .issuer ())
844
- .signature (signature );
897
+ .version (license .version ())
898
+ .issuedTo (license .issuedTo ())
899
+ .issueDate (license .issueDate ())
900
+ .startDate (license .startDate ())
901
+ .type (license .type ())
902
+ .subscriptionType (license .subscriptionType )
903
+ .feature (license .feature )
904
+ .maxNodes (license .maxNodes ())
905
+ .maxResourceUnits (license .maxResourceUnits ())
906
+ .expiryDate (license .expiryDate ())
907
+ .issuer (license .issuer ())
908
+ .signature (signature );
845
909
}
846
910
847
911
/**
@@ -850,15 +914,15 @@ public Builder fromLicenseSpec(License license, String signature) {
850
914
*/
851
915
public Builder fromPre20LicenseSpec (License pre20License ) {
852
916
return uid (pre20License .uid ())
853
- .issuedTo (pre20License .issuedTo ())
854
- .issueDate (pre20License .issueDate ())
855
- .maxNodes (pre20License .maxNodes ())
856
- .expiryDate (pre20License .expiryDate ());
917
+ .issuedTo (pre20License .issuedTo ())
918
+ .issueDate (pre20License .issueDate ())
919
+ .maxNodes (pre20License .maxNodes ())
920
+ .expiryDate (pre20License .expiryDate ());
857
921
}
858
922
859
923
public License build () {
860
924
return new License (version , uid , issuer , issuedTo , issueDate , type ,
861
- subscriptionType , feature , signature , expiryDate , maxNodes , startDate );
925
+ subscriptionType , feature , signature , expiryDate , maxNodes , maxResourceUnits , startDate );
862
926
}
863
927
864
928
public Builder validate () {
@@ -874,11 +938,10 @@ public Builder validate() {
874
938
throw new IllegalStateException ("uid can not be null" );
875
939
} else if (signature == null ) {
876
940
throw new IllegalStateException ("signature can not be null" );
877
- } else if (maxNodes == -1 ) {
878
- throw new IllegalStateException ("maxNodes has to be set" );
879
941
} else if (expiryDate == -1 ) {
880
942
throw new IllegalStateException ("expiryDate has to be set" );
881
943
}
944
+ validateLimits (type , maxNodes , maxResourceUnits );
882
945
return this ;
883
946
}
884
947
0 commit comments