All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.gravitee.node.license.DefaultLicenseFactory Maven / Gradle / Ivy

There is a newer version: 7.0.0-alpha.13
Show newest version
/**
 * Copyright (C) 2015 The Gravitee team (http://gravitee.io)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.gravitee.node.license;

import static java.util.stream.Collectors.toSet;

import io.gravitee.node.api.license.*;
import io.gravitee.node.api.license.model.LicenseModel;
import io.gravitee.node.license.license3j.License3J;
import io.gravitee.node.license.license3j.License3JFeature;
import java.io.ByteArrayInputStream;
import java.util.*;
import javax.annotation.Nonnull;
import javax0.license3j.io.LicenseReader;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Jeoffrey HAEYAERT (jeoffrey.haeyaert at graviteesource.com)
 * @author GraviteeSource Team
 */
@Slf4j
public class DefaultLicenseFactory implements LicenseFactory {

    private static final String LICENSE_TIER_KEY = "tier";
    private static final String LICENSE_PACKS_KEY = "packs";
    private static final String LICENSE_FEATURES_KEY = "features";
    private static final String LEGACY_FEATURE_VALUE = "included";
    private static final String LIST_SEPARATOR = ",";

    private final LicenseModelService licenseModelService;

    public DefaultLicenseFactory(LicenseModelService licenseModelService) {
        this.licenseModelService = licenseModelService;
    }

    @Override
    public License create(@Nonnull String referenceType, @Nonnull String referenceId, String base64License)
        throws InvalidLicenseException, MalformedLicenseException {
        byte[] bytesLicense = Objects.isNull(base64License) ? null : Base64.getDecoder().decode(base64License);
        return create(referenceType, referenceId, bytesLicense);
    }

    @Override
    public License create(@Nonnull String referenceType, @Nonnull String referenceId, byte[] bytesLicense)
        throws InvalidLicenseException, MalformedLicenseException {
        if (Objects.isNull(bytesLicense)) {
            return new OSSLicense(referenceType, referenceId);
        } else if (referenceType.equals(License.REFERENCE_TYPE_PLATFORM)) {
            return createPlatformLicense(bytesLicense);
        } else {
            return createOrgLicence(referenceId, bytesLicense);
        }
    }

    private License createPlatformLicense(@Nonnull byte[] bytesLicense) throws InvalidLicenseException, MalformedLicenseException {
        try (LicenseReader reader = new LicenseReader(new ByteArrayInputStream(bytesLicense))) {
            final License3J license = new License3J(reader.read());

            // Verify the license is valid and throw an exception in any case.
            license.verify();

            return create(License.REFERENCE_TYPE_PLATFORM, License.REFERENCE_ID_PLATFORM, license);
        } catch (InvalidLicenseException lie) {
            throw lie;
        } catch (Exception e) {
            throw new MalformedLicenseException("License cannot be read", e);
        }
    }

    private License createOrgLicence(@Nonnull String referenceId, @Nonnull byte[] bytesLicense) {
        try (LicenseReader reader = new LicenseReader(new ByteArrayInputStream(bytesLicense))) {
            final License3J license = new License3J(reader.read());

            // Check the license is valid. Expiration date is not taken in account
            if (license.isValid()) {
                return create(License.REFERENCE_TYPE_ORGANIZATION, referenceId, license);
            }
        } catch (Exception e) {
            log.warn("Organization license cannot be read for [{}].", referenceId, e);
        }

        // Fallback to OSS in case of invalid organization license
        return new OSSLicense(License.REFERENCE_TYPE_ORGANIZATION, referenceId);
    }

    private License create(String referenceType, String referenceId, License3J license) throws InvalidLicenseException {
        final String tier = readTier(license);
        final Set packs = readPacks(license, tier);
        final Set features = readFeatures(license, packs);

        return DefaultLicense
            .builder()
            .referenceType(referenceType)
            .referenceId(referenceId)
            .tier(tier)
            .packs(packs)
            .features(features)
            .license3j(license)
            .build();
    }

    private String readTier(License3J license) {
        return readString(license, LICENSE_TIER_KEY).orElse(null);
    }

    private Set readPacks(License3J license, String tier) {
        final Set licensePacks = new HashSet<>(readList(license, LICENSE_PACKS_KEY));

        if (tier != null) {
            Set tierPacks = licenseModelService.getLicenseModel().getTiers().get(tier).getPacks();
            licensePacks.addAll(tierPacks);
        }

        return licensePacks;
    }

    private Set readFeatures(License3J license, Set packs) {
        final HashSet licenseFeatures = new HashSet<>();
        final LicenseModel licenseModel = licenseModelService.getLicenseModel();

        licenseFeatures.addAll(readList(license, LICENSE_FEATURES_KEY));
        licenseFeatures.addAll(readLegacyFeatures(license));

        for (String pack : packs) {
            licenseFeatures.addAll(licenseModel.getPacks().get(pack).getFeatures());
        }

        return licenseFeatures;
    }

    private Set readList(License3J license, String key) {
        return readString(license, key).map(value -> Set.of(value.split(LIST_SEPARATOR))).orElse(Set.of());
    }

    private Optional readString(License3J license, String featureKey) {
        return license.feature(featureKey).map(License3JFeature::getString).filter(s -> !s.isBlank());
    }

    private Set readLegacyFeatures(License3J license) {
        return license
            .features()
            .entrySet()
            .stream()
            .filter(entry -> LEGACY_FEATURE_VALUE.equals(entry.getValue()))
            .map(Map.Entry::getKey)
            .collect(toSet());
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy