org.kaaproject.kaa.server.common.dao.service.EventClassServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.kaaproject.kaa.server.common.dao.service.EventClassServiceImpl.java

Source

/*
 * Copyright 2014-2016 CyberVision, Inc.
 *
 * 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 org.kaaproject.kaa.server.common.dao.service;

import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.convertDtoList;
import static org.kaaproject.kaa.server.common.dao.impl.DaoUtil.getDto;
import static org.kaaproject.kaa.server.common.dao.service.Validator.isValidSqlId;
import static org.kaaproject.kaa.server.common.dao.service.Validator.isValidSqlObject;
import static org.kaaproject.kaa.server.common.dao.service.Validator.validateSqlId;

import org.apache.commons.lang.StringUtils;
import org.kaaproject.avro.ui.shared.NamesValidator;
import org.kaaproject.kaa.common.dto.event.AefMapInfoDto;
import org.kaaproject.kaa.common.dto.event.EventClassDto;
import org.kaaproject.kaa.common.dto.event.EventClassFamilyDto;
import org.kaaproject.kaa.common.dto.event.EventClassFamilyVersionDto;
import org.kaaproject.kaa.common.dto.event.EventClassType;
import org.kaaproject.kaa.server.common.dao.EventClassService;
import org.kaaproject.kaa.server.common.dao.exception.IncorrectParameterException;
import org.kaaproject.kaa.server.common.dao.impl.CtlSchemaDao;
import org.kaaproject.kaa.server.common.dao.impl.EventClassDao;
import org.kaaproject.kaa.server.common.dao.impl.EventClassFamilyDao;
import org.kaaproject.kaa.server.common.dao.model.sql.CtlSchema;
import org.kaaproject.kaa.server.common.dao.model.sql.EventClass;
import org.kaaproject.kaa.server.common.dao.model.sql.EventClassFamily;
import org.kaaproject.kaa.server.common.dao.model.sql.EventClassFamilyVersion;
import org.kaaproject.kaa.server.common.dao.schema.EventSchemaProcessor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@Transactional
public class EventClassServiceImpl implements EventClassService {

    private static final Logger LOG = LoggerFactory.getLogger(EventClassServiceImpl.class);

    @Autowired
    private EventClassFamilyDao<EventClassFamily> eventClassFamilyDao;

    @Autowired
    private EventClassDao<EventClass> eventClassDao;

    @Autowired
    private EventSchemaProcessor eventSchemaProcessor;

    @Autowired
    private CtlSchemaDao<CtlSchema> ctlSchemaDao;

    @Override
    public List<EventClassFamilyDto> findEventClassFamiliesByTenantId(String tenantId) {
        List<EventClassFamilyDto> eventClassFamilies;
        if (isValidSqlId(tenantId)) {
            LOG.debug("Find event class families by tenant id [{}]", tenantId);
            eventClassFamilies = convertDtoList(eventClassFamilyDao.findByTenantId(tenantId));
        } else {
            throw new IncorrectParameterException("Incorrect tenant id: " + tenantId);
        }
        return eventClassFamilies;
    }

    @Override
    public EventClassFamilyDto findEventClassFamilyByTenantIdAndName(String tenantId, String name) {
        if (isValidSqlId(tenantId)) {
            LOG.debug("Find event class family by tenant id [{}] and name {}", tenantId, name);
            return eventClassFamilyDao.findByTenantIdAndName(tenantId, name).toDto();
        } else {
            throw new IncorrectParameterException("Incorrect tenant id: " + tenantId);
        }
    }

    @Override
    public EventClassFamilyDto findEventClassFamilyById(String id) {
        validateSqlId(id, "Event class family id is incorrect. Can't find event class family by id " + id);
        return getDto(eventClassFamilyDao.findById(id));
    }

    @Override
    public EventClassFamilyDto findEventClassFamilyByEcfvId(String id) {
        validateSqlId(id, "Event class family version id is incorrect. Can't find event class family "
                + "by ECF version id " + id);
        return getDto(eventClassFamilyDao.findByEcfvId(id));
    }

    @Override
    public List<EventClassFamilyVersionDto> findEventClassFamilyVersionsByEcfId(String ecfId) {
        validateSqlId(ecfId, "Event class family id is incorrect. Can't find event class family by id " + ecfId);
        EventClassFamily ecf = eventClassFamilyDao.findById(ecfId);
        return convertDtoList(ecf.getSchemas());
    }

    @Override
    public EventClassFamilyDto saveEventClassFamily(EventClassFamilyDto eventClassFamilyDto) {
        EventClassFamilyDto savedEventClassFamilyDto = null;
        if (isValidSqlObject(eventClassFamilyDto)) {
            if (eventClassFamilyDao.validateName(eventClassFamilyDto.getTenantId(), eventClassFamilyDto.getId(),
                    eventClassFamilyDto.getName())) {
                if (StringUtils.isBlank(eventClassFamilyDto.getId())) {
                    if (NamesValidator.validateNamespace(eventClassFamilyDto.getNamespace())) {
                        if (NamesValidator.validateClassName(eventClassFamilyDto.getClassName())) {
                            if (eventClassFamilyDao.validateClassName(eventClassFamilyDto.getTenantId(),
                                    eventClassFamilyDto.getId(), eventClassFamilyDto.getClassName())) {
                                eventClassFamilyDto.setCreatedTime(System.currentTimeMillis());
                            } else {
                                LOG.debug("Can't save event class family. Class name should be unique within the "
                                        + "tenant.");
                                throw new IncorrectParameterException("Incorrect event class family. Class name "
                                        + "should be unique within the tenant.");
                            }
                        } else {
                            LOG.debug("Can't save event class family. Class name [{}] is not valid.",
                                    eventClassFamilyDto.getClassName());
                            throw new IncorrectParameterException(
                                    "Incorrect event class family. Class name " + "is not valid. '"
                                            + eventClassFamilyDto.getClassName() + "' is not a valid identifier.");
                        }
                    } else {
                        LOG.debug("Can't save event class family. Namespace [{}] is not valid.",
                                eventClassFamilyDto.getNamespace());
                        throw new IncorrectParameterException(
                                "Incorrect event class family. Namespace is " + "not valid. '"
                                        + eventClassFamilyDto.getNamespace() + "' is not a valid identifier.");
                    }
                }
                savedEventClassFamilyDto = getDto(
                        eventClassFamilyDao.save(new EventClassFamily(eventClassFamilyDto)));
            } else {
                LOG.debug("Can't save event class family. Name should be unique within the tenant.");
                throw new IncorrectParameterException(
                        "Incorrect event class family. Name should be unique" + " within the tenant.");
            }
        }
        return savedEventClassFamilyDto;
    }

    @Override
    public void addEventClassFamilyVersion(String eventClassFamilyId,
            EventClassFamilyVersionDto eventClassFamilyVersion, String createdUsername) {
        EventClassFamilyDto eventClassFamily = findEventClassFamilyById(eventClassFamilyId);
        if (eventClassFamily != null) {
            List<EventClassDto> records = eventClassFamilyVersion.getRecords();
            List<String> fqns = new ArrayList<>(records.size());
            for (EventClassDto eventClass : records) {
                fqns.add(eventClass.getFqn());
            }
            if (validateEventClassFamilyFqns(eventClassFamily.getId(), fqns)) {
                List<EventClassFamilyVersionDto> schemasDto = findEventClassFamilyVersionsByEcfId(
                        eventClassFamilyId);
                int version = 1;
                if (schemasDto != null && !schemasDto.isEmpty()) {
                    Collections.sort(schemasDto, new Comparator<EventClassFamilyVersionDto>() {
                        @Override
                        public int compare(EventClassFamilyVersionDto o1, EventClassFamilyVersionDto o2) {
                            return o1.getVersion() - o2.getVersion();
                        }
                    });
                    version = schemasDto.get(schemasDto.size() - 1).getVersion() + 1;
                } else {
                    schemasDto = new ArrayList<>();
                }
                eventClassFamilyVersion.setVersion(version);
                eventClassFamilyVersion.setCreatedTime(System.currentTimeMillis());
                eventClassFamilyVersion.setCreatedUsername(createdUsername);
                schemasDto.add(eventClassFamilyVersion);
                List<EventClassFamilyVersion> schemas = new ArrayList<>();
                for (EventClassDto eventClass : records) {
                    setEventClassProperties(eventClassFamily, eventClass);
                }
                schemasDto.forEach(s -> schemas.add(new EventClassFamilyVersion(s)));
                setBackreference(schemas);
                EventClassFamily ecf = new EventClassFamily(eventClassFamily);
                ecf.setSchemas(schemas);
                eventClassFamilyDao.save(ecf);
            } else {
                LOG.debug("Can't process event class family schema.");
                throw new IncorrectParameterException(
                        "Incorrect event class family schema. FQNs should be" + " unique within the tenant.");
            }
        } else {
            LOG.debug("Can't find related event class family.");
            throw new IncorrectParameterException("Event class family not found, id:" + eventClassFamilyId);
        }
    }

    private void setEventClassProperties(EventClassFamilyDto eventClassFamilyDto, EventClassDto eventClass) {
        eventClass.setTenantId(eventClassFamilyDto.getTenantId());
        eventClass.setVersion(ctlSchemaDao.findById(eventClass.getCtlSchemaId()).getVersion());
    }

    private void setBackreference(List<EventClassFamilyVersion> ecfvList) {
        ecfvList.forEach(ecfv -> ecfv.getRecords().forEach(ec -> ec.setEcfv(ecfv)));
    }

    @Override
    public boolean validateEventClassFamilyFqns(String eventClassFamilyId, List<String> fqns) {
        Set<String> storedFqns = getFqnSetForEcf(eventClassFamilyId);
        for (String fqn : fqns) {
            if (storedFqns.contains(fqn)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public List<EventClassDto> findEventClassesByFamilyIdVersionAndType(String ecfId, int version,
            EventClassType type) {
        List<EventClassDto> eventClasses = new ArrayList<>();
        if (isValidSqlId(ecfId)) {
            LOG.debug("Find event classes by family id [{}] version [{}] and type [{}]", ecfId, version, type);
            EventClassFamily ecf = eventClassFamilyDao.findById(ecfId);
            Optional<EventClassFamilyVersion> ecfv = ecf.getSchemas().stream()
                    .filter(s -> s.getVersion() == version).findFirst();

            if (type == null) {
                ecfv.ifPresent(e -> eventClasses.addAll(convertDtoList(e.getRecords())));
            } else {
                ecfv.ifPresent(e -> eventClasses.addAll(convertDtoList(
                        e.getRecords().stream().filter(ec -> ec.getType() == type).collect(Collectors.toList()))));
            }
        } else {
            throw new IncorrectParameterException("Incorrect event class family id: " + ecfId);
        }
        return eventClasses;
    }

    @Override
    public List<EventClassDto> findEventClassByTenantIdAndFqn(String tenantId, String fqn) {
        if (isValidSqlId(tenantId)) {
            LOG.debug("Find event class family by tenant id [{}] and fqn {}", tenantId, fqn);
            return convertDtoList(eventClassDao.findByTenantIdAndFqn(tenantId, fqn));
        } else {
            throw new IncorrectParameterException("Incorrect tenant id: " + tenantId);
        }
    }

    @Override
    public EventClassDto findEventClassByTenantIdAndFqnAndVersion(String tenantId, String fqn, int version) {
        if (isValidSqlId(tenantId)) {
            LOG.debug("Find event class family by tenant id [{}] and fqn {}", tenantId, fqn);
            return getDto(eventClassDao.findByTenantIdAndFqnAndVersion(tenantId, fqn, version));
        } else {
            throw new IncorrectParameterException("Incorrect tenant id: " + tenantId);
        }

    }

    @Override
    public EventClassDto findEventClassById(String eventClassId) {
        if (isValidSqlId(eventClassId)) {
            LOG.debug("Find event class by id [{}] ", eventClassId);
            return getDto(eventClassDao.findById(eventClassId));
        } else {
            throw new IncorrectParameterException("Incorrect event class id: " + eventClassId);
        }
    }

    @Override
    public boolean isValidEcfListInSdkProfile(List<AefMapInfoDto> aefList) {
        Set<EventClass> ecList = new HashSet<>();
        for (AefMapInfoDto aef : aefList) {
            EventClassFamily ecf = eventClassFamilyDao.findById(aef.getEcfId());

            Optional<EventClassFamilyVersion> optEcfv = ecf.getSchemas().stream()
                    .filter(ecfv -> ecfv.getVersion() == aef.getVersion()).findFirst();
            if (optEcfv.isPresent()) {
                for (EventClass ec : optEcfv.get().getRecords()) {
                    if (!ecList.add(ec)) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    @Override
    public Set<String> getFqnSetForEcf(String ecfId) {
        if (isValidSqlId(ecfId)) {
            LOG.debug("Get fqn list for event class family by id [{}] ", ecfId);
            Set<String> storedFqns = new HashSet<>();
            EventClassFamily ecf = eventClassFamilyDao.findById(ecfId);
            ecf.getSchemas().forEach(ecfv -> ecfv.getRecords().forEach(ec -> storedFqns.add(ec.getFqn())));
            return storedFqns;
        } else {
            throw new IncorrectParameterException("Incorrect event class family id: " + ecfId);
        }
    }
}