2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2020 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=========================================================
20 package org.openecomp.sdc.be.tosca;
22 import static org.openecomp.sdc.be.utils.CommonBeUtils.compareAsdcComponentVersions;
24 import io.vavr.collection.HashMap;
25 import io.vavr.collection.Map;
26 import io.vavr.collection.Stream;
27 import java.util.function.BiConsumer;
28 import java.util.function.BinaryOperator;
29 import lombok.EqualsAndHashCode;
30 import org.apache.commons.lang3.tuple.ImmutableTriple;
31 import org.openecomp.sdc.be.model.Component;
34 * Provides caching abilities for components
36 public final class ComponentCache {
37 // TODO: Make this final whenever possible. The current code using the class
39 private final BinaryOperator<CacheEntry> merge;
40 // does not allow this.
41 private Map<String, CacheEntry> entries = HashMap.empty();
43 private ComponentCache(BinaryOperator<CacheEntry> merge) {
48 * Creates an overwritable cache based on a merging strategy
50 * @param merge The strategy used to merge two values which keys are the same
52 public static ComponentCache overwritable(BinaryOperator<CacheEntry> merge) {
53 return new ComponentCache(merge);
57 * Creates a cached entry
59 * @param id The id of the entry
60 * @param fileName the filename of the entry
61 * @param component the cached component
63 public static CacheEntry entry(String id, String fileName, Component component) {
64 return new CacheEntry(id, fileName, component);
68 * Decorate the cache with a listener called whenever a value is merged
70 * @param bc the consumer called when a value is merged
72 public ComponentCache onMerge(BiConsumer<CacheEntry, CacheEntry> bc) {
73 return new ComponentCache((oldValue, newValue) -> {
74 CacheEntry value = merge.apply(oldValue, newValue);
75 if (value.equals(newValue)) {
76 bc.accept(oldValue, newValue);
82 // For now we'll keep this as is, to prevent the refactoring to be too big
83 public Iterable<ImmutableTriple<String, String, Component>> iterable() {
84 return all().map(e -> new ImmutableTriple<>(e.id, e.fileName, e.component));
88 * Streams all the entries stored in the cache
90 public Stream<CacheEntry> all() {
91 return entries.values().toStream();
93 // TODO: Encapsulate the cache and expose functions to interact with it
96 * Tells if an entry has been cached for a specific key
98 * @param key The key used to index the entry
100 public boolean notCached(String key) {
101 return !entries.get(key).isDefined();
105 * Store an entry in the cache. Keep in mind that currently this mutates the cache and does not work in a referentially transparent way (This
106 * should be fixed whenever possible).
108 * @param id The id of the entry
109 * @param fileName the filename of the entry
110 * @param component the cached component
112 public ComponentCache put(String id, String fileName, Component component) {
113 String uuid = component.getInvariantUUID();
114 CacheEntry entry = new CacheEntry(id, fileName, component);
115 // TODO: Make the entries final whenever possible. The current code using the class does not allow this
116 entries = entries.put(uuid, entry, merge);
120 public interface MergeStrategy {
123 * A strategy designed to favour the latest component version when merging two cached entries
125 static BinaryOperator<CacheEntry> overwriteIfSameVersions() {
126 return (oldValue, newValue) -> compareAsdcComponentVersions(newValue.getComponentVersion(), oldValue.getComponentVersion()) ? newValue
132 * Entry stored by the cache
135 public static final class CacheEntry {
138 final String fileName;
139 final Component component;
141 CacheEntry(String id, String fileName, Component component) {
143 this.fileName = fileName;
144 this.component = component;
147 public String getComponentVersion() {
148 return component.getVersion();