2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.model.cache;
23 import fj.data.Either;
24 import org.apache.commons.lang3.tuple.ImmutablePair;
25 import org.apache.commons.lang3.tuple.ImmutableTriple;
26 import org.openecomp.sdc.be.config.BeEcompErrorManager;
27 import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity;
28 import org.openecomp.sdc.be.config.Configuration;
29 import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheCatalogInfo;
30 import org.openecomp.sdc.be.config.Configuration.ApplicationL2CacheConfig;
31 import org.openecomp.sdc.be.config.ConfigurationManager;
32 import org.openecomp.sdc.be.dao.api.ActionStatus;
33 import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus;
34 import org.openecomp.sdc.be.dao.cassandra.ComponentCassandraDao;
35 import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition;
36 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
37 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
38 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
39 import org.openecomp.sdc.be.model.*;
40 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
41 import org.openecomp.sdc.be.resources.data.ComponentCacheData;
42 import org.openecomp.sdc.common.log.wrappers.Logger;
43 import org.openecomp.sdc.common.util.SerializationUtils;
44 import org.openecomp.sdc.common.util.ZipUtil;
45 import org.springframework.beans.factory.annotation.Autowired;
47 import javax.annotation.PostConstruct;
48 import java.io.IOException;
50 import java.util.concurrent.locks.Lock;
51 import java.util.concurrent.locks.ReentrantReadWriteLock;
52 import java.util.function.Function;
53 import java.util.stream.Collectors;
54 import java.util.List;
58 @org.springframework.stereotype.Component("component-cache")
59 public class ComponentCache {
61 private static final String COMPONENT_CACHE_IS_DISABLED = "Component Cache is disabled";
63 private static final Logger log = Logger.getLogger(ComponentCache.class);
66 ComponentCassandraDao componentCassandraDao;
69 ToscaOperationFacade toscaOperationFacade;
71 private Map<ComponentTypeEnum, Map<String, Component>> catalogInMemoryCache = new HashMap<>();
72 private final ReentrantReadWriteLock rwCatalogLock = new ReentrantReadWriteLock();
73 private final Lock rCatalogLock = rwCatalogLock.readLock();
74 private final Lock wCatalogLock = rwCatalogLock.writeLock();
76 boolean enabled = true;
77 int catalogInMemorySizePerResource = 300;
78 int catalogInMemorySizePerService = 200;
79 int catalogInMemorySizePerProduct = 100;
80 boolean catalogInMemoryEnabled = true;
81 Map<ComponentTypeEnum, Integer> limitMemoryCatalogSizePerType = new HashMap<>();
86 Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
87 if (configuration != null) {
88 ApplicationL2CacheConfig applicationL2Cache = configuration.getApplicationL2Cache();
89 if (applicationL2Cache != null) {
90 this.enabled = applicationL2Cache.isEnabled();
92 ApplicationL1CacheCatalogInfo catalog = applicationL2Cache.getCatalogL1Cache();
93 if (catalog != null) {
94 catalogInMemoryEnabled = catalog.getEnabled();
95 catalogInMemorySizePerResource = catalog.getResourcesSizeInCache();
96 catalogInMemorySizePerService = catalog.getServicesSizeInCache();
97 catalogInMemorySizePerProduct = catalog.getProductsSizeInCache();
102 ComponentTypeEnum[] typesForCache = { ComponentTypeEnum.RESOURCE, ComponentTypeEnum.SERVICE,
103 ComponentTypeEnum.PRODUCT };
104 for (ComponentTypeEnum typeEnum : typesForCache) {
105 Map<String, Component> map = new HashMap<>();
106 catalogInMemoryCache.put(typeEnum, map);
109 limitMemoryCatalogSizePerType.put(ComponentTypeEnum.RESOURCE, catalogInMemorySizePerResource);
110 limitMemoryCatalogSizePerType.put(ComponentTypeEnum.SERVICE, catalogInMemorySizePerService);
111 limitMemoryCatalogSizePerType.put(ComponentTypeEnum.PRODUCT, catalogInMemorySizePerProduct);
114 public boolean isEnabled() {
118 public void setEnabled(boolean enabled) {
119 this.enabled = enabled;
122 public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime,
123 Function<Component, Component> filterFieldsFunc) {
125 Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
126 componentUid, lastModificationTime, filterFieldsFunc);
128 if (componentFromCache.isRight()) {
129 return Either.right(componentFromCache.right().value());
132 return Either.left(componentFromCache.left().value().left);
136 public Either<List<ComponentCacheData>, ActionStatus> getAllComponentIdTimeAndType() {
138 return Either.right(ActionStatus.NOT_ALLOWED);
141 return componentCassandraDao
142 .getAllComponentIdTimeAndType();
147 * get components for catalog
150 * @param componentTypeEnum
154 public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
155 Set<String> components, ComponentTypeEnum componentTypeEnum) {
158 log.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
159 componentTypeEnum.name().toLowerCase());
160 return Either.right(ActionStatus.NOT_ALLOWED);
162 log.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
164 Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForCatalog;
166 Set<String> leftComponentsForSearch = new HashSet<>();
167 leftComponentsForSearch.addAll(components);
169 // get components from inmemory cache
170 List<Component> componentsFromMemory = null;
171 if (catalogInMemoryEnabled) {
172 componentsFromMemory = getDataFromInMemoryCache(components, componentTypeEnum);
173 log.debug("The number of components of type {} fetched from memory is {}",
174 componentTypeEnum.name().toLowerCase(),
175 componentsFromMemory == null ? 0 : componentsFromMemory.size());
176 if (componentsFromMemory != null) {
177 componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
180 log.debug("Catalog InMemory cache is disabled");
183 log.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
184 leftComponentsForSearch.size());
186 // get components from cassandra cache and filter each component
187 Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result = getComponents(
188 leftComponentsForSearch, filterFieldsFunc);
190 if (result.isLeft()) {
191 // add inmemory components to the valid components(not dirty)
192 List<Component> foundComponents = result.left().value().getLeft();
193 if (componentsFromMemory != null) {
194 foundComponents.addAll(componentsFromMemory);
196 if (catalogInMemoryEnabled) {
197 updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
205 * @param foundComponents
206 * @param componentTypeEnum
208 private void updateCatalogInMemoryCacheWithCertified(List<Component> foundComponents,
209 ComponentTypeEnum componentTypeEnum) {
214 long start = System.currentTimeMillis();
215 Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
216 int mapSizeBefore = map.size();
218 Map<String, Component> collect = foundComponents.stream()
219 .filter(p -> p.getLifecycleState() == LifecycleStateEnum.CERTIFIED)
220 .limit(limitMemoryCatalogSizePerType.get(componentTypeEnum))
221 .collect(Collectors.toMap(Component::getUniqueId, p -> p));
224 "Size of in memory cache for catalog {}(certified only): Before {}, After {}. Replacement Time is {} ms.",
225 componentTypeEnum.name().toLowerCase(), mapSizeBefore, map.size(),
226 System.currentTimeMillis() - start);
228 wCatalogLock.unlock();
233 private List<Component> getDataFromInMemoryCache(Set<String> components, ComponentTypeEnum componentTypeEnum) {
234 List<Component> foundComponents = new ArrayList<>();
240 Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
241 for (String compUid : components) {
242 Component component = map.get(compUid);
243 if (component != null) {
244 foundComponents.add(component);
249 rCatalogLock.unlock();
252 return foundComponents;
257 * get full components from cassandra. On each component apply filter
258 * function in order to remove unused members
261 * @param filterFieldsFunc
262 * @return <found components, found dirty components, not found components
265 public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponents(
266 Set<String> components, Function<List<Component>, List<Component>> filterFieldsFunc) {
269 log.debug(COMPONENT_CACHE_IS_DISABLED);
270 return Either.right(ActionStatus.NOT_ALLOWED);
273 Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
276 if (componentsFull.isRight()) {
277 return Either.right(componentsFull.right().value());
280 ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = componentsFull.left().value();
281 List<Component> foundResources = immutableTriple.left;
282 List<Component> foundDirtyResources = immutableTriple.middle;
283 Set<String> notFoundResources = immutableTriple.right;
285 List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
286 List<Component> filterdFoundDirtyResources = filterFieldsFunc.apply(foundDirtyResources);
288 ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<>(
289 filterdFoundResources, filterdFoundDirtyResources, notFoundResources);
291 return Either.left(result);
295 public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForLeftPanel(
296 ComponentTypeEnum componentTypeEnum, String internalComponentType, Set<String> filteredResources) {
298 log.debug("In getComponentsForLeftPanel componentTypeEnum = {}, internalComponentType = {}",
299 componentTypeEnum, internalComponentType);
301 Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForLeftPanel;
303 return getComponents(filteredResources, filterFieldsFunc);
307 private List<Component> filterForLeftPanel(List<Component> components) {
309 List<Component> result = new ArrayList<>();
310 if (components != null) {
311 components.forEach(p -> result.add(filterFieldsForLeftPanel(p)));
317 private List<Component> filterForCatalog(List<Component> components) {
319 List<Component> result = new ArrayList<>();
320 if (components != null) {
321 components.forEach(p -> result.add(filterFieldsForCatalog(p)));
327 private Component filterFieldsForLeftPanel(Component component) {
329 Component result = null;
330 ComponentTypeEnum componentTypeEnum = component.getComponentType();
331 switch (componentTypeEnum) {
333 result = new Resource();
334 copyFieldsForLeftPanel(component, result);
337 result = new Service();
338 copyFieldsForLeftPanel(component, result);
347 private Component filterFieldsForCatalog(Component component) {
349 Component result = null;
350 ComponentTypeEnum componentTypeEnum = component.getComponentType();
351 switch (componentTypeEnum) {
353 result = new Resource();
354 copyFieldsForCatalog(component, result);
357 result = new Service();
358 copyFieldsForCatalog(component, result);
361 result = new Product();
362 copyFieldsForCatalog(component, result);
372 * Copy relevant fields to the filtered component for left panel
375 * @param filteredComponent
377 private void copyFieldsForLeftPanel(Component component, Component filteredComponent) {
379 ComponentTypeEnum componentTypeEnum = component.getComponentType();
380 filteredComponent.setCategories(component.getCategories());
381 filteredComponent.setComponentType(component.getComponentType());
382 if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())
383 && ResourceTypeEnum.VL.equals(((ResourceMetadataDataDefinition) component
384 .getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType())) {
385 filteredComponent.setCapabilities(component.getCapabilities());
386 filteredComponent.setRequirements(component.getRequirements());
388 filteredComponent.setVersion(component.getVersion());
389 filteredComponent.setDescription(component.getDescription());
390 filteredComponent.setUniqueId(component.getUniqueId());
391 filteredComponent.setIcon(component.getIcon());
392 filteredComponent.setTags(component.getTags());
393 filteredComponent.setLifecycleState(component.getLifecycleState());
394 filteredComponent.setInvariantUUID(component.getInvariantUUID());
395 filteredComponent.setUUID(component.getUUID());
396 filteredComponent.setSystemName(component.getSystemName());
397 filteredComponent.setName(component.getName());
399 if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
400 Resource resource = (Resource) component;
401 Resource filteredResource = (Resource) filteredComponent;
402 filteredResource.setToscaResourceName(resource.getToscaResourceName());
403 filteredResource.setResourceType(resource.getResourceType());
407 private void copyFieldsForCatalog(Component component, Component filteredComponent) {
409 ComponentTypeEnum componentTypeEnum = component.getComponentType();
410 filteredComponent.setCategories(component.getCategories());
411 filteredComponent.setComponentType(component.getComponentType());
412 filteredComponent.setVersion(component.getVersion());
413 filteredComponent.setDescription(component.getDescription());
414 filteredComponent.setUniqueId(component.getUniqueId());
415 filteredComponent.setIcon(component.getIcon());
416 filteredComponent.setTags(component.getTags());
417 filteredComponent.setLifecycleState(component.getLifecycleState());
418 filteredComponent.setSystemName(component.getSystemName());
419 filteredComponent.setName(component.getName());
420 filteredComponent.setLastUpdateDate(component.getLastUpdateDate());
422 if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
423 Resource resource = (Resource) component;
424 Resource filteredResource = (Resource) filteredComponent;
425 filteredResource.setToscaResourceName(resource.getToscaResourceName());
426 filteredResource.setResourceType(resource.getResourceType());
427 } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) {
428 Service service = (Service) component;
429 Service filteredService = (Service) filteredComponent;
430 filteredService.setDistributionStatus(service.getDistributionStatus());
435 * get components from cache of a given list ou unique ids.
437 * for each component data from cassandra, unzip the data if needed and
438 * deserialize the unzipped data to java object(Component).
440 * @param filteredResources
441 * @return ImmutableTripple or ActionStatus. | |-- components |-- dirty
442 * components - components with dirty flag = true. |-- set of non
446 private Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsFull(
447 Set<String> filteredResources) {
450 log.debug(COMPONENT_CACHE_IS_DISABLED);
451 return Either.right(ActionStatus.NOT_ALLOWED);
454 List<Component> foundResources = new LinkedList<>();
455 List<Component> foundDirtyResources = new LinkedList<>();
456 Set<String> notFoundResources = new HashSet<>();
457 ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<>(
458 foundResources, foundDirtyResources, notFoundResources);
460 long cassandraFetchStart = System.currentTimeMillis();
461 List<String> uidsList = new ArrayList<>();
462 uidsList.addAll(filteredResources);
463 Either<List<ComponentCacheData>, ActionStatus> componentsFromCache = componentCassandraDao
464 .getComponents(uidsList);
466 long cassandraFetchEnd = System.currentTimeMillis();
467 log.debug("Fetch time from cassandara of all components took {} ms",
468 (cassandraFetchEnd - cassandraFetchStart));
469 if (componentsFromCache.isRight()) {
470 BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
471 "Failed to fetch components from cache", ErrorSeverity.ERROR);
472 return Either.right(componentsFromCache.right().value());
475 List<ComponentCacheData> list = componentsFromCache.left().value();
476 log.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
477 if (list != null && !list.isEmpty()) {
479 List<ComponentCacheData> filteredData = list.stream().filter(p -> filteredResources.contains(p.getId()))
480 .collect(Collectors.toList());
481 log.debug("Number of components filterd is {}", filteredData == null ? 0 : filteredData.size());
483 if (filteredData != null) {
484 long desStart = System.currentTimeMillis();
486 for (ComponentCacheData componentCacheData : filteredData) {
488 log.debug("Process uid {} from cache", componentCacheData.getId());
490 String compUid = componentCacheData.getId();
492 Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
495 if (deserializeExt.isLeft()) {
496 Component component = deserializeExt.left().value();
497 if (!componentCacheData.getIsDirty()) {
498 foundResources.add(component);
500 foundDirtyResources.add(component);
503 notFoundResources.add(compUid);
507 long desEnd = System.currentTimeMillis();
508 log.debug("Deserialization and unzip of {} components took {} ms", filteredData.size(),
509 (desEnd - desStart));
512 List<String> foundResourcesUid = foundResources.stream().map(Component::getUniqueId).collect(Collectors.toList());
513 List<String> foundDirtyResourcesUid = foundDirtyResources.stream().map(Component::getUniqueId)
514 .collect(Collectors.toList());
515 log.debug("Number of processed components from cache is {}",
516 (foundResourcesUid.size() + foundDirtyResourcesUid.size()));
517 Set<String> notCachedResources = filteredResources.stream()
518 .filter(p -> !foundResourcesUid.contains(p) && !foundDirtyResourcesUid.contains(p))
519 .collect(Collectors.toSet());
520 notFoundResources.addAll(notCachedResources);
522 if (log.isDebugEnabled()) {
523 log.debug("Number of components fetched is {}", foundResources.size());
524 log.debug("Number of components fetched dirty is {}", foundDirtyResources.size());
525 log.debug("Number of components non cached is {}", notCachedResources.size());
528 return Either.left(result);
531 private Either<? extends Component, Boolean> convertComponentCacheToComponent(
532 ComponentCacheData componentCacheData) {
534 String compUid = componentCacheData.getId();
536 byte[] dataAsArray = componentCacheData.getDataAsArray();
538 if (componentCacheData.getIsZipped()) {
539 long startUnzip = System.nanoTime();
540 dataAsArray = ZipUtil.unzip(dataAsArray);
541 long endUnzip = System.nanoTime();
542 log.trace("Unzip component {} took {} microsecond", compUid, (endUnzip - startUnzip) / 1000);
545 long startDes = System.nanoTime();
547 Either<? extends Component, Boolean> deserializeExt = deserializeComponent(componentCacheData, dataAsArray);
549 long endDes = System.nanoTime();
550 log.trace("Deserialize component {} took {} microsecond", compUid, (endDes - startDes) / 1000);
551 return deserializeExt;
554 private Either<? extends Component, Boolean> deserializeComponent(ComponentCacheData componentCacheData,
555 byte[] dataAsArray) {
556 String type = componentCacheData.getType();
557 NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(type);
559 Either<? extends Component, Boolean> deserializeExt = Either.right(false);
562 deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Resource.class, componentCacheData.getId());
565 deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Service.class, componentCacheData.getId());
568 deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Product.class, componentCacheData.getId());
573 return deserializeExt;
576 public Either<Component, ActionStatus> getComponent(String componentUid) {
578 return getComponent(componentUid, null, Function.identity());
582 private boolean saveComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum,
583 Component component) {
585 log.trace("Going to save component {} of type {} in cache", componentUid, nodeTypeEnum.name().toLowerCase());
587 boolean result = false;
589 Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(component);
590 if (serializeExt.isLeft()) {
591 byte[] serializedData = serializeExt.left().value();
594 zipBytes = ZipUtil.zipBytes(serializedData);
595 ComponentCacheData componentCacheData = new ComponentCacheData();
596 componentCacheData.setDataAsArray(zipBytes);
597 componentCacheData.setIsZipped(true);
598 componentCacheData.setId(componentUid);
599 componentCacheData.setModificationTime(new Date(lastModificationTime));
600 componentCacheData.setType(component.getComponentType().name().toLowerCase());
602 CassandraOperationStatus status = componentCassandraDao.saveComponent(componentCacheData);
604 if (status == CassandraOperationStatus.OK) {
608 } catch (IOException e) {
609 log.debug("Failed to prepare component {} of type {} for cache", componentUid,
610 nodeTypeEnum.name().toLowerCase());
611 if (log.isTraceEnabled()) {
612 log.trace("Failed to prepare component {} of type {} for cache",componentUid,nodeTypeEnum.name().toLowerCase());
616 log.debug("Failed to serialize component {} of type {} for cache", componentUid,
617 nodeTypeEnum.name().toLowerCase());
622 public boolean setComponent(Component component, NodeTypeEnum nodeTypeEnum) {
624 boolean result = false;
627 log.debug(COMPONENT_CACHE_IS_DISABLED);
631 String componentUid = component.getUniqueId();
632 Long lastUpdateDate = component.getLastUpdateDate();
634 result = saveComponent(componentUid, lastUpdateDate, nodeTypeEnum, component);
641 * get components from cache of a given list ou unique ids.
643 * for each component data from cassandra, unzip the data if needed and
644 * deserialize the unzipped data to java object(Component).
646 * @param filteredResources
647 * @return ImmutableTripple or ActionStatus. | |-- components |-- set of non
651 private Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsFull(
652 Map<String, Long> filteredResources) {
655 log.debug(COMPONENT_CACHE_IS_DISABLED);
656 return Either.right(ActionStatus.NOT_ALLOWED);
659 List<Component> foundResources = new LinkedList<>();
660 Set<String> notFoundResources = new HashSet<>();
661 ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<>(
662 foundResources, notFoundResources);
664 long cassandraFetchStart = System.currentTimeMillis();
666 Either<ImmutablePair<List<ComponentCacheData>, Set<String>>, ActionStatus> componentsFromCache = componentCassandraDao
667 .getComponents(filteredResources);
669 long cassandraFetchEnd = System.currentTimeMillis();
670 log.debug("Fetch time from cassandara of all components took {} ms",
671 (cassandraFetchEnd - cassandraFetchStart));
672 if (componentsFromCache.isRight()) {
673 BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
674 "Failed to fetch components from cache", ErrorSeverity.ERROR);
675 return Either.right(componentsFromCache.right().value());
678 ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = componentsFromCache.left().value();
679 List<ComponentCacheData> list = immutablePair.getLeft();
680 log.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
681 if (list != null && !list.isEmpty()) {
683 log.debug("Number of components filterd is {}", list == null ? 0 : list.size());
686 long desStart = System.currentTimeMillis();
688 for (ComponentCacheData componentCacheData : list) {
690 log.debug("Process uid {} from cache", componentCacheData.getId());
692 String compUid = componentCacheData.getId();
694 Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
697 if (deserializeExt.isLeft()) {
698 Component component = deserializeExt.left().value();
699 foundResources.add(component);
701 notFoundResources.add(compUid);
705 long desEnd = System.currentTimeMillis();
706 log.debug("Deserialization and unzip of {} components took {} ms", list.size(), (desEnd - desStart));
709 log.debug("Number of processed components from cache is {}", foundResources.size());
711 Set<String> notFoundInCache = immutablePair.getRight();
712 notFoundResources.addAll(notFoundInCache);
714 if (log.isDebugEnabled()) {
715 log.debug("Number of components fetched is {}", foundResources.size());
716 log.debug("Number of components non cached is {}", notFoundResources.size());
719 return Either.left(result);
723 * get components for catalog
726 * @param componentTypeEnum
729 public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
730 Map<String, Long> components, ComponentTypeEnum componentTypeEnum) {
733 log.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
734 componentTypeEnum.name().toLowerCase());
735 return Either.right(ActionStatus.NOT_ALLOWED);
737 log.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
739 Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForCatalog;
741 Map<String, Long> leftComponentsForSearch = new HashMap<>();
742 leftComponentsForSearch.putAll(components);
744 // get components from inmemory cache
745 List<Component> componentsFromMemory = null;
746 if (catalogInMemoryEnabled) {
747 componentsFromMemory = getDataFromInMemoryCache(components.keySet(), componentTypeEnum);
748 log.debug("The number of components of type {} fetched from memory is {}",
749 componentTypeEnum.name().toLowerCase(),
750 componentsFromMemory == null ? 0 : componentsFromMemory.size());
751 if (componentsFromMemory != null) {
752 List<String> ignoredComponents = new ArrayList<>();
753 for (Component componentFromMem : componentsFromMemory) {
754 if (componentFromMem.getLastUpdateDate().longValue() != components
755 .get(componentFromMem.getUniqueId()).longValue()) {
756 // Ignore the component from memory
757 ignoredComponents.add(componentFromMem.getUniqueId());
761 log.debug("Number of components from type {} ignored from memory cache is {}",
762 componentTypeEnum.name().toLowerCase(), ignoredComponents.size());
763 // remove from memory result the components which are not valid
764 componentsFromMemory = componentsFromMemory.stream()
765 .filter(p -> !ignoredComponents.contains(p.getUniqueId())).collect(Collectors.toList());
766 // Remove from leftComponentsForSearch the valid components from
768 componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
772 log.debug("Catalog InMemory cache is disabled");
775 log.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
776 leftComponentsForSearch.size());
778 // get components from cassandra cache and filter each component
779 Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result = getComponents(
780 leftComponentsForSearch, filterFieldsFunc);
782 if (result.isLeft()) {
783 // add inmemory components to the valid components(not dirty)
784 List<Component> foundComponents = result.left().value().getLeft();
785 if (componentsFromMemory != null) {
786 foundComponents.addAll(componentsFromMemory);
788 if (catalogInMemoryEnabled) {
789 updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
798 * - Map of <componentUniqueId, last update date>
799 * @param filterFieldsFunc
802 public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponents(Map<String, Long> components,
803 Function<List<Component>, List<Component>> filterFieldsFunc) {
806 log.debug(COMPONENT_CACHE_IS_DISABLED);
807 return Either.right(ActionStatus.NOT_ALLOWED);
810 Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
813 if (componentsFull.isRight()) {
814 return Either.right(componentsFull.right().value());
817 ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFull.left().value();
818 List<Component> foundResources = immutablePair.left;
819 Set<String> notFoundResources = immutablePair.right;
821 List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
823 ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<>(
824 filterdFoundResources, notFoundResources);
826 return Either.left(result);
831 * get the component and its modification time from cache
833 * @param componentUid
834 * @param filterFieldsFunc
837 public Either<ImmutablePair<Component, Long>, ActionStatus> getComponentAndTime(String componentUid,
838 Function<Component, Component> filterFieldsFunc) {
840 Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
841 componentUid, null, filterFieldsFunc);
843 if (componentFromCache.isRight()) {
844 return Either.right(componentFromCache.right().value());
847 ImmutablePair<Component, ComponentCacheData> immutablePair = componentFromCache.left().value();
849 ImmutablePair<Component, Long> result = new ImmutablePair<>(immutablePair.left,
850 immutablePair.right.getModificationTime().getTime());
852 return Either.left(result);
855 private Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> getComponentFromCache(
856 String componentUid, Long lastModificationTime, Function<Component, Component> filterFieldsFunc) {
858 return Either.right(ActionStatus.NOT_ALLOWED);
861 Either<ComponentCacheData, ActionStatus> componentRes = componentCassandraDao.getComponent(componentUid);
863 if (componentRes.isRight()) {
864 return Either.right(componentRes.right().value());
867 ComponentCacheData componentCacheData = componentRes.left().value();
869 if (lastModificationTime != null) {
870 long cacheCompModificationTime = componentCacheData.getModificationTime().getTime();
871 if (lastModificationTime != cacheCompModificationTime) {
873 "Component {} found in cache but its modification time {} does not match to the timestamp in cache {}.",
874 componentUid, lastModificationTime, cacheCompModificationTime);
875 return Either.right(ActionStatus.INVALID_CONTENT);
879 Either<? extends Component, Boolean> convertRes = convertComponentCacheToComponent(componentCacheData);
880 if (convertRes.isRight()) {
881 return Either.right(ActionStatus.CONVERT_COMPONENT_ERROR);
884 Component component = convertRes.left().value();
886 Component filteredComponent = component;
887 if (filterFieldsFunc != null) {
888 filteredComponent = filterFieldsFunc.apply(component);
891 ImmutablePair<Component, ComponentCacheData> result = new ImmutablePair<>(
892 filteredComponent, componentCacheData);
894 return Either.left(result);
897 public ActionStatus deleteComponentFromCache(String id) {
899 return ActionStatus.NOT_ALLOWED;
901 CassandraOperationStatus status = this.componentCassandraDao.deleteComponent(id);
902 if (CassandraOperationStatus.OK.equals(status)) {
903 return ActionStatus.OK;
905 log.debug("delete component failed with error {}", status);
906 return ActionStatus.GENERAL_ERROR;