Skip to content

Commit

Permalink
KAA-1423: Added Endpoint Specific Configuration Support
Browse files Browse the repository at this point in the history
  • Loading branch information
agulenko committed Sep 27, 2016
1 parent c0cddc1 commit ed1d1cf
Show file tree
Hide file tree
Showing 97 changed files with 3,677 additions and 583 deletions.
Expand Up @@ -31,6 +31,7 @@
import org.kaaproject.kaa.common.dto.EndpointProfileSchemaDto; import org.kaaproject.kaa.common.dto.EndpointProfileSchemaDto;
import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto; import org.kaaproject.kaa.common.dto.EndpointProfilesBodyDto;
import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto; import org.kaaproject.kaa.common.dto.EndpointProfilesPageDto;
import org.kaaproject.kaa.common.dto.EndpointSpecificConfigurationDto;
import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto; import org.kaaproject.kaa.common.dto.EndpointUserConfigurationDto;
import org.kaaproject.kaa.common.dto.NotificationDto; import org.kaaproject.kaa.common.dto.NotificationDto;
import org.kaaproject.kaa.common.dto.NotificationSchemaDto; import org.kaaproject.kaa.common.dto.NotificationSchemaDto;
Expand Down Expand Up @@ -527,6 +528,18 @@ public void editUserConfiguration(EndpointUserConfigurationDto endpointUserConfi
restTemplate.postForLocation(restTemplate.getUrl() + "userConfiguration", endpointUserConfiguration); restTemplate.postForLocation(restTemplate.getUrl() + "userConfiguration", endpointUserConfiguration);
} }


public EndpointSpecificConfigurationDto editEndpointSpecificConfiguration(EndpointSpecificConfigurationDto configuration) throws Exception {
return restTemplate.postForObject(restTemplate.getUrl() + "endpointConfiguration", configuration, EndpointSpecificConfigurationDto.class);
}

public void deleteEndpointSpecificConfiguration(String endpointKeyHash) throws Exception {
restTemplate.delete(restTemplate.getUrl() + "endpointConfiguration/" + endpointKeyHash);
}

public EndpointSpecificConfigurationDto findEndpointSpecificConfiguration(String endpointKeyHash) throws Exception {
return restTemplate.getForObject(restTemplate.getUrl() + "endpointConfiguration/" + endpointKeyHash, EndpointSpecificConfigurationDto.class);
}

public ProfileFilterDto editProfileFilter(ProfileFilterDto profileFilter) throws Exception { public ProfileFilterDto editProfileFilter(ProfileFilterDto profileFilter) throws Exception {
return restTemplate.postForObject(restTemplate.getUrl() + "profileFilter", profileFilter, ProfileFilterDto.class); return restTemplate.postForObject(restTemplate.getUrl() + "profileFilter", profileFilter, ProfileFilterDto.class);
} }
Expand Down
Expand Up @@ -17,16 +17,16 @@
package org.kaaproject.kaa.server.common.dao; package org.kaaproject.kaa.server.common.dao;




import java.util.Collection;
import java.util.List;

import org.kaaproject.kaa.common.dto.ChangeConfigurationNotification; import org.kaaproject.kaa.common.dto.ChangeConfigurationNotification;
import org.kaaproject.kaa.common.dto.ConfigurationDto; import org.kaaproject.kaa.common.dto.ConfigurationDto;
import org.kaaproject.kaa.common.dto.ConfigurationRecordDto; import org.kaaproject.kaa.common.dto.ConfigurationRecordDto;
import org.kaaproject.kaa.common.dto.ConfigurationSchemaDto; import org.kaaproject.kaa.common.dto.ConfigurationSchemaDto;
import org.kaaproject.kaa.common.dto.HistoryDto; import org.kaaproject.kaa.common.dto.HistoryDto;
import org.kaaproject.kaa.common.dto.VersionDto; import org.kaaproject.kaa.common.dto.VersionDto;


import java.util.Collection;
import java.util.List;

