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.jsontitan.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;
57 import java.util.concurrent.locks.Lock;
58 import java.util.concurrent.locks.ReentrantReadWriteLock;
59 import java.util.function.Function;
60 import java.util.stream.Collectors;
62 @org.springframework.stereotype.Component("component-cache")
63 public class ComponentCache {
65 private static final String COMPONENT_CACHE_IS_DISABLED = "Component Cache is disabled";
67 private static final Logger log = Logger.getLogger(ComponentCache.class);
70 ComponentCassandraDao componentCassandraDao;
73 ToscaOperationFacade toscaOperationFacade;
75 private Map<ComponentTypeEnum, Map<String, Component>> catalogInMemoryCache = new HashMap<>();
76 private final ReentrantReadWriteLock rwCatalogLock = new ReentrantReadWriteLock();
77 private final Lock rCatalogLock = rwCatalogLock.readLock();
78 private final Lock wCatalogLock = rwCatalogLock.writeLock();
80 boolean enabled = true;
81 int catalogInMemorySizePerResource = 300;
82 int catalogInMemorySizePerService = 200;
83 int catalogInMemorySizePerProduct = 100;
84 boolean catalogInMemoryEnabled = true;
85 Map<ComponentTypeEnum, Integer> limitMemoryCatalogSizePerType = new HashMap<>();
90 Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration();
91 if (configuration != null) {
92 ApplicationL2CacheConfig applicationL2Cache = configuration.getApplicationL2Cache();
93 if (applicationL2Cache != null) {
94 this.enabled = applicationL2Cache.isEnabled();
96 ApplicationL1CacheCatalogInfo catalog = applicationL2Cache.getCatalogL1Cache();
97 if (catalog != null) {
98 catalogInMemoryEnabled = catalog.getEnabled();
99 catalogInMemorySizePerResource = catalog.getResourcesSizeInCache();
100 catalogInMemorySizePerService = catalog.getServicesSizeInCache();
101 catalogInMemorySizePerProduct = catalog.getProductsSizeInCache();
106 ComponentTypeEnum[] typesForCache = { ComponentTypeEnum.RESOURCE, ComponentTypeEnum.SERVICE,
107 ComponentTypeEnum.PRODUCT };
108 for (ComponentTypeEnum typeEnum : typesForCache) {
109 Map<String, Component> map = new HashMap<>();
110 catalogInMemoryCache.put(typeEnum, map);
113 limitMemoryCatalogSizePerType.put(ComponentTypeEnum.RESOURCE, catalogInMemorySizePerResource);
114 limitMemoryCatalogSizePerType.put(ComponentTypeEnum.SERVICE, catalogInMemorySizePerService);
115 limitMemoryCatalogSizePerType.put(ComponentTypeEnum.PRODUCT, catalogInMemorySizePerProduct);
118 public boolean isEnabled() {
122 public void setEnabled(boolean enabled) {
123 this.enabled = enabled;
126 public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime,
127 Function<Component, Component> filterFieldsFunc) {
129 Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
130 componentUid, lastModificationTime, filterFieldsFunc);
132 if (componentFromCache.isRight()) {
133 return Either.right(componentFromCache.right().value());
136 return Either.left(componentFromCache.left().value().left);
140 public Either<List<ComponentCacheData>, ActionStatus> getAllComponentIdTimeAndType() {
142 return Either.right(ActionStatus.NOT_ALLOWED);
145 return componentCassandraDao
146 .getAllComponentIdTimeAndType();
151 * get components for catalog
154 * @param componentTypeEnum
158 public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
159 Set<String> components, ComponentTypeEnum componentTypeEnum) {
162 log.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
163 componentTypeEnum.name().toLowerCase());
164 return Either.right(ActionStatus.NOT_ALLOWED);
166 log.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
168 Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForCatalog;
170 Set<String> leftComponentsForSearch = new HashSet<>();
171 leftComponentsForSearch.addAll(components);
173 // get components from inmemory cache
174 List<Component> componentsFromMemory = null;
175 if (catalogInMemoryEnabled) {
176 componentsFromMemory = getDataFromInMemoryCache(components, componentTypeEnum);
177 log.debug("The number of components of type {} fetched from memory is {}",
178 componentTypeEnum.name().toLowerCase(),
179 componentsFromMemory == null ? 0 : componentsFromMemory.size());
180 if (componentsFromMemory != null) {
181 componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
184 log.debug("Catalog InMemory cache is disabled");
187 log.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
188 leftComponentsForSearch.size());
190 // get components from cassandra cache and filter each component
191 Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result = getComponents(
192 leftComponentsForSearch, filterFieldsFunc);
194 if (result.isLeft()) {
195 // add inmemory components to the valid components(not dirty)
196 List<Component> foundComponents = result.left().value().getLeft();
197 if (componentsFromMemory != null) {
198 foundComponents.addAll(componentsFromMemory);
200 if (catalogInMemoryEnabled) {
201 updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
209 * @param foundComponents
210 * @param componentTypeEnum
212 private void updateCatalogInMemoryCacheWithCertified(List<Component> foundComponents,
213 ComponentTypeEnum componentTypeEnum) {
218 long start = System.currentTimeMillis();
219 Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
220 int mapSizeBefore = map.size();
222 Map<String, Component> collect = foundComponents.stream()
223 .filter(p -> p.getLifecycleState() == LifecycleStateEnum.CERTIFIED)
224 .limit(limitMemoryCatalogSizePerType.get(componentTypeEnum))
225 .collect(Collectors.toMap(Component::getUniqueId, p -> p));
228 "Size of in memory cache for catalog {}(certified only): Before {}, After {}. Replacement Time is {} ms.",
229 componentTypeEnum.name().toLowerCase(), mapSizeBefore, map.size(),
230 System.currentTimeMillis() - start);
232 wCatalogLock.unlock();
237 private List<Component> getDataFromInMemoryCache(Set<String> components, ComponentTypeEnum componentTypeEnum) {
238 List<Component> foundComponents = new ArrayList<>();
244 Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum);
245 for (String compUid : components) {
246 Component component = map.get(compUid);
247 if (component != null) {
248 foundComponents.add(component);
253 rCatalogLock.unlock();
256 return foundComponents;
261 * get full components from cassandra. On each component apply filter
262 * function in order to remove unused members
265 * @param filterFieldsFunc
266 * @return <found components, found dirty components, not found components
269 public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponents(
270 Set<String> components, Function<List<Component>, List<Component>> filterFieldsFunc) {
273 log.debug(COMPONENT_CACHE_IS_DISABLED);
274 return Either.right(ActionStatus.NOT_ALLOWED);
277 Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
280 if (componentsFull.isRight()) {
281 return Either.right(componentsFull.right().value());
284 ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = componentsFull.left().value();
285 List<Component> foundResources = immutableTriple.left;
286 List<Component> foundDirtyResources = immutableTriple.middle;
287 Set<String> notFoundResources = immutableTriple.right;
289 List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
290 List<Component> filterdFoundDirtyResources = filterFieldsFunc.apply(foundDirtyResources);
292 ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<>(
293 filterdFoundResources, filterdFoundDirtyResources, notFoundResources);
295 return Either.left(result);
299 public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForLeftPanel(
300 ComponentTypeEnum componentTypeEnum, String internalComponentType, Set<String> filteredResources) {
302 log.debug("In getComponentsForLeftPanel componentTypeEnum = {}, internalComponentType = {}",
303 componentTypeEnum, internalComponentType);
305 Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForLeftPanel;
307 return getComponents(filteredResources, filterFieldsFunc);
311 private List<Component> filterForLeftPanel(List<Component> components) {
313 List<Component> result = new ArrayList<>();
314 if (components != null) {
315 components.forEach(p -> result.add(filterFieldsForLeftPanel(p)));
321 private List<Component> filterForCatalog(List<Component> components) {
323 List<Component> result = new ArrayList<>();
324 if (components != null) {
325 components.forEach(p -> result.add(filterFieldsForCatalog(p)));
331 private Component filterFieldsForLeftPanel(Component component) {
333 Component result = null;
334 ComponentTypeEnum componentTypeEnum = component.getComponentType();
335 switch (componentTypeEnum) {
337 result = new Resource();
338 copyFieldsForLeftPanel(component, result);
341 result = new Service();
342 copyFieldsForLeftPanel(component, result);
351 private Component filterFieldsForCatalog(Component component) {
353 Component result = null;
354 ComponentTypeEnum componentTypeEnum = component.getComponentType();
355 switch (componentTypeEnum) {
357 result = new Resource();
358 copyFieldsForCatalog(component, result);
361 result = new Service();
362 copyFieldsForCatalog(component, result);
365 result = new Product();
366 copyFieldsForCatalog(component, result);
376 * Copy relevant fields to the filtered component for left panel
379 * @param filteredComponent
381 private void copyFieldsForLeftPanel(Component component, Component filteredComponent) {
383 ComponentTypeEnum componentTypeEnum = component.getComponentType();
384 filteredComponent.setCategories(component.getCategories());
385 filteredComponent.setComponentType(component.getComponentType());
386 if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())
387 && ResourceTypeEnum.VL.equals(((ResourceMetadataDataDefinition) component
388 .getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType())) {
389 filteredComponent.setCapabilities(component.getCapabilities());
390 filteredComponent.setRequirements(component.getRequirements());
392 filteredComponent.setVersion(component.getVersion());
393 filteredComponent.setDescription(component.getDescription());
394 filteredComponent.setUniqueId(component.getUniqueId());
395 filteredComponent.setIcon(component.getIcon());
396 filteredComponent.setTags(component.getTags());
397 filteredComponent.setLifecycleState(component.getLifecycleState());
398 filteredComponent.setInvariantUUID(component.getInvariantUUID());
399 filteredComponent.setUUID(component.getUUID());
400 filteredComponent.setSystemName(component.getSystemName());
401 filteredComponent.setName(component.getName());
403 if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
404 Resource resource = (Resource) component;
405 Resource filteredResource = (Resource) filteredComponent;
406 filteredResource.setToscaResourceName(resource.getToscaResourceName());
407 filteredResource.setResourceType(resource.getResourceType());
411 private void copyFieldsForCatalog(Component component, Component filteredComponent) {
413 ComponentTypeEnum componentTypeEnum = component.getComponentType();
414 filteredComponent.setCategories(component.getCategories());
415 filteredComponent.setComponentType(component.getComponentType());
416 filteredComponent.setVersion(component.getVersion());
417 filteredComponent.setDescription(component.getDescription());
418 filteredComponent.setUniqueId(component.getUniqueId());
419 filteredComponent.setIcon(component.getIcon());
420 filteredComponent.setTags(component.getTags());
421 filteredComponent.setLifecycleState(component.getLifecycleState());
422 filteredComponent.setSystemName(component.getSystemName());
423 filteredComponent.setName(component.getName());
424 filteredComponent.setLastUpdateDate(component.getLastUpdateDate());
426 if (componentTypeEnum == ComponentTypeEnum.RESOURCE) {
427 Resource resource = (Resource) component;
428 Resource filteredResource = (Resource) filteredComponent;
429 filteredResource.setToscaResourceName(resource.getToscaResourceName());
430 filteredResource.setResourceType(resource.getResourceType());
431 } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) {
432 Service service = (Service) component;
433 Service filteredService = (Service) filteredComponent;
434 filteredService.setDistributionStatus(service.getDistributionStatus());
439 * get components from cache of a given list ou unique ids.
441 * for each component data from cassandra, unzip the data if needed and
442 * deserialize the unzipped data to java object(Component).
444 * @param filteredResources
445 * @return ImmutableTripple or ActionStatus. | |-- components |-- dirty
446 * components - components with dirty flag = true. |-- set of non
450 private Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsFull(
451 Set<String> filteredResources) {
454 log.debug(COMPONENT_CACHE_IS_DISABLED);
455 return Either.right(ActionStatus.NOT_ALLOWED);
458 List<Component> foundResources = new LinkedList<>();
459 List<Component> foundDirtyResources = new LinkedList<>();
460 Set<String> notFoundResources = new HashSet<>();
461 ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<>(
462 foundResources, foundDirtyResources, notFoundResources);
464 long cassandraFetchStart = System.currentTimeMillis();
465 List<String> uidsList = new ArrayList<>();
466 uidsList.addAll(filteredResources);
467 Either<List<ComponentCacheData>, ActionStatus> componentsFromCache = componentCassandraDao
468 .getComponents(uidsList);
470 long cassandraFetchEnd = System.currentTimeMillis();
471 log.debug("Fetch time from cassandara of all components took {} ms",
472 (cassandraFetchEnd - cassandraFetchStart));
473 if (componentsFromCache.isRight()) {
474 BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
475 "Failed to fetch components from cache", ErrorSeverity.ERROR);
476 return Either.right(componentsFromCache.right().value());
479 List<ComponentCacheData> list = componentsFromCache.left().value();
480 log.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
481 if (list != null && !list.isEmpty()) {
483 List<ComponentCacheData> filteredData = list.stream().filter(p -> filteredResources.contains(p.getId()))
484 .collect(Collectors.toList());
485 log.debug("Number of components filterd is {}", filteredData == null ? 0 : filteredData.size());
487 if (filteredData != null) {
488 long desStart = System.currentTimeMillis();
490 for (ComponentCacheData componentCacheData : filteredData) {
492 log.debug("Process uid {} from cache", componentCacheData.getId());
494 String compUid = componentCacheData.getId();
496 Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
499 if (deserializeExt.isLeft()) {
500 Component component = deserializeExt.left().value();
501 if (!componentCacheData.getIsDirty()) {
502 foundResources.add(component);
504 foundDirtyResources.add(component);
507 notFoundResources.add(compUid);
511 long desEnd = System.currentTimeMillis();
512 log.debug("Deserialization and unzip of {} components took {} ms", filteredData.size(),
513 (desEnd - desStart));
516 List<String> foundResourcesUid = foundResources.stream().map(Component::getUniqueId).collect(Collectors.toList());
517 List<String> foundDirtyResourcesUid = foundDirtyResources.stream().map(Component::getUniqueId)
518 .collect(Collectors.toList());
519 log.debug("Number of processed components from cache is {}",
520 (foundResourcesUid.size() + foundDirtyResourcesUid.size()));
521 Set<String> notCachedResources = filteredResources.stream()
522 .filter(p -> !foundResourcesUid.contains(p) && !foundDirtyResourcesUid.contains(p))
523 .collect(Collectors.toSet());
524 notFoundResources.addAll(notCachedResources);
526 if (log.isDebugEnabled()) {
527 log.debug("Number of components fetched is {}", foundResources.size());
528 log.debug("Number of components fetched dirty is {}", foundDirtyResources.size());
529 log.debug("Number of components non cached is {}", notCachedResources.size());
532 return Either.left(result);
535 private Either<? extends Component, Boolean> convertComponentCacheToComponent(
536 ComponentCacheData componentCacheData) {
538 String compUid = componentCacheData.getId();
540 byte[] dataAsArray = componentCacheData.getDataAsArray();
542 if (componentCacheData.getIsZipped()) {
543 long startUnzip = System.nanoTime();
544 dataAsArray = ZipUtil.unzip(dataAsArray);
545 long endUnzip = System.nanoTime();
546 log.trace("Unzip component {} took {} microsecond", compUid, (endUnzip - startUnzip) / 1000);
549 long startDes = System.nanoTime();
551 Either<? extends Component, Boolean> deserializeExt = deserializeComponent(componentCacheData, dataAsArray);
553 long endDes = System.nanoTime();
554 log.trace("Deserialize component {} took {} microsecond", compUid, (endDes - startDes) / 1000);
555 return deserializeExt;
558 private Either<? extends Component, Boolean> deserializeComponent(ComponentCacheData componentCacheData,
559 byte[] dataAsArray) {
560 String type = componentCacheData.getType();
561 NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(type);
563 Either<? extends Component, Boolean> deserializeExt = Either.right(false);
566 deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Resource.class, componentCacheData.getId());
569 deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Service.class, componentCacheData.getId());
572 deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Product.class, componentCacheData.getId());
577 return deserializeExt;
580 public Either<Component, ActionStatus> getComponent(String componentUid) {
582 return getComponent(componentUid, null, Function.identity());
586 private boolean saveComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum,
587 Component component) {
589 log.trace("Going to save component {} of type {} in cache", componentUid, nodeTypeEnum.name().toLowerCase());
591 boolean result = false;
593 Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(component);
594 if (serializeExt.isLeft()) {
595 byte[] serializedData = serializeExt.left().value();
598 zipBytes = ZipUtil.zipBytes(serializedData);
599 ComponentCacheData componentCacheData = new ComponentCacheData();
600 componentCacheData.setDataAsArray(zipBytes);
601 componentCacheData.setIsZipped(true);
602 componentCacheData.setId(componentUid);
603 componentCacheData.setModificationTime(new Date(lastModificationTime));
604 componentCacheData.setType(component.getComponentType().name().toLowerCase());
606 CassandraOperationStatus status = componentCassandraDao.saveComponent(componentCacheData);
608 if (status == CassandraOperationStatus.OK) {
612 } catch (IOException e) {
613 log.debug("Failed to prepare component {} of type {} for cache", componentUid,
614 nodeTypeEnum.name().toLowerCase());
615 if (log.isTraceEnabled()) {
616 log.trace("Failed to prepare component {} of type {} for cache",componentUid,nodeTypeEnum.name().toLowerCase());
620 log.debug("Failed to serialize component {} of type {} for cache", componentUid,
621 nodeTypeEnum.name().toLowerCase());
626 public boolean setComponent(Component component, NodeTypeEnum nodeTypeEnum) {
628 boolean result = false;
631 log.debug(COMPONENT_CACHE_IS_DISABLED);
635 String componentUid = component.getUniqueId();
636 Long lastUpdateDate = component.getLastUpdateDate();
638 result = saveComponent(componentUid, lastUpdateDate, nodeTypeEnum, component);
645 * get components from cache of a given list ou unique ids.
647 * for each component data from cassandra, unzip the data if needed and
648 * deserialize the unzipped data to java object(Component).
650 * @param filteredResources
651 * @return ImmutableTripple or ActionStatus. | |-- components |-- set of non
655 private Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsFull(
656 Map<String, Long> filteredResources) {
659 log.debug(COMPONENT_CACHE_IS_DISABLED);
660 return Either.right(ActionStatus.NOT_ALLOWED);
663 List<Component> foundResources = new LinkedList<>();
664 Set<String> notFoundResources = new HashSet<>();
665 ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<>(
666 foundResources, notFoundResources);
668 long cassandraFetchStart = System.currentTimeMillis();
670 Either<ImmutablePair<List<ComponentCacheData>, Set<String>>, ActionStatus> componentsFromCache = componentCassandraDao
671 .getComponents(filteredResources);
673 long cassandraFetchEnd = System.currentTimeMillis();
674 log.debug("Fetch time from cassandara of all components took {} ms",
675 (cassandraFetchEnd - cassandraFetchStart));
676 if (componentsFromCache.isRight()) {
677 BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache",
678 "Failed to fetch components from cache", ErrorSeverity.ERROR);
679 return Either.right(componentsFromCache.right().value());
682 ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = componentsFromCache.left().value();
683 List<ComponentCacheData> list = immutablePair.getLeft();
684 log.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size()));
685 if (list != null && !list.isEmpty()) {
687 log.debug("Number of components filterd is {}", list == null ? 0 : list.size());
690 long desStart = System.currentTimeMillis();
692 for (ComponentCacheData componentCacheData : list) {
694 log.debug("Process uid {} from cache", componentCacheData.getId());
696 String compUid = componentCacheData.getId();
698 Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent(
701 if (deserializeExt.isLeft()) {
702 Component component = deserializeExt.left().value();
703 foundResources.add(component);
705 notFoundResources.add(compUid);
709 long desEnd = System.currentTimeMillis();
710 log.debug("Deserialization and unzip of {} components took {} ms", list.size(), (desEnd - desStart));
713 log.debug("Number of processed components from cache is {}", foundResources.size());
715 Set<String> notFoundInCache = immutablePair.getRight();
716 notFoundResources.addAll(notFoundInCache);
718 if (log.isDebugEnabled()) {
719 log.debug("Number of components fetched is {}", foundResources.size());
720 log.debug("Number of components non cached is {}", notFoundResources.size());
723 return Either.left(result);
727 * get components for catalog
730 * @param componentTypeEnum
733 public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog(
734 Map<String, Long> components, ComponentTypeEnum componentTypeEnum) {
737 log.debug("In getComponentsForCatalog for type {}. Cache is disabled.",
738 componentTypeEnum.name().toLowerCase());
739 return Either.right(ActionStatus.NOT_ALLOWED);
741 log.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase());
743 Function<List<Component>, List<Component>> filterFieldsFunc = this::filterForCatalog;
745 Map<String, Long> leftComponentsForSearch = new HashMap<>();
746 leftComponentsForSearch.putAll(components);
748 // get components from inmemory cache
749 List<Component> componentsFromMemory = null;
750 if (catalogInMemoryEnabled) {
751 componentsFromMemory = getDataFromInMemoryCache(components.keySet(), componentTypeEnum);
752 log.debug("The number of components of type {} fetched from memory is {}",
753 componentTypeEnum.name().toLowerCase(),
754 componentsFromMemory == null ? 0 : componentsFromMemory.size());
755 if (componentsFromMemory != null) {
756 List<String> ignoredComponents = new ArrayList<>();
757 for (Component componentFromMem : componentsFromMemory) {
758 if (componentFromMem.getLastUpdateDate().longValue() != components
759 .get(componentFromMem.getUniqueId()).longValue()) {
760 // Ignore the component from memory
761 ignoredComponents.add(componentFromMem.getUniqueId());
765 log.debug("Number of components from type {} ignored from memory cache is {}",
766 componentTypeEnum.name().toLowerCase(), ignoredComponents.size());
767 // remove from memory result the components which are not valid
768 componentsFromMemory = componentsFromMemory.stream()
769 .filter(p -> !ignoredComponents.contains(p.getUniqueId())).collect(Collectors.toList());
770 // Remove from leftComponentsForSearch the valid components from
772 componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId()));
776 log.debug("Catalog InMemory cache is disabled");
779 log.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(),
780 leftComponentsForSearch.size());
782 // get components from cassandra cache and filter each component
783 Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result = getComponents(
784 leftComponentsForSearch, filterFieldsFunc);
786 if (result.isLeft()) {
787 // add inmemory components to the valid components(not dirty)
788 List<Component> foundComponents = result.left().value().getLeft();
789 if (componentsFromMemory != null) {
790 foundComponents.addAll(componentsFromMemory);
792 if (catalogInMemoryEnabled) {
793 updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum);
802 * - Map of <componentUniqueId, last update date>
803 * @param filterFieldsFunc
806 public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponents(Map<String, Long> components,
807 Function<List<Component>, List<Component>> filterFieldsFunc) {
810 log.debug(COMPONENT_CACHE_IS_DISABLED);
811 return Either.right(ActionStatus.NOT_ALLOWED);
814 Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull(
817 if (componentsFull.isRight()) {
818 return Either.right(componentsFull.right().value());
821 ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFull.left().value();
822 List<Component> foundResources = immutablePair.left;
823 Set<String> notFoundResources = immutablePair.right;
825 List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources);
827 ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<>(
828 filterdFoundResources, notFoundResources);
830 return Either.left(result);
835 * get the component and its modification time from cache
837 * @param componentUid
838 * @param filterFieldsFunc
841 public Either<ImmutablePair<Component, Long>, ActionStatus> getComponentAndTime(String componentUid,
842 Function<Component, Component> filterFieldsFunc) {
844 Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache(
845 componentUid, null, filterFieldsFunc);
847 if (componentFromCache.isRight()) {
848 return Either.right(componentFromCache.right().value());
851 ImmutablePair<Component, ComponentCacheData> immutablePair = componentFromCache.left().value();
853 ImmutablePair<Component, Long> result = new ImmutablePair<>(immutablePair.left,
854 immutablePair.right.getModificationTime().getTime());
856 return Either.left(result);
859 private Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> getComponentFromCache(
860 String componentUid, Long lastModificationTime, Function<Component, Component> filterFieldsFunc) {
862 return Either.right(ActionStatus.NOT_ALLOWED);
865 Either<ComponentCacheData, ActionStatus> componentRes = componentCassandraDao.getComponent(componentUid);
867 if (componentRes.isRight()) {
868 return Either.right(componentRes.right().value());
871 ComponentCacheData componentCacheData = componentRes.left().value();
873 if (lastModificationTime != null) {
874 long cacheCompModificationTime = componentCacheData.getModificationTime().getTime();
875 if (lastModificationTime != cacheCompModificationTime) {
877 "Component {} found in cache but its modification time {} does not match to the timestamp in cache {}.",
878 componentUid, lastModificationTime, cacheCompModificationTime);
879 return Either.right(ActionStatus.INVALID_CONTENT);
883 Either<? extends Component, Boolean> convertRes = convertComponentCacheToComponent(componentCacheData);
884 if (convertRes.isRight()) {
885 return Either.right(ActionStatus.CONVERT_COMPONENT_ERROR);
888 Component component = convertRes.left().value();
890 Component filteredComponent = component;
891 if (filterFieldsFunc != null) {
892 filteredComponent = filterFieldsFunc.apply(component);
895 ImmutablePair<Component, ComponentCacheData> result = new ImmutablePair<>(
896 filteredComponent, componentCacheData);
898 return Either.left(result);
901 public ActionStatus deleteComponentFromCache(String id) {
903 return ActionStatus.NOT_ALLOWED;
905 CassandraOperationStatus status = this.componentCassandraDao.deleteComponent(id);
906 if (CassandraOperationStatus.OK.equals(status)) {
907 return ActionStatus.OK;
909 log.debug("delete component failed with error {}", status);
910 return ActionStatus.GENERAL_ERROR;