implemented Trial licenses
Original commit: elastic/x-pack-elasticsearch@64b987a991
This commit is contained in:
parent
f05ccaa3f9
commit
6b208bce8f
|
@ -252,7 +252,15 @@ public class ESLicenseManager {
|
|||
return convertToESLicense(license);
|
||||
}
|
||||
|
||||
ESLicense decryptAndVerifyESLicense(SignedLicense signedLicense, String signature) {
|
||||
return convertToESLicense(this.licenseManager.decryptAndVerifyLicense(signedLicense), signature);
|
||||
}
|
||||
|
||||
static ESLicense convertToESLicense(License license) {
|
||||
return convertToESLicense(license, null);
|
||||
}
|
||||
|
||||
static ESLicense convertToESLicense(License license, String signature) {
|
||||
final LicenseBuilders.LicenseBuilder licenseBuilder = LicenseBuilders.licenseBuilder(false);
|
||||
licenseBuilder
|
||||
.expiryDate(license.getGoodBeforeDate())
|
||||
|
@ -261,6 +269,10 @@ public class ESLicenseManager {
|
|||
.issuedTo(license.getHolder())
|
||||
.issuer(license.getIssuer());
|
||||
|
||||
if (signature != null) {
|
||||
licenseBuilder.signature(signature);
|
||||
}
|
||||
|
||||
assert license.getFeatures().size() == 4 : "one license should have only four feature";
|
||||
String maxNodesPrefix = "maxNodes:";
|
||||
String typePrefix = "type:";
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
package org.elasticsearch.license.manager;
|
||||
|
||||
import net.nicholaswilliams.java.licensing.LicenseManager;
|
||||
import net.nicholaswilliams.java.licensing.ObjectSerializer;
|
||||
import net.nicholaswilliams.java.licensing.SignedLicense;
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
@ -20,22 +19,22 @@ import static org.elasticsearch.license.core.ESLicenses.ESLicense;
|
|||
|
||||
public class Utils {
|
||||
|
||||
public static ESLicenses getESLicensesFromSignatures(final LicenseManager licenseManager, Set<String> signatures) {
|
||||
public static ESLicenses getESLicensesFromSignatures(final Set<String> signatures) {
|
||||
final LicenseBuilders.LicensesBuilder licensesBuilder = LicenseBuilders.licensesBuilder();
|
||||
for (String signature : signatures) {
|
||||
licensesBuilder.license(getESLicenseFromSignature(licenseManager, signature));
|
||||
licensesBuilder.license(getESLicenseFromSignature(signature));
|
||||
}
|
||||
return licensesBuilder.build();
|
||||
}
|
||||
|
||||
private static ESLicense getESLicenseFromSignature(LicenseManager licenseManager, String signature) {
|
||||
private static ESLicense getESLicenseFromSignature(String signature) {
|
||||
byte[] signatureBytes = Base64.decodeBase64(signature);
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(signatureBytes);
|
||||
byteBuffer = (ByteBuffer) byteBuffer.position(13);
|
||||
int start = byteBuffer.getInt();
|
||||
SignedLicense signedLicense = new ObjectSerializer()
|
||||
.readObject(SignedLicense.class, Arrays.copyOfRange(signatureBytes, start, signatureBytes.length));
|
||||
return ESLicenseManager.convertToESLicense(licenseManager.decryptAndVerifyLicense(signedLicense));
|
||||
return ESLicenseManager.getInstance().decryptAndVerifyESLicense(signedLicense, signature);
|
||||
}
|
||||
|
||||
public static boolean isSame(ESLicenses firstLicenses, ESLicenses secondLicenses) {
|
||||
|
|
|
@ -10,16 +10,19 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
|||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.license.core.ESLicenses;
|
||||
import org.elasticsearch.license.core.LicenseBuilders;
|
||||
import org.elasticsearch.license.plugin.core.TrialLicenses;
|
||||
import org.elasticsearch.license.plugin.core.TrialLicensesBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.elasticsearch.license.core.ESLicenses.*;
|
||||
import static org.elasticsearch.license.plugin.core.TrialLicenses.TrialLicense;
|
||||
|
||||
public class Utils {
|
||||
|
||||
|
||||
public static ESLicenses readLicensesFrom(StreamInput in) throws IOException {
|
||||
public static ESLicenses readGeneratedLicensesFrom(StreamInput in) throws IOException {
|
||||
final LicenseBuilders.LicensesBuilder licensesBuilder = LicenseBuilders.licensesBuilder();
|
||||
boolean exists = in.readBoolean();
|
||||
if (exists) {
|
||||
|
@ -32,7 +35,7 @@ public class Utils {
|
|||
return null;
|
||||
}
|
||||
|
||||
public static void writeLicensesTo(ESLicenses esLicenses, StreamOutput out) throws IOException {
|
||||
public static void writeGeneratedLicensesTo(ESLicenses esLicenses, StreamOutput out) throws IOException {
|
||||
if (esLicenses == null) {
|
||||
out.writeBoolean(false);
|
||||
return;
|
||||
|
@ -44,6 +47,52 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
public static TrialLicenses readTrialLicensesFrom(StreamInput in) throws IOException {
|
||||
final TrialLicensesBuilder licensesBuilder = TrialLicensesBuilder.trialLicensesBuilder();
|
||||
boolean exists = in.readBoolean();
|
||||
if (exists) {
|
||||
int size = in.readVInt();
|
||||
for (int i = 0; i < size; i++) {
|
||||
licensesBuilder.license(trialLicenseFromMap(in.readMap()));
|
||||
}
|
||||
return licensesBuilder.build();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void writeTrialLicensesTo(TrialLicenses trialLicenses, StreamOutput out) throws IOException {
|
||||
if (trialLicenses == null) {
|
||||
out.writeBoolean(false);
|
||||
return;
|
||||
}
|
||||
out.writeBoolean(true);
|
||||
out.writeVInt(trialLicenses.trialLicenses().size());
|
||||
for (TrialLicense trialLicense : trialLicenses) {
|
||||
out.writeMap(trialLicenseAsMap(trialLicense));
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> trialLicenseAsMap(TrialLicense trialLicense) {
|
||||
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||
builder.put(TrialLicenseFields.UID, trialLicense.uid());
|
||||
builder.put(TrialLicenseFields.ISSUE_DATE, trialLicense.issueDate());
|
||||
builder.put(TrialLicenseFields.EXPIRY_DATE, trialLicense.expiryDate());
|
||||
builder.put(TrialLicenseFields.MAX_NODES, trialLicense.maxNodes());
|
||||
builder.put(TrialLicenseFields.FEATURE, trialLicense.feature().string());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static TrialLicense trialLicenseFromMap(Map<String, Object> map) {
|
||||
return TrialLicensesBuilder.trialLicenseBuilder()
|
||||
.uid((String) map.get(TrialLicenseFields.UID))
|
||||
.maxNodes((int) map.get(TrialLicenseFields.MAX_NODES))
|
||||
.feature(FeatureType.fromString((String) map.get(TrialLicenseFields.FEATURE)))
|
||||
.issueDate((long) map.get(TrialLicenseFields.ISSUE_DATE))
|
||||
.expiryDate((long) map.get(TrialLicenseFields.EXPIRY_DATE))
|
||||
.build();
|
||||
|
||||
}
|
||||
|
||||
public static Map<String, Object> licenseAsMap(ESLicense esLicense) {
|
||||
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
|
||||
builder.put(LicenseFields.UID, esLicense.uid());
|
||||
|
@ -73,6 +122,15 @@ public class Utils {
|
|||
|
||||
}
|
||||
|
||||
final static class TrialLicenseFields {
|
||||
private final static String UID = "uid";
|
||||
private final static String ISSUE_DATE = "issue_date";
|
||||
private final static String EXPIRY_DATE = "expiry_date";
|
||||
private final static String MAX_NODES = "max_nodes";
|
||||
private final static String FEATURE = "feature";
|
||||
|
||||
}
|
||||
|
||||
final static class LicenseFields {
|
||||
private final static String UID = "uid";
|
||||
private final static String TYPE = "type";
|
||||
|
|
|
@ -13,8 +13,8 @@ import org.elasticsearch.license.core.LicenseBuilders;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.license.plugin.action.Utils.readLicensesFrom;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.writeLicensesTo;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.readGeneratedLicensesFrom;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.writeGeneratedLicensesTo;
|
||||
|
||||
public class GetLicenseResponse extends ActionResponse {
|
||||
|
||||
|
@ -34,13 +34,13 @@ public class GetLicenseResponse extends ActionResponse {
|
|||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
licenses = readLicensesFrom(in);
|
||||
licenses = readGeneratedLicensesFrom(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
writeLicensesTo(licenses, out);
|
||||
writeGeneratedLicensesTo(licenses, out);
|
||||
}
|
||||
|
||||
}
|
|
@ -53,6 +53,10 @@ public class TransportGetLicenseAction extends TransportMasterNodeReadOperationA
|
|||
protected void masterOperation(final GetLicenseRequest request, ClusterState state, final ActionListener<GetLicenseResponse> listener) throws ElasticsearchException {
|
||||
MetaData metaData = state.metaData();
|
||||
LicensesMetaData licenses = metaData.custom(LicensesMetaData.TYPE);
|
||||
listener.onResponse(new GetLicenseResponse(licenses));
|
||||
if (licenses != null) {
|
||||
listener.onResponse(new GetLicenseResponse(licenses.getLicenses()));
|
||||
} else {
|
||||
listener.onResponse(new GetLicenseResponse());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,8 +15,8 @@ import org.elasticsearch.license.core.LicenseUtils;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.elasticsearch.license.plugin.action.Utils.readLicensesFrom;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.writeLicensesTo;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.readGeneratedLicensesFrom;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.writeGeneratedLicensesTo;
|
||||
|
||||
public class PutLicenseRequest extends AcknowledgedRequest<PutLicenseRequest> {
|
||||
|
||||
|
@ -54,14 +54,14 @@ public class PutLicenseRequest extends AcknowledgedRequest<PutLicenseRequest> {
|
|||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
license = readLicensesFrom(in);
|
||||
license = readGeneratedLicensesFrom(in);
|
||||
readTimeout(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
writeLicensesTo(license, out);
|
||||
writeGeneratedLicensesTo(license, out);
|
||||
writeTimeout(out);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
package org.elasticsearch.license.plugin.core;
|
||||
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.ElasticsearchIllegalArgumentException;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.common.collect.ImmutableMap;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
|
@ -14,39 +14,87 @@ import org.elasticsearch.common.xcontent.ToXContent;
|
|||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.license.core.ESLicenses;
|
||||
import org.elasticsearch.license.core.LicenseBuilders;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import static org.elasticsearch.license.core.ESLicenses.ESLicense;
|
||||
import static org.elasticsearch.license.core.ESLicenses.FeatureType;
|
||||
import static org.elasticsearch.license.plugin.action.Utils.*;
|
||||
import static org.elasticsearch.license.plugin.core.TrialLicenses.TrialLicense;
|
||||
|
||||
/**
|
||||
* Contains metadata about registered licenses
|
||||
*
|
||||
* TODO: add trial licenses to MetaData
|
||||
* TODO: store only signatures rather than the whole licenses json in cluster state
|
||||
*/
|
||||
public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicenses {
|
||||
public class LicensesMetaData implements MetaData.Custom {
|
||||
|
||||
public static final String TYPE = "licenses";
|
||||
|
||||
public static final Factory FACTORY = new Factory();
|
||||
|
||||
private final ImmutableMap<FeatureType, ESLicense> licenses;
|
||||
private final ImmutableMap<FeatureType, ESLicense> licensesMap;
|
||||
|
||||
private final ImmutableMap<FeatureType, TrialLicense> trialLicensesMap;
|
||||
|
||||
/**
|
||||
* Constructs new licenses metadata
|
||||
*
|
||||
* @param esLicenses list of esLicense
|
||||
*/
|
||||
public LicensesMetaData(List<ESLicense> esLicenses) {
|
||||
this.licenses = map(esLicenses);
|
||||
public LicensesMetaData(ESLicenses esLicenses, TrialLicenses trialLicenses) {
|
||||
this.licensesMap = map(esLicenses);
|
||||
this.trialLicensesMap = map(trialLicenses);
|
||||
}
|
||||
|
||||
public LicensesMetaData(ESLicenses esLicenses) {
|
||||
this.licenses = map(esLicenses);
|
||||
|
||||
public ESLicenses getLicenses() {
|
||||
return new ESLicenses() {
|
||||
@Override
|
||||
public Collection<ESLicense> licenses() {
|
||||
return licensesMap.values();
|
||||
}
|
||||
|
||||
private static ImmutableMap<FeatureType, ESLicense> map(Iterable<ESLicense> esLicenses) {
|
||||
@Override
|
||||
public Set<FeatureType> features() {
|
||||
return licensesMap.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ESLicense get(FeatureType featureType) {
|
||||
return licensesMap.get(featureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ESLicense> iterator() {
|
||||
return licensesMap.values().iterator();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public TrialLicenses getTrialLicenses() {
|
||||
return new TrialLicenses() {
|
||||
@Override
|
||||
public Collection<TrialLicense> trialLicenses() {
|
||||
return trialLicensesMap.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrialLicense getTrialLicense(FeatureType featureType) {
|
||||
return trialLicensesMap.get(featureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TrialLicense> iterator() {
|
||||
return trialLicensesMap.values().iterator();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private static ImmutableMap<FeatureType, ESLicense> map(ESLicenses esLicenses) {
|
||||
final ImmutableMap.Builder<FeatureType, ESLicense> builder = ImmutableMap.builder();
|
||||
if (esLicenses != null) {
|
||||
for (ESLicense esLicense : esLicenses) {
|
||||
|
@ -56,37 +104,14 @@ public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicen
|
|||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ESLicense> licenses() {
|
||||
return licenses.values();
|
||||
private static ImmutableMap<FeatureType, TrialLicense> map(TrialLicenses trialLicenses) {
|
||||
final ImmutableMap.Builder<FeatureType, TrialLicense> builder = ImmutableMap.builder();
|
||||
if (trialLicenses != null) {
|
||||
for (TrialLicense esLicense : trialLicenses) {
|
||||
builder.put(esLicense.feature(), esLicense);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<FeatureType> features() {
|
||||
return licenses.keySet();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ESLicense get(FeatureType featureType) {
|
||||
return licenses.get(featureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ESLicense> iterator() {
|
||||
return licenses.values().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TrialLicense> trialLicenses() {
|
||||
//todo trial license functionality
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TrialLicense getTrialLicense(FeatureType featureType) {
|
||||
//todo trial license functionality
|
||||
return null;
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,7 +132,13 @@ public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicen
|
|||
*/
|
||||
@Override
|
||||
public LicensesMetaData readFrom(StreamInput in) throws IOException {
|
||||
return new LicensesMetaData(readLicensesFrom(in));
|
||||
ESLicenses esLicenses = null;
|
||||
TrialLicenses trialLicenses = null;
|
||||
if (in.readBoolean()) {
|
||||
esLicenses = readGeneratedLicensesFrom(in);
|
||||
trialLicenses = readTrialLicensesFrom(in);
|
||||
}
|
||||
return new LicensesMetaData(esLicenses, trialLicenses);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -115,7 +146,13 @@ public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicen
|
|||
*/
|
||||
@Override
|
||||
public void writeTo(LicensesMetaData licensesMetaData, StreamOutput out) throws IOException {
|
||||
writeLicensesTo(licensesMetaData, out);
|
||||
if (licensesMetaData == null) {
|
||||
out.writeBoolean(false);
|
||||
} else {
|
||||
out.writeBoolean(true);
|
||||
writeGeneratedLicensesTo(licensesMetaData.getLicenses(), out);
|
||||
writeTrialLicensesTo(licensesMetaData.getTrialLicenses(), out);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -125,25 +162,27 @@ public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicen
|
|||
public LicensesMetaData fromXContent(XContentParser parser) throws IOException {
|
||||
|
||||
XContentParser.Token token;
|
||||
List<ESLicense> licenses = null;
|
||||
final LicenseBuilders.LicensesBuilder licensesBuilder = LicenseBuilders.licensesBuilder();
|
||||
final TrialLicensesBuilder trialLicensesBuilder = TrialLicensesBuilder.trialLicensesBuilder();
|
||||
String fieldName = null;
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
fieldName = parser.currentName();
|
||||
}
|
||||
if (fieldName != null && fieldName.equals(Fields.LICENSES)) {
|
||||
if (licenses == null) {
|
||||
licenses = new ArrayList<>();
|
||||
}
|
||||
if (fieldName != null) {
|
||||
if (fieldName.equals(Fields.LICENSES)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
licenses.add(licenseFromMap(parser.map()));
|
||||
licensesBuilder.license(licenseFromMap(parser.map()));
|
||||
}
|
||||
}
|
||||
if (fieldName.equals(Fields.TRIAL_LICENSES)) {
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
trialLicensesBuilder.license(trialLicenseFromMap(parser.map()));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (licenses == null) {
|
||||
throw new ElasticsearchParseException("failed to parse licenses: expected ['" + Fields.LICENSES + "']");
|
||||
}
|
||||
return new LicensesMetaData(licenses);
|
||||
return new LicensesMetaData(licensesBuilder.build(), trialLicensesBuilder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -153,10 +192,16 @@ public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicen
|
|||
public void toXContent(LicensesMetaData licensesMetaData, XContentBuilder builder, ToXContent.Params params) throws IOException {
|
||||
builder.startObject();
|
||||
builder.startArray(Fields.LICENSES);
|
||||
for (ESLicense license : licensesMetaData.licenses()) {
|
||||
for (ESLicense license : licensesMetaData.getLicenses()) {
|
||||
builder.map(licenseAsMap(license));
|
||||
}
|
||||
builder.endArray();
|
||||
|
||||
builder.startArray(Fields.TRIAL_LICENSES);
|
||||
for (TrialLicense license : licensesMetaData.getTrialLicenses()) {
|
||||
builder.map(trialLicenseAsMap(license));
|
||||
}
|
||||
builder.endArray();
|
||||
builder.endObject();
|
||||
}
|
||||
|
||||
|
@ -168,6 +213,7 @@ public class LicensesMetaData implements MetaData.Custom, ESLicenses, TrialLicen
|
|||
|
||||
private final static class Fields {
|
||||
private static final String LICENSES = "licenses";
|
||||
private static final String TRIAL_LICENSES = "trial_licenses";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,12 +7,17 @@ package org.elasticsearch.license.plugin.core;
|
|||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
||||
import org.elasticsearch.cluster.*;
|
||||
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.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.license.core.ESLicenses;
|
||||
import org.elasticsearch.license.core.LicenseBuilders;
|
||||
|
@ -23,6 +28,7 @@ import org.elasticsearch.license.plugin.action.put.PutLicenseRequest;
|
|||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.internal.InternalNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -60,7 +66,7 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
@Override
|
||||
public void registerLicenses(final PutLicenseRequestHolder requestHolder, final ActionListener<ClusterStateUpdateResponse> listener) {
|
||||
final PutLicenseRequest request = requestHolder.request;
|
||||
final LicensesMetaData newLicenseMetaData = new LicensesMetaData(request.license());
|
||||
final ESLicenses newLicenses = request.license();
|
||||
clusterService.submitStateUpdateTask(requestHolder.source, new AckedClusterStateUpdateTask<ClusterStateUpdateResponse>(request, listener) {
|
||||
@Override
|
||||
protected ClusterStateUpdateResponse newResponse(boolean acknowledged) {
|
||||
|
@ -73,15 +79,15 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
||||
LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE);
|
||||
|
||||
esLicenseManager.verifyLicenses(newLicenseMetaData);
|
||||
esLicenseManager.verifyLicenses(newLicenses);
|
||||
|
||||
if (currentLicenses == null) {
|
||||
// no licenses were registered
|
||||
currentLicenses = newLicenseMetaData;
|
||||
currentLicenses = new LicensesMetaData(newLicenses, null);
|
||||
} else {
|
||||
// merge previous license with new one
|
||||
//TODO: proper merge for trial licenses
|
||||
currentLicenses = new LicensesMetaData(LicenseBuilders.merge(currentLicenses, newLicenseMetaData));
|
||||
ESLicenses mergedLicenses = LicenseBuilders.merge(currentLicenses.getLicenses(), newLicenses);
|
||||
currentLicenses = new LicensesMetaData(mergedLicenses, currentLicenses.getTrialLicenses());
|
||||
}
|
||||
|
||||
mdBuilder.putCustom(LicensesMetaData.TYPE, currentLicenses);
|
||||
|
@ -109,7 +115,8 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
|
||||
if (currentLicenses != null) {
|
||||
//TODO: proper delete for trial licenses
|
||||
currentLicenses = new LicensesMetaData(LicenseBuilders.removeFeatures(currentLicenses, featuresToDelete));
|
||||
final ESLicenses newLicenses = LicenseBuilders.removeFeatures(currentLicenses.getLicenses(), featuresToDelete);
|
||||
currentLicenses = new LicensesMetaData(newLicenses, currentLicenses.getTrialLicenses());
|
||||
}
|
||||
mdBuilder.putCustom(LicensesMetaData.TYPE, currentLicenses);
|
||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
||||
|
@ -117,6 +124,44 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
});
|
||||
}
|
||||
|
||||
//TODO: hook this up
|
||||
private void registerTrialLicense(final TrialLicenses.TrialLicense trialLicense) {
|
||||
clusterService.submitStateUpdateTask("register trial license []", new ProcessedClusterStateUpdateTask() {
|
||||
@Override
|
||||
public void clusterStateProcessed(String source, ClusterState oldState, ClusterState newState) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClusterState execute(ClusterState currentState) throws Exception {
|
||||
MetaData metaData = currentState.metaData();
|
||||
MetaData.Builder mdBuilder = MetaData.builder(currentState.metaData());
|
||||
LicensesMetaData currentLicenses = metaData.custom(LicensesMetaData.TYPE);
|
||||
TrialLicensesBuilder newTrialLicenses = TrialLicensesBuilder.trialLicensesBuilder().license(trialLicense);
|
||||
if (currentLicenses != null) {
|
||||
if (currentLicenses.getTrialLicenses() != null) {
|
||||
// had previous trial licenses
|
||||
newTrialLicenses = newTrialLicenses.licenses(currentLicenses.getTrialLicenses());
|
||||
currentLicenses = new LicensesMetaData(currentLicenses.getLicenses(), newTrialLicenses.build());
|
||||
} else {
|
||||
// had no previous trial license
|
||||
currentLicenses = new LicensesMetaData(currentLicenses.getLicenses(), newTrialLicenses.build());
|
||||
}
|
||||
} else {
|
||||
// had no license meta data
|
||||
currentLicenses = new LicensesMetaData(null, newTrialLicenses.build());
|
||||
}
|
||||
mdBuilder.putCustom(LicensesMetaData.TYPE, currentLicenses);
|
||||
return ClusterState.builder(currentState).metaData(mdBuilder).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(String source, @Nullable Throwable t) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws ElasticsearchException {
|
||||
clusterService = node.injector().getInstance(ClusterService.class);
|
||||
|
@ -188,4 +233,36 @@ public class LicensesService extends AbstractLifecycleComponent<LicensesService>
|
|||
this.source = source;
|
||||
}
|
||||
}
|
||||
|
||||
private TrialLicenses.TrialLicense generateTrialLicense(String feature, int durationInDays, int maxNodes) {
|
||||
return TrialLicensesBuilder.trialLicenseBuilder()
|
||||
.issueDate(System.currentTimeMillis())
|
||||
.durationInDays(durationInDays)
|
||||
.feature(ESLicenses.FeatureType.fromString(feature))
|
||||
.maxNodes(maxNodes)
|
||||
.build();
|
||||
}
|
||||
|
||||
private class PutTrialLicenseRequest extends AcknowledgedRequest<PutTrialLicenseRequest> {
|
||||
|
||||
private PutTrialLicenseRequest() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
super.readFrom(in);
|
||||
readTimeout(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
writeTimeout(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Collection;
|
|||
|
||||
import static org.elasticsearch.license.core.ESLicenses.FeatureType;
|
||||
|
||||
public interface TrialLicenses {
|
||||
public interface TrialLicenses extends Iterable<TrialLicenses.TrialLicense> {
|
||||
|
||||
public Collection<TrialLicense> trialLicenses();
|
||||
|
||||
|
@ -22,5 +22,10 @@ public interface TrialLicenses {
|
|||
public long issueDate();
|
||||
|
||||
public long expiryDate();
|
||||
|
||||
public int maxNodes();
|
||||
|
||||
public String uid();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,9 +21,29 @@ public class TrialLicensesBuilder {
|
|||
return new TrialLicensesBuilder();
|
||||
}
|
||||
|
||||
private final ImmutableMap.Builder<ESLicenses.FeatureType, TrialLicense> licenseBuilder = ImmutableMap.builder();
|
||||
public static TrialLicenseBuilder trialLicenseBuilder() {
|
||||
return new TrialLicenseBuilder();
|
||||
}
|
||||
|
||||
public static TrialLicenses merge(TrialLicenses trialLicenses, TrialLicenses mergeTrialLicenses) {
|
||||
if (trialLicenses == null && mergeTrialLicenses == null) {
|
||||
throw new IllegalArgumentException("both licenses can not be null");
|
||||
} else if (trialLicenses == null) {
|
||||
return mergeTrialLicenses;
|
||||
} else if (mergeTrialLicenses == null) {
|
||||
return trialLicenses;
|
||||
} else {
|
||||
return trialLicensesBuilder()
|
||||
.licenses(trialLicenses.trialLicenses())
|
||||
.licenses(mergeTrialLicenses.trialLicenses())
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private final ImmutableMap.Builder<ESLicenses.FeatureType, TrialLicense> licenseBuilder;
|
||||
|
||||
public TrialLicensesBuilder() {
|
||||
licenseBuilder = ImmutableMap.builder();
|
||||
}
|
||||
|
||||
public TrialLicensesBuilder license(TrialLicense trialLicense) {
|
||||
|
@ -31,6 +51,10 @@ public class TrialLicensesBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
public TrialLicensesBuilder licenses(TrialLicenses trialLicenses) {
|
||||
return licenses(trialLicenses.trialLicenses());
|
||||
}
|
||||
|
||||
public TrialLicensesBuilder licenses(Collection<TrialLicense> trialLicenses) {
|
||||
for (TrialLicense trialLicense : trialLicenses) {
|
||||
license(trialLicense);
|
||||
|
@ -52,6 +76,10 @@ public class TrialLicensesBuilder {
|
|||
return licenseMap.get(featureType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<TrialLicense> iterator() {
|
||||
return licenseMap.values().iterator();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -60,10 +88,22 @@ public class TrialLicensesBuilder {
|
|||
private long expiryDate = -1;
|
||||
private long issueDate = -1;
|
||||
private int durationInDays = -1;
|
||||
private int maxNodes = -1;
|
||||
private String uid = null;
|
||||
|
||||
public TrialLicenseBuilder() {
|
||||
}
|
||||
|
||||
public TrialLicenseBuilder uid(String uid) {
|
||||
this.uid = uid;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TrialLicenseBuilder maxNodes(int maxNodes) {
|
||||
this.maxNodes = maxNodes;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TrialLicenseBuilder feature(ESLicenses.FeatureType featureType) {
|
||||
this.featureType = featureType;
|
||||
return this;
|
||||
|
@ -90,6 +130,9 @@ public class TrialLicensesBuilder {
|
|||
assert durationInDays != -1;
|
||||
expiryDate = DateUtils.expiryDateAfterDays(issueDate, durationInDays);
|
||||
}
|
||||
if (uid == null) {
|
||||
uid = UUID.randomUUID().toString();
|
||||
}
|
||||
return new TrialLicense() {
|
||||
@Override
|
||||
public ESLicenses.FeatureType feature() {
|
||||
|
@ -105,6 +148,16 @@ public class TrialLicensesBuilder {
|
|||
public long expiryDate() {
|
||||
return expiryDate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int maxNodes() {
|
||||
return maxNodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String uid() {
|
||||
return uid;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -116,6 +169,8 @@ public class TrialLicensesBuilder {
|
|||
msg = "issueDate has to be set";
|
||||
} else if (durationInDays == -1 && expiryDate == -1) {
|
||||
msg = "durationInDays or expiryDate has to be set";
|
||||
} else if (maxNodes == -1) {
|
||||
msg = "maxNodes has to be set";
|
||||
}
|
||||
if (msg != null) {
|
||||
throw new IllegalArgumentException(msg);
|
||||
|
|
Loading…
Reference in New Issue