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;
31 import org.apache.commons.lang3.tuple.ImmutableTriple;
32 import org.openecomp.sdc.be.model.Component;
35 * Provides caching abilities for components
37 public final class ComponentCache {
38 // TODO: Make this final whenever possible. The current code using the class
40 private final BinaryOperator<CacheEntry> merge;
41 // does not allow this.
42 private Map<String, CacheEntry> entries = HashMap.empty();
44 private ComponentCache(BinaryOperator<CacheEntry> merge) {
49 * Creates an overwritable cache based on a merging strategy
51 * @param merge The strategy used to merge two values which keys are the same
53 public static ComponentCache overwritable(BinaryOperator<CacheEntry> merge) {
54 return new ComponentCache(merge);
58 * Creates a cached entry
60 * @param id The id of the entry
61 * @param fileName the filename of the entry
62 * @param component the cached component
64 public static CacheEntry entry(String id, String fileName, Component component) {
65 return new CacheEntry(id, fileName, component);
69 * Decorate the cache with a listener called whenever a value is merged
71 * @param bc the consumer called when a value is merged
73 public ComponentCache onMerge(BiConsumer<CacheEntry, CacheEntry> bc) {
74 return new ComponentCache((oldValue, newValue) -> {
75 CacheEntry value = merge.apply(oldValue, newValue);
76 if (value.equals(newValue)) {
77 bc.accept(oldValue, newValue);
83 // For now we'll keep this as is, to prevent the refactoring to be too big
84 public Iterable<ImmutableTriple<String, String, Component>> iterable() {
85 return all().map(e -> new ImmutableTriple<>(e.id, e.fileName, e.component));
89 * Streams all the entries stored in the cache
91 public Stream<CacheEntry> all() {
92 return entries.values().toStream();
94 // TODO: Encapsulate the cache and expose functions to interact with it
97 * Tells if an entry has been cached for a specific key
99 * @param key The key used to index the entry
101 public boolean notCached(String key) {
102 return !entries.get(key).isDefined();
106 * 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
107 * should be fixed whenever possible).
109 * @param id The id of the entry
110 * @param fileName the filename of the entry
111 * @param component the cached component
113 public ComponentCache put(String id, String fileName, Component component) {
114 String uuid = component.getInvariantUUID();
115 CacheEntry entry = new CacheEntry(id, fileName, component);
116 // TODO: Make the entries final whenever possible. The current code using the class does not allow this
117 entries = entries.put(uuid, entry, merge);
121 public interface MergeStrategy {
124 * A strategy designed to favour the latest component version when merging two cached entries
126 static BinaryOperator<CacheEntry> overwriteIfSameVersions() {
127 return (oldValue, newValue) -> compareAsdcComponentVersions(newValue.getComponentVersion(), oldValue.getComponentVersion()) ? newValue
133 * Entry stored by the cache
137 public static final class CacheEntry {
140 final String fileName;
141 final Component component;
143 CacheEntry(String id, String fileName, Component component) {
145 this.fileName = fileName;
146 this.component = component;
149 public String getComponentVersion() {
150 return component.getVersion();