/** /**
* The interface Configuration service. * The interface Configuration service.
*/ */
Expand Down Expand Up @@ -192,6 +192,8 @@ public interface ConfigurationService {
*/ */
ConfigurationSchemaDto saveConfSchema(ConfigurationSchemaDto configurationSchema); ConfigurationSchemaDto saveConfSchema(ConfigurationSchemaDto configurationSchema);


String validateConfiguration(String appId, int schemaVersion, String configurationBody);

/** /**
* Find configuration schema by id. * Find configuration schema by id.
* *
Expand Down
@@ -0,0 +1,61 @@
/*
* 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;

import org.kaaproject.kaa.common.dto.EndpointProfileDto;
import org.kaaproject.kaa.common.dto.EndpointSpecificConfigurationDto;

import java.util.Optional;

/**
* The interface Endpoint specific configuration service.
*/
public interface EndpointSpecificConfigurationService {

/**
* Find endpoint specific configuration by endpoint key hash
*
* @param endpointKeyHash
* @return the endpoint specific configuration
*/
Optional<EndpointSpecificConfigurationDto> findByEndpointKeyHash(String endpointKeyHash);

/**
* Find endpoint specific configuration by endpoint profile
*
* @param endpointProfileDto
* @return the endpoint specific configuration
*/
Optional<EndpointSpecificConfigurationDto> findByEndpointProfile(EndpointProfileDto endpointProfileDto);

/**
* Delete endpoint specific configuration by endpoint key hash
*
* @param endpointKeyHash
* @return deleted endpoint specific configuration
*/
Optional<EndpointSpecificConfigurationDto> deleteByEndpointKeyHash(String endpointKeyHash);

/**
* Save endpoint specific configuration by endpoint key hash
*
* @param configurationDto endpoint specific configuration
* @return saved endpoint specific configuration
*/
EndpointSpecificConfigurationDto save(EndpointSpecificConfigurationDto configurationDto);

}
@@ -0,0 +1,30 @@
/*
* 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.impl;

import org.kaaproject.kaa.common.dto.EndpointSpecificConfigurationDto;
import org.kaaproject.kaa.server.common.dao.model.EndpointSpecificConfiguration;

public interface EndpointSpecificConfigurationDao<T extends EndpointSpecificConfiguration> extends Dao<T, String> {

void removeByEndpointKeyHash(String endpointKeyHash);

EndpointSpecificConfiguration findByEndpointKeyHashAndConfigurationVersion(String endpointKeyHash, int configurationVersion);

EndpointSpecificConfiguration save(EndpointSpecificConfigurationDto endpointSpecificConfigurationDto);

}
@@ -0,0 +1,30 @@
/*
* 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.model;

import org.kaaproject.kaa.common.dto.EndpointSpecificConfigurationDto;
import org.kaaproject.kaa.common.dto.HasVersion;

import java.io.Serializable;

/**
* An endpoint specific configuration provides single endpoint configuration without creating dedicated endpoint group.
* Endpoint specific configuration has highest priority in configuration override.
*/
public interface EndpointSpecificConfiguration extends ToDto<EndpointSpecificConfigurationDto>, HasVersion, Serializable {

}
Expand Up @@ -16,22 +16,6 @@


package org.kaaproject.kaa.server.common.dao.service; 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 java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import org.apache.avro.Schema; import org.apache.avro.Schema;
import org.apache.avro.generic.GenericRecord; import org.apache.avro.generic.GenericRecord;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
Expand All @@ -58,6 +42,7 @@
import org.kaaproject.kaa.server.common.core.configuration.BaseData; 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.BaseDataFactory;
import org.kaaproject.kaa.server.common.core.configuration.KaaData; 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.configuration.OverrideDataFactory;
import org.kaaproject.kaa.server.common.core.schema.BaseSchema; 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.DataSchema;
Expand All @@ -82,6 +67,23 @@
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; 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;

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;

@Service @Service
@Transactional @Transactional
public class ConfigurationServiceImpl implements ConfigurationService { public class ConfigurationServiceImpl implements ConfigurationService {
Expand Down Expand Up @@ -466,6 +468,34 @@ public ConfigurationSchemaDto saveConfSchema(ConfigurationSchemaDto configuratio
return savedConfigSchema; return savedConfigSchema;
} }


@Override
public String validateConfiguration(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 e) {
LOG.error("Invalid configuration for override schema.", e);
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 @Override
public ConfigurationSchemaDto findConfSchemaById(String id) { public ConfigurationSchemaDto findConfSchemaById(String id) {
validateSqlId(id, "Incorrect configuration schema id " + id + ". Can't find configuration schema."); validateSqlId(id, "Incorrect configuration schema id " + id + ". Can't find configuration schema.");
Expand Down
@@ -0,0 +1,112 @@
/*
* 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 org.kaaproject.kaa.common.dto.EndpointProfileDto;
import org.kaaproject.kaa.common.dto.EndpointSpecificConfigurationDto;
import org.kaaproject.kaa.server.common.dao.ConfigurationService;
import org.kaaproject.kaa.server.common.dao.EndpointService;
import org.kaaproject.kaa.server.common.dao.EndpointSpecificConfigurationService;
import org.kaaproject.kaa.server.common.dao.impl.EndpointSpecificConfigurationDao;
import org.kaaproject.kaa.server.common.dao.model.EndpointSpecificConfiguration;
import org.kaaproject.kaa.server.common.dao.model.ToDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;

import java.util.Optional;

import static org.kaaproject.kaa.server.common.dao.service.Validator.validateString;

@Service
public class EndpointSpecificConfigurationServiceImpl implements EndpointSpecificConfigurationService {

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

private EndpointSpecificConfigurationDao<EndpointSpecificConfiguration> endpointSpecificConfigurationDao;
@Autowired
private EndpointService endpointService;
@Autowired
private ConfigurationService configurationService;

@Override
public Optional<EndpointSpecificConfigurationDto> findByEndpointKeyHash(String endpointKeyHash) {
LOG.debug("Looking for endpoint specific configuration by EP key hash {}", endpointKeyHash);
EndpointProfileDto profileDto = getEndpointProfileDto(endpointKeyHash);
if (profileDto == null) {
return Optional.empty();
}
EndpointSpecificConfiguration configuration = endpointSpecificConfigurationDao.findByEndpointKeyHashAndConfigurationVersion(endpointKeyHash, profileDto.getConfigurationVersion());
return Optional.ofNullable(configuration).map(ToDto::toDto);
}

@Override
public Optional<EndpointSpecificConfigurationDto> findByEndpointProfile(EndpointProfileDto endpointProfileDto) {
String base64EncodedEndpointKeyHash = Base64Utils.encodeToString(endpointProfileDto.getEndpointKeyHash());
int configurationVersion = endpointProfileDto.getConfigurationVersion();
EndpointSpecificConfiguration configuration = endpointSpecificConfigurationDao.findByEndpointKeyHashAndConfigurationVersion(base64EncodedEndpointKeyHash, configurationVersion);
return Optional.ofNullable(configuration).map(ToDto::toDto);

}

@Override
public Optional<EndpointSpecificConfigurationDto> deleteByEndpointKeyHash(String endpointKeyHash) {
Optional<EndpointSpecificConfigurationDto> configuration = findByEndpointKeyHash(endpointKeyHash);
if (configuration.isPresent()) {
endpointSpecificConfigurationDao.removeByEndpointKeyHash(endpointKeyHash);
}
return configuration;
}

@Override
public EndpointSpecificConfigurationDto save(EndpointSpecificConfigurationDto configurationDto) {
EndpointProfileDto profileDto = getEndpointProfileDto(configurationDto.getEndpointKeyHash());
configurationDto.setConfigurationVersion(profileDto.getConfigurationVersion());
validateConfigurationBody(configurationDto, profileDto);
return endpointSpecificConfigurationDao.save(configurationDto).toDto();
}

private EndpointProfileDto getEndpointProfileDto(String endpointKeyHash) {
validateString(endpointKeyHash, "Endpoint key hash is required");
return endpointService.findEndpointProfileByKeyHash(Base64Utils.decodeFromString(endpointKeyHash));
}


private void validateConfigurationBody(EndpointSpecificConfigurationDto configurationDto, EndpointProfileDto ep) {
validateString(configurationDto.getConfiguration(), "Endpoint specific configuration body is required");
int configurationVersion = configurationDto.getConfigurationVersion();
String appId = ep.getApplicationId();
String configurationBody = configurationDto.getConfiguration();
configurationBody = configurationService.validateConfiguration(appId, configurationVersion, configurationBody);
validateString(configurationBody, "Provided configuration body is invalid");
configurationDto.setConfiguration(configurationBody);
}

public void setEndpointSpecificConfigurationDao(EndpointSpecificConfigurationDao<EndpointSpecificConfiguration> endpointSpecificConfigurationDao) {
this.endpointSpecificConfigurationDao = endpointSpecificConfigurationDao;
}

public void setEndpointService(EndpointService endpointService) {
this.endpointService = endpointService;
}

public void setConfigurationService(ConfigurationService configurationService) {
this.configurationService = configurationService;
}
}

0 comments on commit ed1d1cf

Please sign in to comment.