mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-03-02 17:09:18 +00:00
Merge pull request elastic/elasticsearch#2788 from rjernst/license1
Internal: Simplify creation of trial license Original commit: elastic/x-pack-elasticsearch@1c92544b65
This commit is contained in:
commit
8b2cdebf88
@ -15,7 +15,6 @@ import org.elasticsearch.cluster.ClusterStateListener;
|
||||
import org.elasticsearch.cluster.ClusterStateUpdateTask;
|
||||
import org.elasticsearch.cluster.ack.ClusterStateUpdateResponse;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.component.AbstractLifecycleComponent;
|
||||
import org.elasticsearch.common.component.Lifecycle;
|
||||
@ -31,13 +30,6 @@ import org.elasticsearch.license.core.LicenseVerifier;
|
||||
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest;
|
||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.EmptyTransportResponseHandler;
|
||||
import org.elasticsearch.transport.TransportChannel;
|
||||
import org.elasticsearch.transport.TransportRequest;
|
||||
import org.elasticsearch.transport.TransportRequestHandler;
|
||||
import org.elasticsearch.transport.TransportResponse;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.xpack.scheduler.SchedulerEngine;
|
||||
import org.elasticsearch.xpack.support.clock.Clock;
|
||||
|
||||
@ -74,12 +66,11 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
public class LicensesService extends AbstractLifecycleComponent implements ClusterStateListener, LicensesManagerService,
|
||||
LicenseeRegistry, SchedulerEngine.Listener {
|
||||
|
||||
public static final String REGISTER_TRIAL_LICENSE_ACTION_NAME = "internal:plugin/license/cluster/register_trial_license";
|
||||
// pkg private for tests
|
||||
static final TimeValue TRIAL_LICENSE_DURATION = TimeValue.timeValueHours(30 * 24);
|
||||
|
||||
private final ClusterService clusterService;
|
||||
|
||||
private final TransportService transportService;
|
||||
|
||||
/**
|
||||
* Currently active consumers to notify to
|
||||
*/
|
||||
@ -97,11 +88,6 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
*/
|
||||
private List<ExpirationCallback> expirationCallbacks = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Duration of generated trial license
|
||||
*/
|
||||
private TimeValue trialLicenseDuration = TimeValue.timeValueHours(30 * 24);
|
||||
|
||||
/**
|
||||
* Max number of nodes licensed by generated trial license
|
||||
*/
|
||||
@ -120,14 +106,9 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
"please read the following messages and update the license again, this time with the \"acknowledge=true\" parameter:";
|
||||
|
||||
@Inject
|
||||
public LicensesService(Settings settings, ClusterService clusterService, TransportService transportService, Clock clock) {
|
||||
public LicensesService(Settings settings, ClusterService clusterService, Clock clock) {
|
||||
super(settings);
|
||||
this.clusterService = clusterService;
|
||||
this.transportService = transportService;
|
||||
if (DiscoveryNode.isMasterNode(settings)) {
|
||||
transportService.registerRequestHandler(REGISTER_TRIAL_LICENSE_ACTION_NAME, TransportRequest.Empty::new,
|
||||
ThreadPool.Names.SAME, new RegisterTrialLicenseRequestHandler());
|
||||
}
|
||||
populateExpirationCallbacks();
|
||||
this.clock = clock;
|
||||
this.scheduler = new SchedulerEngine(clock);
|
||||
@ -354,7 +335,7 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
* has no signed/trial license
|
||||
*/
|
||||
private void registerTrialLicense() {
|
||||
clusterService.submitStateUpdateTask("generate trial license for [" + trialLicenseDuration + "]", new ClusterStateUpdateTask() {
|
||||
clusterService.submitStateUpdateTask("generate trial license for [" + TRIAL_LICENSE_DURATION + "]", new ClusterStateUpdateTask() {
|
||||
@Override
|
||||
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
|
||||
LicensesMetaData licensesMetaData = newState.metaData().custom(LicensesMetaData.TYPE);
|
||||
@ -376,7 +357,7 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
.issuedTo(clusterService.getClusterName().value())
|
||||
.maxNodes(trialLicenseMaxNodes)
|
||||
.issueDate(issueDate)
|
||||
.expiryDate(issueDate + trialLicenseDuration.getMillis());
|
||||
.expiryDate(issueDate + TRIAL_LICENSE_DURATION.getMillis());
|
||||
License trialLicense = TrialLicense.create(specBuilder);
|
||||
mdBuilder.putCustom(LicensesMetaData.TYPE, new LicensesMetaData(trialLicense));
|
||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
||||
@ -411,7 +392,6 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
|
||||
@Override
|
||||
protected void doClose() throws ElasticsearchException {
|
||||
transportService.removeHandler(REGISTER_TRIAL_LICENSE_ACTION_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -440,9 +420,10 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
}
|
||||
// auto-generate license if no licenses ever existed
|
||||
// this will trigger a subsequent cluster changed event
|
||||
if (prevLicensesMetaData == null
|
||||
&& (currentLicensesMetaData == null || currentLicensesMetaData.getLicense() == null)) {
|
||||
requestTrialLicense(currentClusterState);
|
||||
if (currentClusterState.getNodes().isLocalNodeElectedMaster() &&
|
||||
prevLicensesMetaData == null &&
|
||||
(currentLicensesMetaData == null || currentLicensesMetaData.getLicense() == null)) {
|
||||
registerTrialLicense();
|
||||
}
|
||||
} else if (logger.isDebugEnabled()) {
|
||||
logger.debug("skipped license notifications reason: [{}]", GatewayService.STATE_NOT_RECOVERED_BLOCK);
|
||||
@ -535,25 +516,17 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
&& clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK) == false
|
||||
&& clusterState.nodes().getMasterNode() != null) {
|
||||
final LicensesMetaData currentMetaData = clusterState.metaData().custom(LicensesMetaData.TYPE);
|
||||
if (currentMetaData == null || currentMetaData.getLicense() == null) {
|
||||
if (clusterState.getNodes().isLocalNodeElectedMaster() &&
|
||||
(currentMetaData == null || currentMetaData.getLicense() == null)) {
|
||||
// triggers a cluster changed event
|
||||
// eventually notifying the current licensee
|
||||
requestTrialLicense(clusterState);
|
||||
registerTrialLicense();
|
||||
} else if (lifecycleState() == Lifecycle.State.STARTED) {
|
||||
notifyLicensees(currentMetaData.getLicense());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void requestTrialLicense(final ClusterState currentState) {
|
||||
DiscoveryNode masterNode = currentState.nodes().getMasterNode();
|
||||
if (masterNode == null) {
|
||||
throw new IllegalStateException("master not available when registering auto-generated license");
|
||||
}
|
||||
transportService.sendRequest(masterNode,
|
||||
REGISTER_TRIAL_LICENSE_ACTION_NAME, TransportRequest.Empty.INSTANCE, EmptyTransportResponseHandler.INSTANCE_SAME);
|
||||
}
|
||||
|
||||
License getLicense(final LicensesMetaData metaData) {
|
||||
if (metaData != null) {
|
||||
License license = metaData.getLicense();
|
||||
@ -623,16 +596,4 @@ public class LicensesService extends AbstractLifecycleComponent implements Clust
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Request handler for trial license generation to master
|
||||
*/
|
||||
private class RegisterTrialLicenseRequestHandler implements TransportRequestHandler<TransportRequest.Empty> {
|
||||
|
||||
@Override
|
||||
public void messageReceived(TransportRequest.Empty empty, TransportChannel channel) throws Exception {
|
||||
registerTrialLicense();
|
||||
channel.sendResponse(TransportResponse.Empty.INSTANCE);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
package org.elasticsearch.license.plugin.core;
|
||||
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlocks;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
@ -17,8 +18,6 @@ import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.LocalTransportAddress;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.xpack.scheduler.SchedulerEngine;
|
||||
import org.elasticsearch.xpack.support.clock.ClockMock;
|
||||
import org.junit.Before;
|
||||
|
||||
@ -31,15 +30,15 @@ public abstract class AbstractLicenseServiceTestCase extends ESTestCase {
|
||||
|
||||
protected LicensesService licensesService;
|
||||
protected ClusterService clusterService;
|
||||
protected TransportService transportService;
|
||||
protected ClockMock clock;
|
||||
protected DiscoveryNodes discoveryNodes;
|
||||
|
||||
@Before
|
||||
public void init() throws Exception {
|
||||
clusterService = mock(ClusterService.class);
|
||||
transportService = mock(TransportService.class);
|
||||
clock = new ClockMock();
|
||||
licensesService = new LicensesService(Settings.EMPTY, clusterService, transportService, clock);
|
||||
licensesService = new LicensesService(Settings.EMPTY, clusterService, clock);
|
||||
discoveryNodes = mock(DiscoveryNodes.class);
|
||||
}
|
||||
|
||||
protected void setInitialState(License license) {
|
||||
@ -49,11 +48,13 @@ public abstract class AbstractLicenseServiceTestCase extends ESTestCase {
|
||||
MetaData metaData = mock(MetaData.class);
|
||||
when(metaData.custom(LicensesMetaData.TYPE)).thenReturn(new LicensesMetaData(license));
|
||||
when(state.metaData()).thenReturn(metaData);
|
||||
final DiscoveryNodes discoveryNodes = mock(DiscoveryNodes.class);
|
||||
final DiscoveryNode mockNode = new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
|
||||
when(discoveryNodes.getMasterNode()).thenReturn(mockNode);
|
||||
when(discoveryNodes.isLocalNodeElectedMaster()).thenReturn(false);
|
||||
when(state.nodes()).thenReturn(discoveryNodes);
|
||||
when(state.getNodes()).thenReturn(discoveryNodes); // it is really ridiculous we have nodes() and getNodes()...
|
||||
when(clusterService.state()).thenReturn(state);
|
||||
when(clusterService.lifecycleState()).thenReturn(Lifecycle.State.STARTED);
|
||||
when(clusterService.getClusterName()).thenReturn(new ClusterName("a"));
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.ClusterStateUpdateTask;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
@ -16,18 +17,17 @@ import org.elasticsearch.common.transport.LocalTransportAddress;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.license.core.License;
|
||||
import org.elasticsearch.license.plugin.TestUtils;
|
||||
import org.elasticsearch.transport.EmptyTransportResponseHandler;
|
||||
import org.elasticsearch.transport.TransportRequest;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
import static java.util.Collections.emptySet;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class LicenseClusterChangeTests extends AbstractLicenseServiceTestCase {
|
||||
|
||||
@ -70,11 +70,16 @@ public class LicenseClusterChangeTests extends AbstractLicenseServiceTestCase {
|
||||
DiscoveryNode master = new DiscoveryNode("b", LocalTransportAddress.buildUnique(), emptyMap(), emptySet(), Version.CURRENT);
|
||||
ClusterState oldState = ClusterState.builder(new ClusterName("a"))
|
||||
.nodes(DiscoveryNodes.builder().masterNodeId(master.getId()).put(master)).build();
|
||||
ClusterState newState = ClusterState.builder(oldState).build();
|
||||
when(discoveryNodes.isLocalNodeElectedMaster()).thenReturn(true);
|
||||
ClusterState newState = ClusterState.builder(oldState).nodes(discoveryNodes).build();
|
||||
|
||||
licensesService.clusterChanged(new ClusterChangedEvent("simulated", newState, oldState));
|
||||
verify(transportService, times(2))
|
||||
.sendRequest(any(DiscoveryNode.class),
|
||||
eq(LicensesService.REGISTER_TRIAL_LICENSE_ACTION_NAME),
|
||||
any(TransportRequest.Empty.class), any(EmptyTransportResponseHandler.class));
|
||||
ArgumentCaptor<ClusterStateUpdateTask> stateUpdater = ArgumentCaptor.forClass(ClusterStateUpdateTask.class);
|
||||
verify(clusterService, times(1)).submitStateUpdateTask(any(), stateUpdater.capture());
|
||||
ClusterState stateWithLicense = stateUpdater.getValue().execute(newState);
|
||||
LicensesMetaData licenseMetaData = stateWithLicense.metaData().custom(LicensesMetaData.TYPE);
|
||||
assertNotNull(licenseMetaData);
|
||||
assertNotNull(licenseMetaData.getLicense());
|
||||
assertEquals(clock.millis() + LicensesService.TRIAL_LICENSE_DURATION.millis(), licenseMetaData.getLicense().expiryDate());
|
||||
}
|
||||
}
|
@ -5,31 +5,39 @@
|
||||
*/
|
||||
package org.elasticsearch.license.plugin.core;
|
||||
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.ClusterStateUpdateTask;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.license.plugin.TestUtils;
|
||||
import org.elasticsearch.transport.EmptyTransportResponseHandler;
|
||||
import org.elasticsearch.transport.TransportRequest;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import static org.elasticsearch.mock.orig.Mockito.times;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class LicenseRegistrationTests extends AbstractLicenseServiceTestCase {
|
||||
|
||||
public void testTrialLicenseRequestOnEmptyLicenseState() throws Exception {
|
||||
setInitialState(null);
|
||||
when(discoveryNodes.isLocalNodeElectedMaster()).thenReturn(true);
|
||||
|
||||
TestUtils.AssertingLicensee licensee = new TestUtils.AssertingLicensee(
|
||||
"testTrialLicenseRequestOnEmptyLicenseState", logger);
|
||||
licensesService.start();
|
||||
licensesService.register(licensee);
|
||||
verify(transportService, times(1))
|
||||
.sendRequest(any(DiscoveryNode.class),
|
||||
eq(LicensesService.REGISTER_TRIAL_LICENSE_ACTION_NAME),
|
||||
any(TransportRequest.Empty.class), any(EmptyTransportResponseHandler.class));
|
||||
assertThat(licensee.statuses.size(), equalTo(0));
|
||||
|
||||
ClusterState state = ClusterState.builder(new ClusterName("a")).build();
|
||||
ArgumentCaptor<ClusterStateUpdateTask> stateUpdater = ArgumentCaptor.forClass(ClusterStateUpdateTask.class);
|
||||
verify(clusterService, Mockito.times(1)).submitStateUpdateTask(any(), stateUpdater.capture());
|
||||
ClusterState stateWithLicense = stateUpdater.getValue().execute(state);
|
||||
LicensesMetaData licenseMetaData = stateWithLicense.metaData().custom(LicensesMetaData.TYPE);
|
||||
assertNotNull(licenseMetaData);
|
||||
assertNotNull(licenseMetaData.getLicense());
|
||||
assertEquals(clock.millis() + LicensesService.TRIAL_LICENSE_DURATION.millis(), licenseMetaData.getLicense().expiryDate());
|
||||
|
||||
licensesService.stop();
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,10 @@
|
||||
*/
|
||||
package org.elasticsearch.license.plugin.core;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.cluster.ClusterStateUpdateTask;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
@ -13,10 +17,6 @@ import org.elasticsearch.license.plugin.TestUtils;
|
||||
import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
||||
import org.elasticsearch.license.plugin.action.put.PutLicenseResponse;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.license.plugin.TestUtils.generateSignedLicense;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
|
@ -106,5 +106,4 @@ internal:indices/flush/synced/in_flight
|
||||
internal:indices/flush/synced/pre
|
||||
internal:indices/flush/synced/sync
|
||||
internal:admin/repository/verify
|
||||
internal:plugin/license/cluster/register_trial_license
|
||||
internal:transport/handshake
|
||||
|
Loading…
x
Reference in New Issue
Block a user