/*
* 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.operations.service.cache.concurrent;
import org.kaaproject.kaa.common.dto.ApplicationDto;
import org.kaaproject.kaa.common.dto.ChangeDto;
import org.kaaproject.kaa.common.dto.ChangeType;
import org.kaaproject.kaa.common.dto.ConfigurationDto;
import org.kaaproject.kaa.common.dto.ConfigurationSchemaDto;
import org.kaaproject.kaa.common.dto.EndpointConfigurationDto;
import org.kaaproject.kaa.common.dto.EndpointGroupDto;
import org.kaaproject.kaa.common.dto.EndpointGroupStateDto;
import org.kaaproject.kaa.common.dto.EndpointProfileDto;
import org.kaaproject.kaa.common.dto.EndpointProfileSchemaDto;
import org.kaaproject.kaa.common.dto.HistoryDto;
import org.kaaproject.kaa.common.dto.ProfileFilterDto;
import org.kaaproject.kaa.common.dto.ServerProfileSchemaDto;
import org.kaaproject.kaa.common.dto.TopicDto;
import org.kaaproject.kaa.common.dto.TopicListEntryDto;
import org.kaaproject.kaa.common.dto.admin.SdkProfileDto;
import org.kaaproject.kaa.common.dto.ctl.CTLSchemaDto;
import org.kaaproject.kaa.common.dto.event.ApplicationEventAction;
import org.kaaproject.kaa.common.dto.event.ApplicationEventFamilyMapDto;
import org.kaaproject.kaa.common.dto.event.ApplicationEventMapDto;
import org.kaaproject.kaa.common.dto.event.EventClassDto;
import org.kaaproject.kaa.common.dto.event.EventClassFamilyDto;
import org.kaaproject.kaa.common.hash.EndpointObjectHash;
import org.kaaproject.kaa.server.common.core.configuration.BaseData;
import org.kaaproject.kaa.server.common.core.configuration.RawData;
import org.kaaproject.kaa.server.common.core.structure.Pair;
import org.kaaproject.kaa.server.common.dao.ApplicationEventMapService;
import org.kaaproject.kaa.server.common.dao.ApplicationService;
import org.kaaproject.kaa.server.common.dao.ConfigurationService;
import org.kaaproject.kaa.server.common.dao.CtlService;
import org.kaaproject.kaa.server.common.dao.EndpointService;
import org.kaaproject.kaa.server.common.dao.EventClassService;
import org.kaaproject.kaa.server.common.dao.HistoryService;
import org.kaaproject.kaa.server.common.dao.ProfileService;
import org.kaaproject.kaa.server.common.dao.SdkProfileService;
import org.kaaproject.kaa.server.common.dao.ServerProfileService;
import org.kaaproject.kaa.server.common.dao.TopicService;
import org.kaaproject.kaa.server.operations.pojo.exceptions.GetDeltaException;
import org.kaaproject.kaa.server.operations.service.cache.AppProfileVersionsKey;
import org.kaaproject.kaa.server.operations.service.cache.AppSeqNumber;
import org.kaaproject.kaa.server.operations.service.cache.AppVersionKey;
import org.kaaproject.kaa.server.operations.service.cache.CacheService;
import org.kaaproject.kaa.server.operations.service.cache.Computable;
import org.kaaproject.kaa.server.operations.service.cache.ConfigurationCacheEntry;
import org.kaaproject.kaa.server.operations.service.cache.ConfigurationIdKey;
import org.kaaproject.kaa.server.operations.service.cache.DeltaCacheKey;
import org.kaaproject.kaa.server.operations.service.cache.EventClassFamilyIdKey;
import org.kaaproject.kaa.server.operations.service.cache.EventClassFqnKey;
import org.kaaproject.kaa.server.operations.service.cache.HistoryKey;
import org.kaaproject.kaa.server.operations.service.cache.TopicListCacheEntry;
import org.kaaproject.kaa.server.operations.service.event.EventClassFamilyVersion;
import org.kaaproject.kaa.server.operations.service.event.EventClassFqnVersion;
import org.kaaproject.kaa.server.operations.service.event.RouteTableKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* The Class ConcurrentCacheService.
*/
@Service
public class ConcurrentCacheService implements CacheService {
/**
* The history seq number comparator.
*/
public static final Comparator<HistoryDto> HISTORY_SEQ_NUMBER_COMPARATOR = (o1, o2) -> {
if (o1.getSequenceNumber() > o2.getSequenceNumber()) {
return 1;
} else {
return o1.getSequenceNumber() == o2.getSequenceNumber() ? 0 : -1;
}
};
/**
* The Constant ALGORITHM.
*/
private static final String ALGORITHM = "RSA";
/**
* The Constant LOG.
*/
private static final Logger LOG = LoggerFactory.getLogger(ConcurrentCacheService.class);
/**
* The app seq number memorizer.
*/
private final CacheTemporaryMemorizer<String, AppSeqNumber> appSeqNumberMemorizer =
new CacheTemporaryMemorizer<>();
//
/**
* The cf id memorizer.
*/
private final CacheTemporaryMemorizer<ConfigurationIdKey, String> cfIdMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The history memorizer.
*/
private final CacheTemporaryMemorizer<HistoryKey, List<HistoryDto>> historyMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The filter lists memorizer.
*/
private final CacheTemporaryMemorizer<AppProfileVersionsKey, List<ProfileFilterDto>>
filterListsMemorizer = new CacheTemporaryMemorizer<>();
/**
* The application event family maps memorizer.
*/
private final CacheTemporaryMemorizer<List<String>, List<ApplicationEventFamilyMapDto>>
aefmMemorizer = new CacheTemporaryMemorizer<>();
/**
* The filters memorizer.
*/
private final CacheTemporaryMemorizer<String, ProfileFilterDto> filtersMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The cf memorizer.
*/
private final CacheTemporaryMemorizer<EndpointObjectHash, EndpointConfigurationDto> cfMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The cf schema memorizer.
*/
private final CacheTemporaryMemorizer<AppVersionKey, ConfigurationSchemaDto> cfSchemaMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The pf schema memorizer.
*/
private final CacheTemporaryMemorizer<AppVersionKey, EndpointProfileSchemaDto> pfSchemaMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The spf schema memorizer.
*/
private final CacheTemporaryMemorizer<AppVersionKey, ServerProfileSchemaDto> spfSchemaMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The ctl schema memorizer.
*/
private final CacheTemporaryMemorizer<String, CTLSchemaDto> ctlSchemaMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The ctl schema body memorizer.
*/
private final CacheTemporaryMemorizer<String, String> ctlSchemaBodyMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The SDK profile memorizer.
*/
private final CacheTemporaryMemorizer<String, SdkProfileDto> sdkProfileMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The endpoint key memorizer.
*/
private final CacheTemporaryMemorizer<EndpointObjectHash, PublicKey> endpointKeyMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The merged configuration memorizer.
*/
private final CacheTemporaryMemorizer<List<EndpointGroupStateDto>,
Pair<BaseData, RawData>> mergedConfigurationMemorizer = new CacheTemporaryMemorizer<>();
/**
* The delta memorizer.
*/
private final CacheTemporaryMemorizer<DeltaCacheKey, ConfigurationCacheEntry> deltaMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The endpoint key memorizer.
*/
private final CacheTemporaryMemorizer<EventClassFamilyIdKey, String> ecfIdKeyMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The endpoint key memorizer.
*/
private final CacheTemporaryMemorizer<String, String> tenantIdMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The application token memorizer.
*/
private final CacheTemporaryMemorizer<String, String> appTokenMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The endpoint groups memorizer.
*/
private final CacheTemporaryMemorizer<String, EndpointGroupDto> groupsMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The topics memorizer.
*/
private final CacheTemporaryMemorizer<String, TopicDto> topicsMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The default group memorizer.
*/
private final CacheTemporaryMemorizer<String, EndpointGroupDto> defaultGroupMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The topic list memorizer.
*/
private final CacheTemporaryMemorizer<EndpointObjectHash, TopicListCacheEntry>
topicListMemorizer = new CacheTemporaryMemorizer<>();
/**
* The endpoint key memorizer.
*/
private final CacheTemporaryMemorizer<EventClassFqnKey, String> ecfIdFqnMemorizer =
new CacheTemporaryMemorizer<>();
/**
* The endpoint key memorizer.
*/
private final CacheTemporaryMemorizer<EventClassFqnVersion, Set<RouteTableKey>>
routeKeysMemorizer = new CacheTemporaryMemorizer<>();
/**
* The application service.
*/
@Autowired
private ApplicationService applicationService;
/**
* The configuration service.
*/
@Autowired
private ConfigurationService configurationService;
/**
* The endpoint service.
*/
@Autowired
private EndpointService endpointService;
/**
* The topic service.
*/
@Autowired
private TopicService topicService;
/**
* The profile service.
*/
@Autowired
private ProfileService profileService;
/**
* The server profile service.
*/
@Autowired
private ServerProfileService serverProfileService;
@Autowired
private CtlService ctlService;
/**
* The history service.
*/
@Autowired
private HistoryService historyService;
@Autowired
private EventClassService eventClassService;
@Autowired
private ApplicationEventMapService applicationEventMapService;
@Autowired
private SdkProfileService sdkProfileService;
/**
* Checks if is supported.
*
* @param changeType the change type
* @return true, if is supported
*/
public static boolean isSupported(ChangeType changeType) {
switch (changeType) {
case ADD_CONF:
case ADD_PROF:
case ADD_TOPIC:
case REMOVE_CONF:
case REMOVE_PROF:
case REMOVE_TOPIC:
case REMOVE_GROUP:
return true;
default:
return false;
}
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* getAppSeqNumber(java.lang.String)
*/
@Override
@Cacheable(value = "appSeqNumbers", key = "#key")
public AppSeqNumber getAppSeqNumber(String key) {
return appSeqNumberMemorizer.compute(key, new Computable<String, AppSeqNumber>() {
@Override
public AppSeqNumber compute(String key) {
LOG.debug("Fetching result for getAppSeqNumber");
ApplicationDto appDto = applicationService.findAppByApplicationToken(key);
AppSeqNumber appSeqNumber = new AppSeqNumber(
appDto.getTenantId(),
appDto.getId(),
appDto.getApplicationToken(),
appDto.getSequenceNumber());
return appSeqNumber;
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* putAppSeqNumber(java.lang.String, java.lang.Integer)
*/
@Override
@CachePut(value = "appSeqNumbers", key = "#key")
public AppSeqNumber putAppSeqNumber(String key, AppSeqNumber appSeqNumber) {
return appSeqNumber;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* getConfIdByKey
* (org.kaaproject.kaa.server.operations.service.cache.ConfigurationIdKey)
*/
@Override
@Cacheable("configurationIds")
public String getConfIdByKey(ConfigurationIdKey key) {
return cfIdMemorizer.compute(key, new Computable<ConfigurationIdKey, String>() {
@Override
public String compute(ConfigurationIdKey key) {
LOG.debug("Fetching result for getConfIdByKey");
String confId = null;
List<ConfigurationDto> configurations =
configurationService.findConfigurationsByEndpointGroupId(key.getEndpointGroupId());
for (ConfigurationDto confDto : configurations) {
if (confDto.getSchemaVersion() == key.getConfigSchemaVersion()) {
confId = confDto.getId();
break;
}
}
return confId;
}
});
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#putConfId
* (org.kaaproject.kaa.server.operations.service.cache.ConfigurationIdKey,
* java.lang.String)
*/
@Override
@CachePut(value = "configurationIds", key = "#key")
public String putConfId(ConfigurationIdKey key, String value) {
return value;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#getHistory
* (org.kaaproject.kaa.server.operations.service.cache.HistoryKey)
*/
@Override
@Cacheable("history")
public List<HistoryDto> getHistory(HistoryKey key) {
return historyMemorizer.compute(key, new Computable<HistoryKey, List<HistoryDto>>() {
@Override
public List<HistoryDto> compute(HistoryKey key) {
LOG.debug("Fetching result for getHistory");
List<HistoryDto> relatedChanges = new ArrayList<HistoryDto>();
ApplicationDto appDto = applicationService.findAppByApplicationToken(key.getAppToken());
List<HistoryDto> fullHistoryList = historyService.findHistoriesBySeqNumberRange(
appDto.getId(), key.getOldSeqNumber(),
key.getNewSeqNumber());
Collections.sort(fullHistoryList, ConcurrentCacheService.HISTORY_SEQ_NUMBER_COMPARATOR);
for (HistoryDto historyDto : fullHistoryList) {
ChangeDto changeDto = historyDto.getChange();
ChangeType changeType = changeDto.getType();
if (!isSupported(changeType)) {
continue;
}
if (changeType == ChangeType.REMOVE_GROUP) {
relatedChanges.add(historyDto);
} else if (changeType == ChangeType.ADD_TOPIC || changeType == ChangeType.REMOVE_TOPIC) {
relatedChanges.add(historyDto);
} else if (changeType == ChangeType.ADD_PROF || changeType == ChangeType.REMOVE_PROF) {
ProfileFilterDto profileFilter = profileService.findProfileFilterById(
changeDto.getProfileFilterId());
if (profileFilter != null
&& supports(profileFilter,
key.getEndpointProfileSchemaVersion(),
key.getServerProfileSchemaVersion())) {
relatedChanges.add(historyDto);
}
} else if (changeType == ChangeType.ADD_CONF || changeType == ChangeType.REMOVE_CONF) {
if (changeDto.getCfVersion() == key.getConfSchemaVersion()) { // NOSONAR
relatedChanges.add(historyDto);
}
}
}
return relatedChanges;
}
private boolean supports(ProfileFilterDto profileFilter,
Integer endpointProfileSchemaVersion,
Integer serverProfileSchemaVersion) {
return (profileFilter.getEndpointProfileSchemaVersion() == null
|| profileFilter.getEndpointProfileSchemaVersion() == endpointProfileSchemaVersion)
&& (profileFilter.getServerProfileSchemaVersion() == null
|| profileFilter.getServerProfileSchemaVersion() == serverProfileSchemaVersion);
}
});
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#putHistory
* (org.kaaproject.kaa.server.operations.service.cache.HistoryKey,
* java.util.List)
*/
@Override
@CachePut(value = "history", key = "#key")
public List<HistoryDto> putHistory(HistoryKey key, List<HistoryDto> value) {
return value;
}
@Override
@Cacheable("applicationEFMs")
public List<ApplicationEventFamilyMapDto> getApplicationEventFamilyMapsByIds(List<String> key) {
return aefmMemorizer.compute(key,
new Computable<List<String>, List<ApplicationEventFamilyMapDto>>() {
@Override
public List<ApplicationEventFamilyMapDto> compute(List<String> key) {
LOG.debug("Fetching result for getApplicationEventFamilyMapsByIds");
List<ApplicationEventFamilyMapDto> value =
applicationEventMapService.findApplicationEventFamilyMapsByIds(key);
putApplicationEventFamilyMaps(key, value);
return value;
}
});
}
@Override
@CachePut(value = "applicationEFMs", key = "#key")
public List<ApplicationEventFamilyMapDto> putApplicationEventFamilyMaps(
List<String> key, List<ApplicationEventFamilyMapDto> value) {
return value;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#getFilters
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey)
*/
@Override
@Cacheable("filterLists")
public List<ProfileFilterDto> getFilters(AppProfileVersionsKey key) {
return filterListsMemorizer.compute(key,
new Computable<AppProfileVersionsKey, List<ProfileFilterDto>>() {
@Override
public List<ProfileFilterDto> compute(AppProfileVersionsKey key) {
LOG.debug("Fetching result for getFilters");
ApplicationDto appDto = applicationService.findAppByApplicationToken(
key.getApplicationToken());
List<ProfileFilterDto> value =
profileService.findProfileFiltersByAppIdAndVersionsCombination(appDto.getId(),
key.getEndpointProfileSchemaVersion(), key.getServerProfileSchemaVersion());
return value;
}
});
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#resetFilters
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey)
*/
@Override
@CacheEvict(value = "filterLists", key = "#key")
public void resetFilters(AppProfileVersionsKey key) {
// Do nothing
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#putFilterList
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey,
* java.util.List)
*/
@Override
@CachePut(value = "filterLists", key = "#key")
public List<ProfileFilterDto> putFilterList(AppProfileVersionsKey key,
List<ProfileFilterDto> value) {
return value;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#getFilter
* (java.lang.String)
*/
@Override
@Cacheable("filters")
public ProfileFilterDto getFilter(String key) {
return filtersMemorizer.compute(key, new Computable<String, ProfileFilterDto>() {
@Override
public ProfileFilterDto compute(String key) {
LOG.debug("Fetching result for getFilter");
ProfileFilterDto value = profileService.findProfileFilterById(key);
return value;
}
});
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#putFilter
* (java.lang.String, org.kaaproject.kaa.common.dto.ProfileFilterDto)
*/
@Override
@CachePut(value = "filters", key = "#key")
public ProfileFilterDto putFilter(String key, ProfileFilterDto value) {
return value;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#getConfByHash
* (org.kaaproject.kaa.common.hash.EndpointObjectHash)
*/
@Override
@Cacheable("configurations")
public EndpointConfigurationDto getConfByHash(EndpointObjectHash key) {
return cfMemorizer.compute(key,
new Computable<EndpointObjectHash, EndpointConfigurationDto>() {
@Override
public EndpointConfigurationDto compute(EndpointObjectHash key) {
LOG.debug("Fetching result for getConfByHash {}", key);
EndpointConfigurationDto value = endpointService.findEndpointConfigurationByHash(
key.getData());
return value;
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* putConfiguration(org.kaaproject.kaa.common.hash.EndpointObjectHash,
* org.kaaproject.kaa.common.dto.EndpointConfigurationDto)
*/
@Override
@CachePut(value = "configurations", key = "#key")
public EndpointConfigurationDto putConfiguration(EndpointObjectHash key,
EndpointConfigurationDto value) {
if (value != null) {
LOG.debug("Fetching result for getConfByHash");
value = endpointService.saveEndpointConfiguration(value);
}
return value;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* getConfSchemaByAppAndVersion
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey)
*/
@Override
@Cacheable("configurationSchemas")
public ConfigurationSchemaDto getConfSchemaByAppAndVersion(AppVersionKey key) {
return cfSchemaMemorizer.compute(key,
new Computable<AppVersionKey, ConfigurationSchemaDto>() {
@Override
public ConfigurationSchemaDto compute(AppVersionKey key) {
LOG.debug("Fetching result for getConfSchemaByAppAndVersion");
ApplicationDto appDto = applicationService.findAppByApplicationToken(
key.getApplicationToken());
ConfigurationSchemaDto value = configurationService.findConfSchemaByAppIdAndVersion(
appDto.getId(), key.getVersion());
return value;
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* putConfigurationSchema
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey,
* org.kaaproject.kaa.common.dto.ConfigurationSchemaDto)
*/
@Override
@CachePut(value = "configurationSchemas", key = "#key")
public ConfigurationSchemaDto putConfigurationSchema(AppVersionKey key,
ConfigurationSchemaDto value) {
return value;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* getProfileSchemaByAppAndVersion
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey)
*/
@Override
@Cacheable("endpointProfileSchemas")
public EndpointProfileSchemaDto getProfileSchemaByAppAndVersion(AppVersionKey key) {
return pfSchemaMemorizer.compute(key,
new Computable<AppVersionKey, EndpointProfileSchemaDto>() {
@Override
public EndpointProfileSchemaDto compute(AppVersionKey key) {
LOG.debug("Fetching result for getProfileSchemaByAppAndVersion");
ApplicationDto appDto = applicationService.findAppByApplicationToken(
key.getApplicationToken());
EndpointProfileSchemaDto value = profileService.findProfileSchemaByAppIdAndVersion(
appDto.getId(), key.getVersion());
return value;
}
});
}
@Override
@Cacheable("serverProfileSchemas")
public ServerProfileSchemaDto getServerProfileSchemaByAppAndVersion(AppVersionKey key) {
return spfSchemaMemorizer.compute(key,
new Computable<AppVersionKey, ServerProfileSchemaDto>() {
@Override
public ServerProfileSchemaDto compute(AppVersionKey key) {
LOG.debug("Fetching result for getServerProfileSchemaByAppAndVersion");
ApplicationDto appDto = applicationService.findAppByApplicationToken(
key.getApplicationToken());
ServerProfileSchemaDto value =
serverProfileService.findServerProfileSchemaByAppIdAndVersion(appDto.getId(),
key.getVersion());
return value;
}
});
}
@Override
@Cacheable("ctlSchemas")
public CTLSchemaDto getCtlSchemaById(String key) {
return ctlSchemaMemorizer.compute(key, new Computable<String, CTLSchemaDto>() {
@Override
public CTLSchemaDto compute(String key) {
LOG.debug("Fetching result for ctl schemas");
return ctlService.findCtlSchemaById(key);
}
});
}
@Override
@Cacheable("ctlSchemaBodies")
public String getFlatCtlSchemaById(String key) {
return ctlSchemaBodyMemorizer.compute(key, new Computable<String, String>() {
@Override
public String compute(String key) {
LOG.debug("Fetching result for ctl schemas");
CTLSchemaDto ctlSchema = ctlService.findCtlSchemaById(key);
return ctlService.flatExportAsString(ctlSchema);
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* putProfileSchema
* (org.kaaproject.kaa.server.operations.service.cache.AppVersionKey,
* org.kaaproject.kaa.common.dto.ProfileSchemaDto)
*/
@Override
@CachePut(value = "endpointProfileSchemas", key = "#key")
public EndpointProfileSchemaDto putProfileSchema(AppVersionKey key,
EndpointProfileSchemaDto value) {
return value;
}
@Override
@Cacheable(value = "sdkProfiles", unless = "#result == null")
public SdkProfileDto getSdkProfileBySdkToken(String key) {
return sdkProfileMemorizer.compute(key, new Computable<String, SdkProfileDto>() {
@Override
public SdkProfileDto compute(String key) {
LOG.debug("Fetching result for getSdkProfileBySdkToken");
return sdkProfileService.findSdkProfileByToken(key);
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* getEndpointKey(org.kaaproject.kaa.common.hash.EndpointObjectHash)
*/
@Override
@Cacheable(value = "endpointKeys", unless = "#result == null")
public PublicKey getEndpointKey(EndpointObjectHash key) {
return endpointKeyMemorizer.compute(key, new Computable<EndpointObjectHash, PublicKey>() {
@Override
public PublicKey compute(EndpointObjectHash key) {
LOG.debug("Fetching result for getEndpointKey");
PublicKey result = null;
EndpointProfileDto endpointProfile = endpointService.findEndpointProfileByKeyHash(
key.getData());
if (endpointProfile != null) {
try {
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(
endpointProfile.getEndpointKey());
KeyFactory keyFact = KeyFactory.getInstance(ALGORITHM);
result = keyFact.generatePublic(x509KeySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
LOG.error("failed to decode key", ex);
}
} else {
LOG.error("failed to find key by hash {}", key);
}
return result;
}
});
}
@Override
@Cacheable("ecfIds")
public String getEventClassFamilyIdByName(EventClassFamilyIdKey key) {
return ecfIdKeyMemorizer.compute(key, new Computable<EventClassFamilyIdKey, String>() {
@Override
public String compute(EventClassFamilyIdKey key) {
LOG.debug("Fetching result for getEcfvId using key {}", key);
EventClassFamilyDto ecf = eventClassService.findEventClassFamilyByTenantIdAndName(
key.getTenantId(), key.getName());
if (ecf != null) {
return ecf.getId();
} else {
LOG.error("failed to find ecf by tenantId [{}] and name {}",
key.getTenantId(), key.getName());
return null;
}
}
});
}
@Override
@Cacheable("ecfIds")
public String getEventClassFamilyIdByEventClassFqn(EventClassFqnKey key) {
return ecfIdFqnMemorizer.compute(key, new Computable<EventClassFqnKey, String>() {
@Override
public String compute(EventClassFqnKey key) {
LOG.debug("Fetching result for getEventClassFamilyIdByEventClassFqn using key {}", key);
List<EventClassDto> eventClasses = eventClassService.findEventClassByTenantIdAndFqn(
key.getTenantId(), key.getFqn());
if (eventClasses != null && !eventClasses.isEmpty()) {
String ecfvId = eventClasses.get(0).getEcfvId();
return eventClassService.findEventClassFamilyByEcfvId(ecfvId).getId();
} else {
LOG.warn("Fetching result for getEcfvId using key {} Failed!", key);
return null;
}
}
});
}
@Override
@Cacheable("routeKeys")
public Set<RouteTableKey> getRouteKeys(EventClassFqnVersion key) {
return routeKeysMemorizer.compute(key,
new Computable<EventClassFqnVersion, Set<RouteTableKey>>() {
@Override
public Set<RouteTableKey> compute(EventClassFqnVersion key) {
LOG.debug("Fetching result for getRouteKeys using key {}", key);
Set<RouteTableKey> routeKeys = new HashSet<>();
EventClassDto eventClass = eventClassService.findEventClassByTenantIdAndFqnAndVersion(
key.getTenantId(), key.getFqn(),
key.getVersion());
String ecfvId = eventClass.getEcfvId();
String ecfId = eventClassService.findEventClassFamilyByEcfvId(ecfvId).getId();
List<ApplicationEventFamilyMapDto> mappingList =
applicationEventMapService.findByEcfIdAndVersion(ecfId,
key.getVersion());
for (ApplicationEventFamilyMapDto mapping : mappingList) {
String applicationId = mapping.getApplicationId();
ApplicationDto appDto = applicationService.findAppById(applicationId);
RouteTableKey routeTableKey = new RouteTableKey(
appDto.getApplicationToken(), new EventClassFamilyVersion(
ecfId, key.getVersion()));
if (!routeKeys.contains(routeTableKey)) {
for (ApplicationEventMapDto eventMap : mapping.getEventMaps()) {
if (eventMap.getEventClassId().equals(eventClass.getId())
&& (ApplicationEventAction.SINK == eventMap.getAction()
|| ApplicationEventAction.BOTH == eventMap.getAction())) {
routeKeys.add(routeTableKey);
break;
}
}
}
}
return routeKeys;
}
});
}
@Override
@Cacheable("tenantIds")
public String getTenantIdByAppToken(String key) {
// TODO: throw exception instead of returning null
return tenantIdMemorizer.compute(key, new Computable<String, String>() {
@Override
public String compute(String key) {
LOG.debug("Fetching result for token id");
ApplicationDto appDto = applicationService.findAppByApplicationToken(key);
return appDto != null ? appDto.getTenantId() : null;
}
});
}
@Override
@Cacheable("appTokens")
public String getAppTokenBySdkToken(String key) {
return appTokenMemorizer.compute(key, new Computable<String, String>() {
@Override
public String compute(String key) {
LOG.debug("Fetching result for sdk token: {} to retrieve application token", key);
SdkProfileDto sdkProfileDto = sdkProfileService.findSdkProfileByToken(key);
String appToken = sdkProfileDto != null ? sdkProfileDto.getApplicationToken() : null;
LOG.trace("Resolved application token: {}", appToken);
return appToken;
}
});
}
@Override
@Cacheable("apps")
public ApplicationDto findAppById(String applicationId) {
return applicationService.findAppById(applicationId);
}
@Override
@CacheEvict(value = "apps", key = "#applicationId")
public void resetAppById(String applicationId) {
return;
}
@Override
@Cacheable("appIds")
public String getApplicationIdByAppToken(String key) {
return appTokenMemorizer.compute(key, new Computable<String, String>() {
@Override
public String compute(String key) {
LOG.debug("Fetching result for token id");
ApplicationDto appDto = applicationService.findAppByApplicationToken(key);
return appDto != null ? appDto.getId() : null;
}
});
}
/**
* Put endpoint key.
*
* @param key the key
* @param endpointKey the endpoint key
* @return the public key
*/
@Override
@CachePut(value = "endpointKeys", key = "#key")
public PublicKey putEndpointKey(EndpointObjectHash key, PublicKey endpointKey) {
return endpointKey;
}
/**
* Remove key from hash.
*/
@Override
@CacheEvict(value = "endpointKeys", key = "#key")
public void resetEndpointKey(EndpointObjectHash hash, PublicKey endpointKey) {
// Do nothing
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* getMergedConfiguration(java.util.List,
* org.kaaproject.kaa.server.operations.service.cache.Computable)
*/
@Override
@Cacheable(value = "mergedConfigurations", key = "#key")
public Pair<BaseData, RawData> getMergedConfiguration(
final List<EndpointGroupStateDto> key,
final Computable<List<EndpointGroupStateDto>,
Pair<BaseData, RawData>> worker) {
return mergedConfigurationMemorizer.compute(key,
new Computable<List<EndpointGroupStateDto>, Pair<BaseData, RawData>>() {
@Override
public Pair<BaseData, RawData> compute(List<EndpointGroupStateDto> key) {
LOG.debug("Fetching result for getMergedConfiguration");
Pair<BaseData, RawData> result = worker.compute(key);
return result;
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* setMergedConfiguration(java.util.List, java.lang.String)
*/
@Override
@CachePut(value = "mergedConfigurations", key = "#key")
public BaseData setMergedConfiguration(List<EndpointGroupStateDto> key,
BaseData mergedConfiguration) {
return mergedConfiguration;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#getDelta
* (org.kaaproject.kaa.server.operations.service.cache.DeltaCacheKey,
* org.kaaproject.kaa.server.operations.service.cache.Computable)
*/
@Override
@Cacheable(value = "deltas", key = "#key")
public ConfigurationCacheEntry getDelta(final DeltaCacheKey key,
final Computable<DeltaCacheKey,
ConfigurationCacheEntry> worker)
throws GetDeltaException {
ConfigurationCacheEntry deltaCacheEntry = deltaMemorizer.compute(key,
new Computable<DeltaCacheKey, ConfigurationCacheEntry>() { // NOSONAR
@Override
public ConfigurationCacheEntry compute(DeltaCacheKey key) {
LOG.debug("Fetching result for getMergedConfiguration");
ConfigurationCacheEntry result = worker.compute(key);
return result;
}
});
return deltaCacheEntry;
}
/*
* (non-Javadoc)
*
* @see
* org.kaaproject.kaa.server.operations.service.cache.CacheService#setDelta
* (org.kaaproject.kaa.server.operations.service.cache.DeltaCacheKey,
* org.kaaproject.kaa.server.operations.service.cache.DeltaCacheEntry)
*/
@Override
@CachePut(value = "deltas", key = "#key")
public ConfigurationCacheEntry setDelta(DeltaCacheKey key, ConfigurationCacheEntry delta) {
return delta;
}
@Override
@CacheEvict(value = "endpointGroups", key = "#key")
public void resetGroup(String key) {
// Do nothing
}
@Override
@CachePut(value = "endpointGroups", key = "#key")
public EndpointGroupDto putEndpointGroup(String key, EndpointGroupDto value) {
return value;
}
@Override
@Cacheable("endpointGroups")
public EndpointGroupDto getEndpointGroupById(String endpointGroupId) {
return groupsMemorizer.compute(endpointGroupId, new Computable<String, EndpointGroupDto>() {
@Override
public EndpointGroupDto compute(String key) {
LOG.debug("Fetching result for token id");
EndpointGroupDto groupDto = endpointService.findEndpointGroupById(key);
return groupDto;
}
});
}
@Override
@CachePut(value = "topics", key = "#key")
public TopicDto putTopic(String key, TopicDto value) {
return value;
}
@Override
@Cacheable("topics")
public TopicDto getTopicById(String topicId) {
return topicsMemorizer.compute(topicId, new Computable<String, TopicDto>() {
@Override
public TopicDto compute(String key) {
LOG.debug("Fetching result for token id");
TopicDto topicDto = topicService.findTopicById(key);
return topicDto;
}
});
}
@Override
@Cacheable("defaultGroups")
public EndpointGroupDto getDefaultGroup(String applicationToken) {
return defaultGroupMemorizer.compute(applicationToken, applicationToken1 -> {
LOG.debug("Fetching result for token id");
ApplicationDto appDto = applicationService.findAppByApplicationToken(applicationToken1);
return endpointService.findDefaultGroup(appDto.getId());
});
}
@Override
@CachePut(value = "topicListEntries", key = "#key")
public TopicListCacheEntry putTopicList(EndpointObjectHash key, TopicListCacheEntry entry) {
if (entry != null) {
TopicListEntryDto entryDto = new TopicListEntryDto(
entry.getSimpleHash(), entry.getHash().getData(), entry.getTopics());
endpointService.saveTopicListEntry(entryDto);
}
return entry;
}
@Override
@Cacheable("topicListEntries")
public TopicListCacheEntry getTopicListByHash(EndpointObjectHash hash) {
return topicListMemorizer.compute(hash,
new Computable<EndpointObjectHash, TopicListCacheEntry>() {
@Override
public TopicListCacheEntry compute(EndpointObjectHash key) {
LOG.debug("Fetching result for getTopicListByHash {}", key);
TopicListEntryDto entryDto = endpointService.findTopicListEntryByHash(key.getData());
if (entryDto != null) {
return new TopicListCacheEntry(
entryDto.getSimpleHash(),
EndpointObjectHash.fromBytes(entryDto.getHash()),
entryDto.getTopics());
} else {
return null;
}
}
});
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* setApplicationService
* (org.kaaproject.kaa.server.common.dao.ApplicationService)
*/
@Override
public void setApplicationService(ApplicationService applicationService) {
this.applicationService = applicationService;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* setConfigurationService
* (org.kaaproject.kaa.server.common.dao.ConfigurationService)
*/
@Override
public void setConfigurationService(ConfigurationService configurationService) {
this.configurationService = configurationService;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* setHistoryService(org.kaaproject.kaa.server.common.dao.HistoryService)
*/
@Override
public void setHistoryService(HistoryService historyService) {
this.historyService = historyService;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* setProfileService(org.kaaproject.kaa.server.common.dao.ProfileService)
*/
@Override
public void setProfileService(ProfileService profileService) {
this.profileService = profileService;
}
/*
* (non-Javadoc)
*
* @see org.kaaproject.kaa.server.operations.service.cache.CacheService#
* setEndpointService(org.kaaproject.kaa.server.common.dao.EndpointService)
*/
@Override
public void setEndpointService(EndpointService endpointService) {
this.endpointService = endpointService;
}
@Override
public void setEventClassService(EventClassService eventClassService) {
this.eventClassService = eventClassService;
}
@Override
public void setApplicationEventMapService(
ApplicationEventMapService applicationEventMapService) {
this.applicationEventMapService = applicationEventMapService;
}
@Override
public void setSdkProfileService(SdkProfileService sdkProfileService) {
this.sdkProfileService = sdkProfileService;
}
}