@@ -413,14 +413,6 @@ public void clusterChanged(ClusterChangedEvent event) {
413413 final ClusterState previousClusterState = event .previousState ();
414414 final ClusterState currentClusterState = event .state ();
415415 if (currentClusterState .blocks ().hasGlobalBlock (GatewayService .STATE_NOT_RECOVERED_BLOCK ) == false ) {
416- if (XPackPlugin .isReadyForXPackCustomMetadata (currentClusterState ) == false ) {
417- logger .debug (
418- "cannot add license to cluster as the following nodes might not understand the license metadata: {}" ,
419- () -> XPackPlugin .nodesNotReadyForXPackCustomMetadata (currentClusterState )
420- );
421- return ;
422- }
423-
424416 final LicensesMetadata prevLicensesMetadata = previousClusterState .getMetadata ().custom (LicensesMetadata .TYPE );
425417 final LicensesMetadata currentLicensesMetadata = currentClusterState .getMetadata ().custom (LicensesMetadata .TYPE );
426418 // notify all interested plugins
@@ -439,26 +431,7 @@ public void clusterChanged(ClusterChangedEvent event) {
439431 } else {
440432 logger .trace ("license unchanged [{}]" , currentLicensesMetadata );
441433 }
442-
443- License currentLicense = null ;
444- boolean noLicenseInPrevMetadata = prevLicensesMetadata == null || prevLicensesMetadata .getLicense () == null ;
445- if (noLicenseInPrevMetadata == false ) {
446- currentLicense = prevLicensesMetadata .getLicense ();
447- }
448- boolean noLicenseInCurrentMetadata = (currentLicensesMetadata == null || currentLicensesMetadata .getLicense () == null );
449- if (noLicenseInCurrentMetadata == false ) {
450- currentLicense = currentLicensesMetadata .getLicense ();
451- }
452-
453- boolean noLicense = noLicenseInPrevMetadata && noLicenseInCurrentMetadata ;
454- // auto-generate license if no licenses ever existed or if the current license is basic and
455- // needs extended or if the license signature needs to be updated. this will trigger a subsequent cluster changed event
456- if (currentClusterState .getNodes ().isLocalNodeElectedMaster ()
457- && (noLicense
458- || LicenseUtils .licenseNeedsExtended (currentLicense )
459- || LicenseUtils .signatureNeedsUpdate (currentLicense , currentClusterState .nodes ()))) {
460- registerOrUpdateSelfGeneratedLicense ();
461- }
434+ maybeRegisterOrUpdateLicense (previousClusterState , currentClusterState );
462435 } else if (logger .isDebugEnabled ()) {
463436 logger .debug ("skipped license notifications reason: [{}]" , GatewayService .STATE_NOT_RECOVERED_BLOCK );
464437 }
@@ -468,24 +441,38 @@ private void updateXPackLicenseState(License license) {
468441 if (license == LicensesMetadata .LICENSE_TOMBSTONE ) {
469442 // implies license has been explicitly deleted
470443 xPacklicenseState .update (LicenseUtils .getXPackLicenseStatus (license , clock ));
471- return ;
472- }
473- checkForExpiredLicense (license );
474- }
475-
476- private boolean checkForExpiredLicense (License license ) {
477- if (license != null ) {
444+ } else if (license != null ) {
478445 XPackLicenseStatus xPackLicenseStatus = LicenseUtils .getXPackLicenseStatus (license , clock );
479446 xPacklicenseState .update (xPackLicenseStatus );
480447 if (xPackLicenseStatus .active ()) {
481448 logger .debug ("license [{}] - valid" , license .uid ());
482- return false ;
483449 } else {
484450 logger .warn ("license [{}] - expired" , license .uid ());
485- return true ;
486451 }
487452 }
488- return false ;
453+ }
454+
455+ private void maybeRegisterOrUpdateLicense (ClusterState previousClusterState , ClusterState currentClusterState ) {
456+ final LicensesMetadata prevLicensesMetadata = previousClusterState .getMetadata ().custom (LicensesMetadata .TYPE );
457+ final LicensesMetadata currentLicensesMetadata = currentClusterState .getMetadata ().custom (LicensesMetadata .TYPE );
458+ License currentLicense = null ;
459+ boolean noLicenseInPrevMetadata = prevLicensesMetadata == null || prevLicensesMetadata .getLicense () == null ;
460+ if (noLicenseInPrevMetadata == false ) {
461+ currentLicense = prevLicensesMetadata .getLicense ();
462+ }
463+ boolean noLicenseInCurrentMetadata = (currentLicensesMetadata == null || currentLicensesMetadata .getLicense () == null );
464+ if (noLicenseInCurrentMetadata == false ) {
465+ currentLicense = currentLicensesMetadata .getLicense ();
466+ }
467+ boolean noLicense = noLicenseInPrevMetadata && noLicenseInCurrentMetadata ;
468+ // auto-generate license if no licenses ever existed or if the current license is basic and
469+ // needs extended or if the license signature needs to be updated. this will trigger a subsequent cluster changed event
470+ if (currentClusterState .getNodes ().isLocalNodeElectedMaster ()
471+ && (noLicense
472+ || LicenseUtils .licenseNeedsExtended (currentLicense )
473+ || LicenseUtils .signatureNeedsUpdate (currentLicense , currentClusterState .nodes ()))) {
474+ registerOrUpdateSelfGeneratedLicense ();
475+ }
489476 }
490477
491478 /**
@@ -496,12 +483,14 @@ private boolean checkForExpiredLicense(License license) {
496483 */
497484 private void onUpdate (final LicensesMetadata currentLicensesMetadata ) {
498485 final License license = getLicenseFromLicensesMetadata (currentLicensesMetadata );
486+ // first update the XPackLicenseState
487+ updateXPackLicenseState (license );
499488 // license can be null if the trial license is yet to be auto-generated
500489 // in this case, it is a no-op
501490 if (license != null ) {
502- final License previousLicense = currentLicenseHolder .get ( );
491+ final License previousLicense = currentLicenseHolder .getAndSet ( license );
503492 if (license .equals (previousLicense ) == false ) {
504- currentLicenseHolder . set ( license );
493+ // then register periodic job to update the XPackLicenseState with the latest expiration message
505494 scheduler .add (new SchedulerEngine .Job (LICENSE_JOB , nextLicenseCheck (license )));
506495 for (ExpirationCallback expirationCallback : expirationCallbacks ) {
507496 scheduler .add (
@@ -517,24 +506,25 @@ private void onUpdate(final LicensesMetadata currentLicensesMetadata) {
517506 }
518507 logger .info ("license [{}] mode [{}] - valid" , license .uid (), license .operationMode ().name ().toLowerCase (Locale .ROOT ));
519508 }
520- updateXPackLicenseState (license );
521509 }
522510 }
523511
524512 // pkg private for tests
525513 SchedulerEngine .Schedule nextLicenseCheck (License license ) {
514+ final long licenseIssueDate = license .issueDate ();
515+ final long licenseExpiryDate = LicenseUtils .getExpiryDate (license );
526516 return (startTime , time ) -> {
527- if (time < license . issueDate () ) {
517+ if (time < licenseIssueDate ) {
528518 // when we encounter a license with a future issue date
529519 // which can happen with autogenerated license,
530520 // we want to schedule a notification on the license issue date
531521 // so the license is notified once it is valid
532522 // see https://github.com/elastic/x-plugins/issues/983
533- return license . issueDate () ;
534- } else if (time < LicenseUtils . getExpiryDate ( license ) ) {
523+ return licenseIssueDate ;
524+ } else if (time < licenseExpiryDate ) {
535525 // Re-check the license every day during the warning period up to the license expiration.
536526 // This will cause the warning message to be updated that is emitted on soon-expiring license use.
537- long nextTime = LicenseUtils . getExpiryDate ( license ) - LicenseSettings .LICENSE_EXPIRATION_WARNING_PERIOD .getMillis ();
527+ long nextTime = licenseExpiryDate - LicenseSettings .LICENSE_EXPIRATION_WARNING_PERIOD .getMillis ();
538528 while (nextTime <= time ) {
539529 nextTime += TimeValue .timeValueDays (1 ).getMillis ();
540530 }
@@ -550,6 +540,7 @@ public License getLicense(final Metadata metadata) {
550540 }
551541
552542 // visible for tests
543+ @ Nullable
553544 License getLicenseFromLicensesMetadata (@ Nullable final LicensesMetadata metadata ) {
554545 if (metadata != null ) {
555546 License license = metadata .getLicense ();
@@ -558,6 +549,13 @@ License getLicenseFromLicensesMetadata(@Nullable final LicensesMetadata metadata
558549 } else if (license != null ) {
559550 if (license .verified ()) {
560551 return license ;
552+ } else {
553+ // this is an "error" level because an unverified license should not be present in the cluster state in the first place
554+ logger .error (
555+ "{} with uid [{}] failed verification on the local node." ,
556+ License .isAutoGeneratedLicense (license .signature ()) ? "Autogenerated license" : "License" ,
557+ license .uid ()
558+ );
561559 }
562560 }
563561 }
0 commit comments