/*
* 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.apache.commons.lang.StringUtils.isBlank;
import static org.kaaproject.kaa.common.dto.UpdateStatus.ACTIVE;
import static org.kaaproject.kaa.common.dto.UpdateStatus.INACTIVE;
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.impl.DaoUtil.idToString;
import static org.kaaproject.kaa.server.common.dao.service.Validator.isValidId;
import static org.kaaproject.kaa.server.common.dao.service.Validator.validateId;
import static org.kaaproject.kaa.server.common.dao.service.Validator.validateSqlId;
import static org.kaaproject.kaa.server.common.dao.service.Validator.validateSqlObject;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericRecord;
import org.apache.commons.lang.StringUtils;
import org.kaaproject.kaa.common.avro.GenericAvroConverter;
import org.kaaproject.kaa.common.dto.ChangeConfigurationNotification;
import org.kaaproject.kaa.common.dto.ChangeDto;
import org.kaaproject.kaa.common.dto.ChangeNotificationDto;
import org.kaaproject.kaa.common.dto.ChangeType;
import org.kaaproject.kaa.common.dto.ConfigurationDto;
import org.kaaproject.kaa.common.dto.ConfigurationRecordDto;
import org.kaaproject.kaa.common.dto.ConfigurationSchemaDto;
import org.kaaproject.kaa.common.dto.HistoryDto;
import org.kaaproject.kaa.common.dto.UpdateStatus;
import org.kaaproject.kaa.common.dto.VersionDto;
import org.kaaproject.kaa.common.dto.ctl.CTLSchemaDto;
import org.kaaproject.kaa.server.common.core.algorithms.AvroUtils;
import org.kaaproject.kaa.server.common.core.algorithms.generation.DefaultRecordGenerationAlgorithm;
import org.kaaproject.kaa.server.common.core.algorithms.generation.DefaultRecordGenerationAlgorithmImpl;
import org.kaaproject.kaa.server.common.core.algorithms.schema.SchemaCreationException;
import org.kaaproject.kaa.server.common.core.algorithms.schema.SchemaGenerationAlgorithm;
import org.kaaproject.kaa.server.common.core.algorithms.schema.SchemaGenerationAlgorithmFactory;
import org.kaaproject.kaa.server.common.core.algorithms.validator.DefaultUuidValidator;
import org.kaaproject.kaa.server.common.core.algorithms.validator.UuidValidator;
import org.kaaproject.kaa.server.common.core.configuration.BaseData;
import org.kaaproject.kaa.server.common.core.configuration.BaseDataFactory;
import org.kaaproject.kaa.server.common.core.configuration.KaaData;
import org.kaaproject.kaa.server.common.core.configuration.OverrideData;
import org.kaaproject.kaa.server.common.core.configuration.OverrideDataFactory;
import org.kaaproject.kaa.server.common.core.schema.BaseSchema;
import org.kaaproject.kaa.server.common.core.schema.DataSchema;
import org.kaaproject.kaa.server.common.core.schema.OverrideSchema;
import org.kaaproject.kaa.server.common.core.schema.ProtocolSchema;
import org.kaaproject.kaa.server.common.dao.ConfigurationService;
import org.kaaproject.kaa.server.common.dao.CtlService;
import org.kaaproject.kaa.server.common.dao.HistoryService;
import org.kaaproject.kaa.server.common.dao.exception.DatabaseProcessingException;
import org.kaaproject.kaa.server.common.dao.exception.IncorrectParameterException;
import org.kaaproject.kaa.server.common.dao.exception.NotFoundException;
import org.kaaproject.kaa.server.common.dao.exception.UpdateStatusConflictException;
import org.kaaproject.kaa.server.common.dao.impl.ConfigurationDao;
import org.kaaproject.kaa.server.common.dao.impl.ConfigurationSchemaDao;
import org.kaaproject.kaa.server.common.dao.impl.EndpointGroupDao;
import org.kaaproject.kaa.server.common.dao.model.sql.Configuration;
import org.kaaproject.kaa.server.common.dao.model.sql.ConfigurationSchema;
import org.kaaproject.kaa.server.common.dao.model.sql.EndpointGroup;
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.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@Service
@Transactional
public class ConfigurationServiceImpl implements ConfigurationService {
private static final Logger LOG = LoggerFactory.getLogger(ConfigurationServiceImpl.class);
private static final String DEFAULT_STRUCT_DESC = "Generated";
@Autowired
private ConfigurationDao<Configuration> configurationDao;
@Autowired
private EndpointGroupDao<EndpointGroup> endpointGroupDao;
@Autowired
private ConfigurationSchemaDao<ConfigurationSchema> configurationSchemaDao;
@Autowired
private HistoryService historyService;
@Autowired
private CtlService ctlService;
@Autowired
private SchemaGenerationAlgorithmFactory schemaGeneratorFactory;
private UuidValidator uuidValidator;
@Override
@Deprecated
public ConfigurationDto findConfigurationByAppIdAndVersion(String applicationId, int version) {
validateSqlId(applicationId, "Application id is incorrect. "
+ "Can't find configuration by application id " + applicationId
+ " and version " + version);
return getDto(configurationDao.findConfigurationByAppIdAndVersion(applicationId, version));
}
@Override
public ConfigurationDto findConfigurationByEndpointGroupIdAndVersion(String endpointGroupId,
int version) {
validateId(endpointGroupId, "Endpoint group id is incorrect. "
+ "Can't find configuration by endpoint group id "
+ endpointGroupId + " and version " + version);
return getDto(configurationDao.findConfigurationByEndpointGroupIdAndVersion(
endpointGroupId, version));
}
@Override
public ConfigurationDto findDefaultConfigurationBySchemaId(String schemaId) {
validateId(schemaId, "Schema id is incorrect. Can't find default configuration by schema id "
+ schemaId);
ConfigurationDto configuration = null;
ConfigurationSchema configurationSchema = configurationSchemaDao.findById(schemaId);
if (configurationSchema != null) {
String appId = configurationSchema.getApplicationId();
EndpointGroup endpointGroup = endpointGroupDao.findByAppIdAndWeight(appId, 0);
if (endpointGroup != null) {
String endpointGroupId = String.valueOf(endpointGroup.getId());
configuration = getDto(configurationDao.findConfigurationByEndpointGroupIdAndVersion(
endpointGroupId, configurationSchema.getVersion()));
} else {
LOG.warn("Can't find default group for application [{}]", appId);
}
} else {
LOG.warn("Can't find configuration schema for id [{}]", schemaId);
}
return configuration;
}
@Override
public ConfigurationDto findConfigurationById(String id) {
validateSqlId(id, "Configuration id is incorrect. Can't find configuration by id " + id);
return getDto(configurationDao.findById(id));
}
@Override
public Collection<ConfigurationRecordDto> findAllConfigurationRecordsByEndpointGroupId(
String endpointGroupId, boolean includeDeprecated) {
Collection<ConfigurationDto> configurations = convertDtoList(
configurationDao.findActualByEndpointGroupId(endpointGroupId));
List<ConfigurationRecordDto> records =
ConfigurationRecordDto.convertToConfigurationRecords(configurations);
if (includeDeprecated) {
List<VersionDto> schemas = findVacantSchemasByEndpointGroupId(endpointGroupId);
for (VersionDto schema : schemas) {
ConfigurationDto deprecatedConfiguration = getDto(
configurationDao.findLatestDeprecated(schema.getId(), endpointGroupId));
if (deprecatedConfiguration != null) {
ConfigurationRecordDto record = new ConfigurationRecordDto();
record.setActiveStructureDto(deprecatedConfiguration);
records.add(record);
}
}
}
Collections.sort(records);
return records;
}
@Override
public ConfigurationRecordDto findConfigurationRecordBySchemaIdAndEndpointGroupId(
String schemaId, String endpointGroupId) {
ConfigurationRecordDto record = new ConfigurationRecordDto();
Collection<ConfigurationDto> configurations = convertDtoList(
configurationDao.findActualBySchemaIdAndGroupId(schemaId, endpointGroupId));
if (configurations != null) {
for (ConfigurationDto configuration : configurations) {
if (configuration.getStatus() == UpdateStatus.ACTIVE) {
record.setActiveStructureDto(configuration);
} else if (configuration.getStatus() == UpdateStatus.INACTIVE) {
record.setInactiveStructureDto(configuration);
}
}
}
if (!record.hasActive()) {
ConfigurationDto deprecatedConfiguration = getDto(
configurationDao.findLatestDeprecated(schemaId, endpointGroupId));
if (deprecatedConfiguration != null) {
record.setActiveStructureDto(deprecatedConfiguration);
}
}
if (record.isEmpty()) {
LOG.debug("Can't find related Configuration record.");
throw new NotFoundException("Configuration record not found, schemaId: "
+ schemaId + ", endpointGroupId: "
+ endpointGroupId); // NOSONAR
}
return record;
}
@Override
public List<VersionDto> findVacantSchemasByEndpointGroupId(String endpointGroupId) {
validateId(endpointGroupId, "Can't find vacant schemas. Invalid endpoint group id: "
+ endpointGroupId);
EndpointGroup group = endpointGroupDao.findById(endpointGroupId);
List<Configuration> configurations = configurationDao.findActualByEndpointGroupId(
endpointGroupId);
List<String> usedSchemaIds = new ArrayList<>();
for (Configuration configuration : configurations) {
ConfigurationSchema schema = configuration.getConfigurationSchema();
if (schema != null) {
usedSchemaIds.add(idToString(schema.getId()));
}
}
List<ConfigurationSchema> schemas = configurationSchemaDao.findVacantSchemas(
group.getApplicationId(), usedSchemaIds);
List<VersionDto> schemaDtoList = new ArrayList<>();
for (ConfigurationSchema schema : schemas) {
schemaDtoList.add(schema.toVersionDto());
}
return schemaDtoList;
}
@Override
public ConfigurationDto saveConfiguration(ConfigurationDto configurationDto) {
validateConfiguration(configurationDto);
String id = configurationDto.getId();
ConfigurationSchemaDto configurationSchemaDto;
Configuration oldActiveConfiguration = null;
if (StringUtils.isNotBlank(id)) {
ConfigurationDto oldConfiguration = findConfigurationById(configurationDto.getId());
if (oldConfiguration != null && oldConfiguration.getStatus() != INACTIVE) {
throw new UpdateStatusConflictException("Can't update configuration, invalid id " + id);
}
configurationSchemaDto = findConfSchemaById(configurationDto.getSchemaId());
configurationDto.setSchemaVersion(configurationSchemaDto.getVersion());
configurationDto.setCreatedTime(oldConfiguration.getCreatedTime());
configurationDto.setCreatedUsername(oldConfiguration.getCreatedUsername());
LOG.debug("Update existing configuration with id: [{}]", configurationDto.getId());
} else {
String schemaId = configurationDto.getSchemaId();
String groupId = configurationDto.getEndpointGroupId();
configurationSchemaDto = findConfSchemaById(schemaId);
if (configurationSchemaDto != null) {
Configuration oldInactiveConfiguration = configurationDao.findInactiveBySchemaIdAndGroupId(
schemaId, groupId);
oldActiveConfiguration = configurationDao.findLatestActiveBySchemaIdAndGroupId(
schemaId, groupId);
if (oldInactiveConfiguration != null) {
configurationDto.setId(idToString(oldInactiveConfiguration.getId()));
configurationDto.setSequenceNumber(oldInactiveConfiguration.getSequenceNumber());
} else if (oldActiveConfiguration != null) {
configurationDto.setSequenceNumber(oldActiveConfiguration.getSequenceNumber());
}
configurationDto.setApplicationId(configurationSchemaDto.getApplicationId());
configurationDto.setSchemaVersion(configurationSchemaDto.getVersion());
configurationDto.setProtocolSchema(configurationSchemaDto.getProtocolSchema());
configurationDto.setCreatedTime(System.currentTimeMillis());
} else {
LOG.debug("Can't find related Configuration schema.");
throw new IncorrectParameterException("Configuration schema not found, id:" + schemaId);
}
}
ConfigurationDto oldActiveConfigurationDto =
oldActiveConfiguration != null ? oldActiveConfiguration.toDto() : null;
validateUuids(configurationDto, oldActiveConfigurationDto, configurationSchemaDto);
configurationDto.setStatus(UpdateStatus.INACTIVE);
configurationDto.setLastModifyTime(System.currentTimeMillis());
return getDto(configurationDao.save(new Configuration(configurationDto)));
}
private void validateUuids(ConfigurationDto currentConfiguration,
ConfigurationDto previousConfiguration,
ConfigurationSchemaDto configurationSchema) {
try {
EndpointGroup endpointGroup = endpointGroupDao.findById(
currentConfiguration.getEndpointGroupId());
GenericAvroConverter<GenericRecord> avroConverter;
Schema avroSchema;
KaaData body = null;
if (endpointGroup != null) {
if (endpointGroup.getWeight() == 0) {
LOG.debug("Create default UUID validator with base schema: {}",
configurationSchema.getBaseSchema());
BaseSchema baseSchema = new BaseSchema(configurationSchema.getBaseSchema());
uuidValidator = new DefaultUuidValidator(baseSchema, new BaseDataFactory());
avroConverter = new GenericAvroConverter<GenericRecord>(baseSchema.getRawSchema());
avroSchema = new Schema.Parser().parse(baseSchema.getRawSchema());
} else {
LOG.debug("Create default UUID validator with override schema: {}",
configurationSchema.getOverrideSchema());
OverrideSchema overrideSchema = new OverrideSchema(
configurationSchema.getOverrideSchema());
uuidValidator = new DefaultUuidValidator(overrideSchema, new OverrideDataFactory());
avroConverter = new GenericAvroConverter<GenericRecord>(overrideSchema.getRawSchema());
avroSchema = new Schema.Parser().parse(overrideSchema.getRawSchema());
}
GenericRecord previousRecord = null;
if (previousConfiguration != null) {
previousRecord = avroConverter.decodeJson(previousConfiguration.getBody());
}
GenericRecord currentRecord = avroConverter.decodeJson(AvroUtils.injectUuids(
currentConfiguration.getBody(), avroSchema));
body = uuidValidator.validateUuidFields(currentRecord, previousRecord);
}
if (body != null) {
currentConfiguration.setBody(body.getRawData());
} else {
throw new RuntimeException("Can't generate json configuration body."); // NOSONAR
}
} catch (Exception ex) {
LOG.warn("Can't generate uuid fields for configuration {}", currentConfiguration);
LOG.error("Can't generate uuid fields for configuration!", ex);
throw new IncorrectParameterException("Incorrect configuration. Can't generate uuid fields.");
}
}
@Override
public ChangeConfigurationNotification activateConfiguration(
String id, String activatedUsername) {
ChangeConfigurationNotification configurationNotification;
validateSqlId(id, "Incorrect configuration id. Can't activate configuration with id " + id);
Configuration oldConfiguration = configurationDao.findById(id);
if (oldConfiguration != null) {
UpdateStatus status = oldConfiguration.getStatus();
if (status != null && status == INACTIVE) {
String schemaId = oldConfiguration.getSchemaId();
String groupId = oldConfiguration.getEndpointGroupId();
if (schemaId != null && groupId != null) {
configurationDao.deactivateOldConfiguration(schemaId, groupId, activatedUsername);
} else {
throw new DatabaseProcessingException(
"Incorrect old configuration. Configuration schema or endpoint group id is empty.");
}
ConfigurationDto configurationDto = getDto(configurationDao.activate(
id, activatedUsername));
HistoryDto historyDto = addHistory(configurationDto, ChangeType.ADD_CONF);
ChangeNotificationDto changeNotificationDto = createNotification(
configurationDto, historyDto);
configurationNotification = new ChangeConfigurationNotification();
configurationNotification.setConfigurationDto(configurationDto);
configurationNotification.setChangeNotificationDto(changeNotificationDto);
} else {
throw new UpdateStatusConflictException("Incorrect status for activating configuration "
+ status);
}
} else {
throw new IncorrectParameterException("Can't find configuration with id " + id);
}
return configurationNotification;
}
@Override
public ChangeConfigurationNotification deactivateConfiguration(
String id, String deactivatedUsername) {
ChangeConfigurationNotification configurationNotification;
validateSqlId(id, "Incorrect configuration id. Can't deactivate configuration with id " + id);
Configuration oldConfiguration = configurationDao.findById(id);
if (oldConfiguration != null) {
UpdateStatus status = oldConfiguration.getStatus();
if (status != null && status == ACTIVE) {
ConfigurationDto configurationDto = getDto(configurationDao.deactivate(
id, deactivatedUsername));
HistoryDto historyDto = addHistory(configurationDto, ChangeType.REMOVE_CONF);
ChangeNotificationDto changeNotificationDto = createNotification(
configurationDto, historyDto);
configurationNotification = new ChangeConfigurationNotification();
configurationNotification.setConfigurationDto(configurationDto);
configurationNotification.setChangeNotificationDto(changeNotificationDto);
} else {
throw new UpdateStatusConflictException("Incorrect status for activating configuration "
+ status);
}
} else {
throw new IncorrectParameterException("Can't find configuration with id " + id);
}
return configurationNotification;
}
@Override
public ChangeConfigurationNotification deleteConfigurationRecord(
String schemaId, String groupId, String deactivatedUsername) {
ChangeConfigurationNotification configurationNotification = null;
validateSqlId(schemaId, "Incorrect configuration schema id " + schemaId + ".");
validateSqlId(groupId, "Incorrect group id " + groupId + ".");
ConfigurationDto configurationDto = getDto(configurationDao.deactivateOldConfiguration(
schemaId, groupId, deactivatedUsername));
if (configurationDto != null) {
HistoryDto historyDto = addHistory(configurationDto, ChangeType.REMOVE_CONF);
ChangeNotificationDto changeNotificationDto = createNotification(
configurationDto, historyDto);
configurationNotification = new ChangeConfigurationNotification();
configurationNotification.setConfigurationDto(configurationDto);
configurationNotification.setChangeNotificationDto(changeNotificationDto);
}
Configuration configuration = configurationDao.findInactiveBySchemaIdAndGroupId(
schemaId, groupId);
if (configuration != null) {
configurationDao.removeById(idToString(configuration));
}
return configurationNotification;
}
@Override
public List<ConfigurationDto> findConfigurationsByEndpointGroupId(String endpointGroupId) {
validateSqlId(endpointGroupId, "Incorrect endpoint group id " + endpointGroupId);
return convertDtoList(configurationDao.findActiveByEndpointGroupId(endpointGroupId));
}
@Override
public List<ConfigurationSchemaDto> findConfSchemasByAppId(String applicationId) {
validateSqlId(applicationId, "Incorrect application id " + applicationId
+ ". Can't find configuration schemas.");
return convertDtoList(configurationSchemaDao.findByApplicationId(applicationId));
}
@Override
public List<VersionDto> findConfigurationSchemaVersionsByAppId(String applicationId) {
validateSqlId(applicationId, "Incorrect application id " + applicationId
+ ". Can't find configuration schema versions.");
List<ConfigurationSchema> configurationSchemas =
configurationSchemaDao.findByApplicationId(applicationId);
List<VersionDto> schemas = new ArrayList<>();
for (ConfigurationSchema configurationSchema : configurationSchemas) {
schemas.add(configurationSchema.toVersionDto());
}
return schemas;
}
@Override
public ConfigurationSchemaDto findConfSchemaByAppIdAndVersion(String applicationId, int version) {
validateSqlId(applicationId, "Incorrect application id " + applicationId
+ ". Can't find configuration schema.");
return getDto(configurationSchemaDao.findByAppIdAndVersion(applicationId, version));
}
@Override
public ConfigurationSchemaDto saveConfSchema(ConfigurationSchemaDto schemaDto, String groupId) {
ConfigurationSchemaDto savedSchema = saveConfigurationSchema(schemaDto);
if (savedSchema != null) {
LOG.debug("Configuration schema with id [{}] saved. Generating default configuration",
savedSchema.getId());
try {
BaseSchema baseSchema = new BaseSchema(savedSchema.getBaseSchema());
DefaultRecordGenerationAlgorithm<BaseData> configurationProcessor =
new DefaultRecordGenerationAlgorithmImpl<BaseSchema, BaseData>(
baseSchema, new BaseDataFactory());
KaaData body = configurationProcessor.getRootData();
LOG.debug("Default configuration {} ", body.getRawData());
ConfigurationDto configurationDto = new ConfigurationDto();
configurationDto.setBody(body.getRawData());
configurationDto.setSchemaId(savedSchema.getId());
configurationDto.setDescription(DEFAULT_STRUCT_DESC);
configurationDto.setEndpointGroupId(groupId);
configurationDto.setCreatedUsername(savedSchema.getCreatedUsername());
ConfigurationDto savedConfiguration = saveConfiguration(configurationDto);
if (savedConfiguration != null) {
activateConfiguration(savedConfiguration.getId(), savedSchema.getCreatedUsername());
} else {
LOG.warn("Can't save default configuration.");
removeCascadeConfigurationSchema(savedSchema.getId());
throw new IncorrectParameterException("Can't save default configuration.");
}
} catch (Exception ex) {
LOG.error("Can't generate configuration based on protocol schema.", ex);
removeCascadeConfigurationSchema(savedSchema.getId());
throw new IncorrectParameterException("Can't save default configuration.");
}
}
return savedSchema;
}
@Override
public ConfigurationSchemaDto saveConfSchema(ConfigurationSchemaDto configurationSchema) {
ConfigurationSchemaDto savedConfigSchema = null;
if (configurationSchema != null) {
String appId = configurationSchema.getApplicationId();
if (isValidId(appId)) {
LOG.debug("Finding default endpoint group for application id [{}]", appId);
EndpointGroup endpointGroup = endpointGroupDao.findByAppIdAndWeight(appId, 0);
if (endpointGroup != null) {
savedConfigSchema = saveConfSchema(configurationSchema, idToString(endpointGroup));
} else {
LOG.warn("Can't find default group for application [{}]", appId);
}
} else {
LOG.warn("Can't find endpoint group. Invalid application id [{}]", appId);
}
} else {
LOG.warn("Configuration schema object is null");
}
return savedConfigSchema;
}
@Override
public ConfigurationSchemaDto findConfSchemaById(String id) {
validateSqlId(id, "Incorrect configuration schema id "
+ id + ". Can't find configuration schema.");
return getDto(configurationSchemaDao.findById(id));
}
@Override
public String normalizeAccordingToOverrideConfigurationSchema(String appId, int schemaVersion, String configurationBody) {
ConfigurationSchemaDto schemaDto = this.findConfSchemaByAppIdAndVersion(appId, schemaVersion);
if (schemaDto != null) {
OverrideSchema overrideSchema = new OverrideSchema(schemaDto.getOverrideSchema());
LOG.debug("Create default UUID validator with override schema: {}", overrideSchema.getRawSchema());
UuidValidator<OverrideData> uuidValidator = new DefaultUuidValidator<>(overrideSchema, new OverrideDataFactory());
GenericAvroConverter<GenericRecord> avroConverter = new GenericAvroConverter<>(overrideSchema.getRawSchema());
try {
GenericRecord configRecord = avroConverter.decodeJson(configurationBody);
// TODO: Need to use last active configuration instead of null. Will be changed after supporting delta configuration
KaaData<OverrideSchema> body = uuidValidator.validateUuidFields(configRecord, null);
if (body != null) {
return body.getRawData();
} else {
LOG.warn("Validated configuration body is empty");
throw new IncorrectParameterException("Validated configuration body is empty");
}
} catch (IOException ex) {
LOG.error("Invalid configuration for override schema.", ex);
throw new IncorrectParameterException("Invalid configuration for override schema.");
}
} else {
LOG.warn("Can't find configuration schema with version {}.", schemaVersion);
throw new IncorrectParameterException("Can't find configuration schema for specified version.");
}
}
@Override
public void removeConfSchemasByAppId(String appId) {
validateSqlId(appId, "Incorrect application id " + appId
+ ". Can't remove configuration schema.");
LOG.debug("Removing configuration schemas and correspond configuration by application id");
List<ConfigurationSchema> configurationSchemaList =
configurationSchemaDao.findByApplicationId(appId);
for (ConfigurationSchema configurationSchema : configurationSchemaList) {
if (configurationSchema != null) {
removeCascadeConfigurationSchema(idToString(configurationSchema));
}
}
}
private ChangeNotificationDto createNotification(ConfigurationDto configurationDto,
HistoryDto historyDto) {
LOG.debug("Create notification after configuration update.");
ChangeNotificationDto changeNotificationDto = null;
if (historyDto != null) {
changeNotificationDto = new ChangeNotificationDto();
changeNotificationDto.setAppId(configurationDto.getApplicationId());
changeNotificationDto.setAppSeqNumber(historyDto.getSequenceNumber());
String endpointGroupId = configurationDto.getEndpointGroupId();
if (isValidId(endpointGroupId)) {
EndpointGroup group = endpointGroupDao.findById(endpointGroupId);
if (group != null) {
changeNotificationDto.setGroupId(idToString(group));
changeNotificationDto.setGroupSeqNumber(group.getSequenceNumber());
} else {
LOG.debug("Can't find endpoint group by id [{}].", endpointGroupId);
}
} else {
LOG.debug("Incorrect endpoint group id [{}].", endpointGroupId);
}
} else {
LOG.debug("Can't save history information.");
}
return changeNotificationDto;
}
private void generateSchemas(ConfigurationSchemaDto schema) throws SchemaCreationException {
CTLSchemaDto ctlSchema = ctlService.findCtlSchemaById(schema.getCtlSchemaId());
String sch = ctlService.flatExportAsString(ctlSchema);
DataSchema dataSchema = new DataSchema(sch);
if (!dataSchema.isEmpty()) {
SchemaGenerationAlgorithm schemaGenerator =
schemaGeneratorFactory.createSchemaGenerator(dataSchema);
ProtocolSchema protocol = schemaGenerator.getProtocolSchema();
BaseSchema base = schemaGenerator.getBaseSchema();
OverrideSchema override = schemaGenerator.getOverrideSchema();
if (!protocol.isEmpty() && !base.isEmpty() && !override.isEmpty()) {
schema.setBaseSchema(base.getRawSchema());
schema.setProtocolSchema(protocol.getRawSchema());
schema.setOverrideSchema(override.getRawSchema());
} else {
LOG.trace("One or more generated schemas are empty. base: {} protocol {} override {}",
base, protocol, override);
throw new IncorrectParameterException("Can't generate schemas. Check your data schema");
}
} else {
LOG.warn("Can't generate schemas because data schema is empty.");
}
}
private void removeCascadeConfigurationSchema(String id) {
LOG.debug("Removing configurations and configuration schema by id " + id);
// configurationDao.removeByConfigurationSchemaId(id);
configurationSchemaDao.removeById(id);
}
private HistoryDto addHistory(ConfigurationDto dto, ChangeType type) {
LOG.debug("Add history information about configuration update");
HistoryDto history = new HistoryDto();
history.setApplicationId(dto.getApplicationId());
ChangeDto change = new ChangeDto();
change.setConfigurationId(dto.getId());
change.setCfVersion(dto.getSchemaVersion());
change.setEndpointGroupId(dto.getEndpointGroupId());
change.setType(type);
history.setChange(change);
return historyService.saveHistory(history);
}
private void validateConfiguration(ConfigurationDto dto) {
validateSqlObject(dto, "Can't save configuration, object is invalid.");
validateSqlId(dto.getSchemaId(), "Configuration object invalid. "
+ "Incorrect configuration schema id : " + dto.getSchemaId());
validateSqlId(dto.getEndpointGroupId(), "Configuration object invalid. "
+ "Incorrect endpoint group id : "
+ dto.getEndpointGroupId());
}
private ConfigurationSchemaDto saveConfigurationSchema(
ConfigurationSchemaDto configurationSchema) {
ConfigurationSchemaDto configurationSchemaDto;
validateSqlObject(configurationSchema, "Can't save configuration schema. "
+ "Configuration schema invalid.");
String id = configurationSchema.getId();
if (isBlank(id)) {
ConfigurationSchemaDto oldConfigurationSchemaDto = findLatestConfSchemaByAppId(
configurationSchema.getApplicationId());
int version = 0;
if (oldConfigurationSchemaDto != null) {
version = oldConfigurationSchemaDto.getVersion();
}
configurationSchema.setVersion(++version);
configurationSchema.setCreatedTime(System.currentTimeMillis());
try {
generateSchemas(configurationSchema);
} catch (SchemaCreationException ex) {
LOG.warn("Can't generate protocol schema from configuration schema.", ex);
throw new IncorrectParameterException("Incorrect configuration schema. "
+ "Can't generate protocol schema.");
}
} else {
ConfigurationSchemaDto oldConfigurationSchemaDto = getDto(
configurationSchemaDao.findById(id));
if (oldConfigurationSchemaDto != null) {
oldConfigurationSchemaDto.editFields(configurationSchema);
configurationSchema = oldConfigurationSchemaDto;
} else {
LOG.error("Can't find configuration schema with given id [{}].", id);
throw new IncorrectParameterException("Invalid configuration schema id: " + id);
}
}
configurationSchemaDto = getDto(configurationSchemaDao.save(
new ConfigurationSchema(configurationSchema)));
return configurationSchemaDto;
}
private ConfigurationSchemaDto findLatestConfSchemaByAppId(String applicationId) {
validateSqlId(applicationId, "Incorrect application id " + applicationId
+ ". Can't find latest configuration schema.");
return getDto(configurationSchemaDao.findLatestByApplicationId(applicationId));
}
}