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

com.alibaba.nacos.cmdb.memory.CmdbProvider Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * 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 com.alibaba.nacos.cmdb.memory;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.api.cmdb.spi.CmdbService;
import com.alibaba.nacos.api.cmdb.pojo.Entity;
import com.alibaba.nacos.api.cmdb.pojo.EntityEvent;
import com.alibaba.nacos.api.cmdb.pojo.Label;
import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.cmdb.core.SwitchAndOptions;
import com.alibaba.nacos.cmdb.service.CmdbReader;
import com.alibaba.nacos.cmdb.service.CmdbWriter;
import com.alibaba.nacos.cmdb.utils.Loggers;
import com.alibaba.nacos.cmdb.utils.UtilsAndCommons;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

/**
 * @author nkorange
 * @since 0.7.0
 */
@Component
public class CmdbProvider implements CmdbReader, CmdbWriter {

    @Autowired
    private SwitchAndOptions switches;

    private CmdbService cmdbService;

    private ServiceLoader serviceLoader = ServiceLoader.load(CmdbService.class);

    private Map> entityMap = new ConcurrentHashMap<>();

    private Map labelMap = new ConcurrentHashMap<>();

    private Set entityTypeSet = new HashSet<>();

    private long eventTimestamp = System.currentTimeMillis();

    public CmdbProvider() throws NacosException {
    }

    private void initCmdbService() throws NacosException {
        Iterator iterator = serviceLoader.iterator();
        if (iterator.hasNext()) {
            cmdbService = iterator.next();
        }

        if (cmdbService == null && switches.isLoadDataAtStart()) {
            throw new NacosException(NacosException.SERVER_ERROR, "Cannot initialize CmdbService!");
        }
    }

    public void load() {

        if (!switches.isLoadDataAtStart()) {
            return;
        }

        // init label map:
        Set labelNames = cmdbService.getLabelNames();
        if (labelNames == null || labelNames.isEmpty()) {
            Loggers.MAIN.warn("[LOAD] init label names failed!");
        } else {
            for (String labelName : labelNames) {
                // If get null label, it's still ok. We will try it later when we meet this label:
                labelMap.put(labelName, cmdbService.getLabel(labelName));
            }
        }

        // init entity type set:
        entityTypeSet = cmdbService.getEntityTypes();

        // init entity map:
        entityMap = cmdbService.getAllEntities();
    }

    @PostConstruct
    public void init() throws NacosException {

        initCmdbService();
        load();

        UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbDumpTask(), switches.getDumpTaskInterval(), TimeUnit.SECONDS);
        UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbLabelTask(), switches.getLabelTaskInterval(), TimeUnit.SECONDS);
        UtilsAndCommons.GLOBAL_EXECUTOR.schedule(new CmdbEventTask(), switches.getEventTaskInterval(), TimeUnit.SECONDS);
    }

    @Override
    public Entity queryEntity(String entityName, String entityType) {
        if (!entityMap.containsKey(entityType)) {
            return null;
        }
        return entityMap.get(entityType).get(entityName);
    }

    @Override
    public String queryLabel(String entityName, String entityType, String labelName) {
        Entity entity = queryEntity(entityName, entityType);
        if (entity == null) {
            return null;
        }
        return entity.getLabels().get(labelName);
    }

    @Override
    public List queryEntitiesByLabel(String labelName, String labelValue) {
        throw new UnsupportedOperationException("Not available now!");
    }

    public void removeEntity(String entityName, String entityType) {
        if (!entityMap.containsKey(entityType)) {
            return;
        }
        entityMap.get(entityType).remove(entityName);
    }

    public void updateEntity(Entity entity) {
        if (!entityTypeSet.contains(entity.getType())) {
            return;
        }
        entityMap.get(entity.getType()).put(entity.getName(), entity);
    }

    public class CmdbLabelTask implements Runnable {

        @Override
        public void run() {

            Loggers.MAIN.debug("LABEL-TASK {}", "start dump.");

            if (cmdbService == null) {
                return;
            }

            try {

                Map tmpLabelMap = new HashMap<>(16);

                Set labelNames = cmdbService.getLabelNames();
                if (labelNames == null || labelNames.isEmpty()) {
                    Loggers.MAIN.warn("CMDB-LABEL-TASK {}", "load label names failed!");
                } else {
                    for (String labelName : labelNames) {
                        // If get null label, it's still ok. We will try it later when we meet this label:
                        tmpLabelMap.put(labelName, cmdbService.getLabel(labelName));
                    }

                    if (Loggers.MAIN.isDebugEnabled()) {
                        Loggers.MAIN.debug("LABEL-TASK {}", "got label map:" + JSON.toJSONString(tmpLabelMap));
                    }

                    labelMap = tmpLabelMap;
                }

            } catch (Exception e) {
                Loggers.MAIN.error("CMDB-LABEL-TASK {}", "dump failed!", e);
            } finally {
                UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getLabelTaskInterval(), TimeUnit.SECONDS);
            }
        }
    }

    public class CmdbDumpTask implements Runnable {

        @Override
        public void run() {

            try {

                Loggers.MAIN.debug("DUMP-TASK {}", "start dump.");

                if (cmdbService == null) {
                    return;
                }
                // refresh entity map:
                entityMap = cmdbService.getAllEntities();
            } catch (Exception e) {
                Loggers.MAIN.error("DUMP-TASK {}", "dump failed!", e);
            } finally {
                UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getDumpTaskInterval(), TimeUnit.SECONDS);
            }
        }
    }

    public class CmdbEventTask implements Runnable {

        @Override
        public void run() {
            try {

                Loggers.MAIN.debug("EVENT-TASK {}", "start dump.");

                if (cmdbService == null) {
                    return;
                }

                long current = System.currentTimeMillis();
                List events = cmdbService.getEntityEvents(eventTimestamp);
                eventTimestamp = current;

                if (Loggers.MAIN.isDebugEnabled()) {
                    Loggers.MAIN.debug("EVENT-TASK {}", "got events size:" + ", events:" + JSON.toJSONString(events));
                }

                if (events != null && !events.isEmpty()) {

                    for (EntityEvent event : events) {
                        switch (event.getType()) {
                            case ENTITY_REMOVE:
                                removeEntity(event.getEntityName(), event.getEntityType());
                                break;
                            case ENTITY_ADD_OR_UPDATE:
                                updateEntity(cmdbService.getEntity(event.getEntityName(), event.getEntityType()));
                                break;
                            default:
                                break;
                        }
                    }
                }

            } catch (Exception e) {
                Loggers.MAIN.error("CMDB-EVENT {}", "event task failed!", e);
            } finally {
                UtilsAndCommons.GLOBAL_EXECUTOR.schedule(this, switches.getEventTaskInterval(), TimeUnit.SECONDS);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy