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

io.gravitee.gateway.services.sync.SyncService Maven / Gradle / Ivy

There is a newer version: 4.5.2
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.gateway.services.sync;

import io.gravitee.common.http.MediaType;
import io.gravitee.common.service.AbstractService;
import io.gravitee.gateway.env.GatewayConfiguration;
import io.gravitee.gateway.handlers.api.manager.ApiManager;
import io.gravitee.gateway.services.sync.cache.ApiKeysCacheService;
import io.gravitee.gateway.services.sync.cache.SubscriptionsCacheService;
import io.gravitee.gateway.services.sync.handler.SyncHandler;
import io.gravitee.gateway.services.sync.healthcheck.ApiSyncProbe;
import io.gravitee.node.api.healthcheck.ProbeManager;
import io.gravitee.repository.exceptions.TechnicalException;
import io.gravitee.repository.management.api.EnvironmentRepository;
import io.gravitee.repository.management.api.OrganizationRepository;
import io.gravitee.repository.management.model.Environment;
import io.gravitee.repository.management.model.Organization;
import io.vertx.ext.web.Router;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;

/**
 * @author David BRASSELY (david.brassely at graviteesource.com)
 * @author Titouan COMPIEGNE (titouan.compiegne at graviteesource.com)
 * @author GraviteeSource Team
 */
public class SyncService extends AbstractService {

    /**
     * Logger.
     */
    private final Logger logger = LoggerFactory.getLogger(SyncService.class);

    private static final String PATH = "/sync";

    @Value("${services.sync.delay:5000}")
    private int delay;

    @Value("${services.sync.unit:MILLISECONDS}")
    private TimeUnit unit;

    @Value("${services.sync.enabled:true}")
    private boolean enabled;

    @Value("${services.local.enabled:false}")
    private boolean localRegistryEnabled;

    @Autowired
    private ApiManager apiManager;

    @Autowired
    private SyncManager syncManager;

    @Autowired
    @Qualifier("managementRouter")
    private Router router;

    @Autowired
    private ApiKeysCacheService apiKeysCacheService;

    @Autowired
    private SubscriptionsCacheService subscriptionsCacheService;

    @Autowired
    private ProbeManager probeManager;

    @Autowired
    private ApiSyncProbe apiSyncProbe;

    @Autowired
    private EnvironmentRepository environmentRepository;

    @Autowired
    private OrganizationRepository organizationRepository;

    @Autowired
    private GatewayConfiguration configuration;

    private Set environments;

    @Override
    protected void doStart() throws Exception {
        if (!localRegistryEnabled) {
            if (enabled) {
                super.doStart();

                logger.info("Sync service has been initialized with delay [{}{}]", delay, unit.name());

                this.environments = getTargetedEnvironments();

                probeManager.register(this.apiSyncProbe);

                logger.info("Associate a new HTTP handler on {}", PATH);

                // Create and associate handler
                SyncHandler syncHandler = new SyncHandler();
                applicationContext.getAutowireCapableBeanFactory().autowireBean(syncHandler);
                router.get(PATH).produces(MediaType.APPLICATION_JSON).handler(syncHandler);

                // Start tasks
                apiKeysCacheService.start();
                subscriptionsCacheService.start();

                // Force refresh based on internal state of the api manager (useful if apis definitions are maintained across the cluster).
                apiManager.refresh();

                // Initialize the sync manager.
                syncManager.start();

                // Set environments list to syncManager
                List environmentsIds = environments.stream().map(Environment::getId).collect(Collectors.toList());
                syncManager.setEnvironments(environmentsIds);

                // Run a first refresh immediately.
                syncManager.refresh();

                // Initial sync has been made, start schedulers.
                syncManager.startScheduler(delay, unit);
                apiKeysCacheService.startScheduler(delay, unit);
                subscriptionsCacheService.startScheduler(delay, unit);
            } else {
                logger.warn("Sync service is disabled");
            }
        } else {
            logger.warn("Sync service is disabled because local registry mode is enabled");
        }
    }

    @Override
    protected void doStop() throws Exception {
        syncManager.stop();
        apiKeysCacheService.stop();
        subscriptionsCacheService.stop();

        super.doStop();
    }

    public boolean isAllApisSync() {
        return syncManager.isAllApisSync();
    }

    @Override
    protected String name() {
        return "Gateway Sync Service";
    }

    private Set getTargetedEnvironments() throws TechnicalException {
        final Optional> optOrganizationsList = configuration.organizations();
        final Optional> optEnvironmentsList = configuration.environments();

        Set organizationsIds = new HashSet<>();
        Set environmentsHrids = new HashSet<>();

        if (optOrganizationsList.isPresent()) {
            List organizationsHrids = optOrganizationsList.get();
            final Set organizations = organizationRepository.findByHrids(new HashSet<>(organizationsHrids));
            organizationsIds = organizations.stream().map(Organization::getId).collect(Collectors.toSet());

            checkOrganizations(organizationsHrids, organizations);
        }

        if (optEnvironmentsList.isPresent()) {
            environmentsHrids = new HashSet<>(optEnvironmentsList.get());
        }

        Set environments = environmentRepository.findByOrganizationsAndHrids(organizationsIds, environmentsHrids);

        checkEnvironments(environmentsHrids, environments);

        return environments;
    }

    private void checkOrganizations(List organizationsHrids, Set organizations) {
        if (organizationsHrids.size() != organizations.size()) {
            final Set hrids = new HashSet<>(organizationsHrids);
            final Set returnedHrids = organizations.stream().flatMap(org -> org.getHrids().stream()).collect(Collectors.toSet());
            hrids.removeAll(returnedHrids);
            logger.warn("No organization found for hrids {}", hrids);
        }
    }

    private void checkEnvironments(Set environmentsHrids, Set environments) {
        final Set returnedHrids = environments
            .stream()
            .flatMap(env -> env.getHrids().stream())
            .filter(environmentsHrids::contains)
            .collect(Collectors.toSet());

        if (environmentsHrids.size() != returnedHrids.size()) {
            final Set hrids = new HashSet<>(environmentsHrids);
            hrids.removeAll(returnedHrids);
            logger.warn("No environment found for hrids {}", hrids);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy