Simplify ml license checking with XpackLicenseState internals (#52684) (#52863)

This change removes TrainedModelConfig#isAvailableWithLicense method with calls to
XPackLicenseState#isAllowedByLicense.

Please note there are subtle changes to the code logic. But they are the right changes:
* Instead of Platinum license, Enterprise license nows guarantees availability.
* No explicit check when the license requirement is basic. Since basic license is always available, this check is unnecessary.
* Trial license is always allowed.
This commit is contained in:
Yang Wang 2020-02-27 14:14:16 +11:00 committed by GitHub
parent fa701e4c1f
commit 14c21aedd2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 2 additions and 85 deletions

View File

@ -21,7 +21,6 @@ import org.elasticsearch.common.xcontent.ToXContentObject;
import org.elasticsearch.common.xcontent.XContentBuilder; import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.license.License; import org.elasticsearch.license.License;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.xpack.core.common.time.TimeUtils; import org.elasticsearch.xpack.core.common.time.TimeUtils;
import org.elasticsearch.xpack.core.ml.inference.persistence.InferenceIndexConstants; import org.elasticsearch.xpack.core.ml.inference.persistence.InferenceIndexConstants;
import org.elasticsearch.xpack.core.ml.job.messages.Messages; import org.elasticsearch.xpack.core.ml.job.messages.Messages;
@ -236,21 +235,6 @@ public class TrainedModelConfig implements ToXContentObject, Writeable {
return licenseLevel; return licenseLevel;
} }
public boolean isAvailableWithLicense(XPackLicenseState licenseState) {
// Basic is always true
if (licenseLevel.equals(License.OperationMode.BASIC)) {
return true;
}
// The model license does not matter, Platinum license gets the same functions as the highest license
if (licenseState.isAllowedByLicense(License.OperationMode.PLATINUM)) {
return true;
}
// catch the rest, if the license is active and is at least the required model license
return licenseState.isAllowedByLicense(licenseLevel, true, false);
}
@Override @Override
public void writeTo(StreamOutput out) throws IOException { public void writeTo(StreamOutput out) throws IOException {
out.writeString(modelId); out.writeString(modelId);

View File

@ -20,7 +20,6 @@ import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.license.License; import org.elasticsearch.license.License;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.search.SearchModule; import org.elasticsearch.search.SearchModule;
import org.elasticsearch.test.AbstractSerializingTestCase; import org.elasticsearch.test.AbstractSerializingTestCase;
import org.elasticsearch.xpack.core.ml.job.messages.Messages; import org.elasticsearch.xpack.core.ml.job.messages.Messages;
@ -44,10 +43,6 @@ import static org.elasticsearch.xpack.core.ml.utils.ToXContentParams.FOR_INTERNA
import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyBoolean;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class TrainedModelConfigTests extends AbstractSerializingTestCase<TrainedModelConfig> { public class TrainedModelConfigTests extends AbstractSerializingTestCase<TrainedModelConfig> {
@ -306,66 +301,4 @@ public class TrainedModelConfigTests extends AbstractSerializingTestCase<Trained
.assertToXContentEquivalence(true) .assertToXContentEquivalence(true)
.test(); .test();
} }
public void testIsAvailableWithLicense() {
TrainedModelConfig.Builder builder = createTestInstance(randomAlphaOfLength(10));
XPackLicenseState licenseState = mock(XPackLicenseState.class);
// Reject everything
when(licenseState.isAllowedByLicense(any(License.OperationMode.class), anyBoolean(), anyBoolean())).thenAnswer(
invocationOnMock -> {
final Object[] arguments = invocationOnMock.getArguments();
assertTrue((boolean) arguments[1]); // ensure the call is made to require active license
return false;
}
);
assertFalse(builder.setLicenseLevel(License.OperationMode.ENTERPRISE.description()).build().isAvailableWithLicense(licenseState));
assertFalse(builder.setLicenseLevel(License.OperationMode.PLATINUM.description()).build().isAvailableWithLicense(licenseState));
assertFalse(builder.setLicenseLevel(License.OperationMode.GOLD.description()).build().isAvailableWithLicense(licenseState));
// Basic license always works not matter what
assertTrue(builder.setLicenseLevel(License.OperationMode.BASIC.description()).build().isAvailableWithLicense(licenseState));
}
public void testActivePlatinumLicenseAlwaysWorks() {
TrainedModelConfig.Builder builder = createTestInstance(randomAlphaOfLength(10));
XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isAllowedByLicense(License.OperationMode.PLATINUM)).thenReturn(true);
// Active Platinum license functions the same as Enterprise license (highest) and should always work
when(licenseState.isAllowedByLicense(any(License.OperationMode.class), anyBoolean(), anyBoolean())).thenAnswer(
invocationOnMock -> {
final Object[] arguments = invocationOnMock.getArguments();
assertEquals(License.OperationMode.PLATINUM, arguments[0]);
assertTrue((boolean) arguments[1]); // ensure the call is made to require active license
assertTrue((boolean) arguments[2]);
return true;
}
);
assertTrue(builder.setLicenseLevel(License.OperationMode.ENTERPRISE.description()).build().isAvailableWithLicense(licenseState));
assertTrue(builder.setLicenseLevel(License.OperationMode.PLATINUM.description()).build().isAvailableWithLicense(licenseState));
assertTrue(builder.setLicenseLevel(License.OperationMode.BASIC.description()).build().isAvailableWithLicense(licenseState));
assertTrue(builder.setLicenseLevel(License.OperationMode.GOLD.description()).build().isAvailableWithLicense(licenseState));
}
public void testActiveGoldLicenseWillWorkWhenRequiredLevelIsGold() {
TrainedModelConfig.Builder builder = createTestInstance(randomAlphaOfLength(10));
XPackLicenseState licenseState = mock(XPackLicenseState.class);
// Active Gold license should work when required level is gold
when(licenseState.isAllowedByLicense(any(License.OperationMode.class), anyBoolean(), anyBoolean())).thenAnswer(
invocationOnMock -> {
final Object[] arguments = invocationOnMock.getArguments();
assertTrue((boolean) arguments[1]); // ensure the call is made to require active license
if (License.OperationMode.PLATINUM == arguments[0] && Boolean.TRUE.equals(arguments[2])) {
return false;
} else
return License.OperationMode.GOLD == arguments[0] && Boolean.FALSE.equals(arguments[2]);
}
);
assertFalse(builder.setLicenseLevel(License.OperationMode.ENTERPRISE.description()).build().isAvailableWithLicense(licenseState));
assertFalse(builder.setLicenseLevel(License.OperationMode.PLATINUM.description()).build().isAvailableWithLicense(licenseState));
assertTrue(builder.setLicenseLevel(License.OperationMode.BASIC.description()).build().isAvailableWithLicense(licenseState));
assertTrue(builder.setLicenseLevel(License.OperationMode.GOLD.description()).build().isAvailableWithLicense(licenseState));
}
} }

View File

@ -79,8 +79,8 @@ public class TransportInternalInferModelAction extends HandledTransportAction<Re
} else { } else {
trainedModelProvider.getTrainedModel(request.getModelId(), false, ActionListener.wrap( trainedModelProvider.getTrainedModel(request.getModelId(), false, ActionListener.wrap(
trainedModelConfig -> { trainedModelConfig -> {
responseBuilder.setLicensed(trainedModelConfig.isAvailableWithLicense(licenseState)); responseBuilder.setLicensed(licenseState.isAllowedByLicense(trainedModelConfig.getLicenseLevel()));
if (trainedModelConfig.isAvailableWithLicense(licenseState) || request.isPreviouslyLicensed()) { if (licenseState.isAllowedByLicense(trainedModelConfig.getLicenseLevel()) || request.isPreviouslyLicensed()) {
this.modelLoadingService.getModel(request.getModelId(), getModelListener); this.modelLoadingService.getModel(request.getModelId(), getModelListener);
} else { } else {
listener.onFailure(LicenseUtils.newComplianceException(XPackField.MACHINE_LEARNING)); listener.onFailure(LicenseUtils.newComplianceException(XPackField.MACHINE_LEARNING));