2 * ===============LICENSE_START=======================================================
4 * ===================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property & Tech Mahindra. All rights reserved.
6 * ===================================================================================
7 * This Acumos software file is distributed by AT&T and Tech Mahindra
8 * under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * This file 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.acumos.federation.gateway.service.impl;
23 import java.lang.invoke.MethodHandles;
24 import java.time.Instant;
25 import java.util.HashSet;
26 import java.util.List;
29 import java.util.function.Function;
30 import java.util.function.Predicate;
32 import org.acumos.cds.domain.MLPSolution;
33 import org.acumos.cds.domain.MLPTag;
34 import org.acumos.federation.gateway.cds.Solution;
35 import org.acumos.federation.gateway.service.ServiceException;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
40 * Some basic tooling for service implementation.
41 * Common functionality to be re-used across service implementations.
43 public abstract class ServiceImpl {
45 private static final Logger log = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
47 private ServiceImpl() {
52 * Returns a predicate equivalent to the logical AND of any non-null argument predicates.
53 * @param preds predicates to combine
54 * @return a predicate computing the logical AND of any non-null arguments or a predicate returning true, if there are none
56 private static Predicate<MLPSolution> and(Predicate<MLPSolution> ... preds) {
57 Predicate<MLPSolution> ret = null;
58 for (Predicate<MLPSolution> x: preds) {
61 } else if (x != null) {
73 * Returns a predicate determining matching against a multi-valued field.
74 * The returned predicate will be called with an MLPSolution. The
75 * Function specified by field will be invoked on it, to extract a Set
76 * of Strings, which will be tested against the value, in theSelector,
77 * corresponding to key.
78 * If theSelector does not contain key, this just returns null.
79 * Otherwise, if the value is a String, this returns a predicate
80 * computing whether the value is in the extracted Set of Strings.
81 * Otherwise, if the value is a List, this returns a predicate
82 * computing whether any of the values in the List is contained in
84 * @param theSelector a map of field names to expected values
85 * @param key the field name to be handled by this predicate
86 * @param field the Function to extract the field value from the Solution
87 * @param listok whether this field supports a list of values in the selector
88 * @return the predicate for testing the field value
89 * @throws ServiceException if the value of key, in theSelector is neither a String nor a List.
92 private static Predicate<MLPSolution> contains(Map<String, ?> theSelector, String key, Function<MLPSolution, Set<String>> field, boolean listok) throws ServiceException {
93 Object o = theSelector.get(key);
97 log.trace("using {} based selection {}", key, o);
98 if (o instanceof String) {
100 return(arg-> field.apply(arg).contains(s));
102 if (listok && o instanceof List) {
105 for (Object val: field.apply(arg)) {
106 if (l.contains(val)) {
113 log.debug("unknown {} criteria representation {}", key, o.getClass().getName());
114 throw new ServiceException("Invalid Selector");
119 * Returns a predicate determining matching against a field.
120 * The returned predicate will be called with an MLPSolution. The
121 * Function specified by field will be invoked on it, to extract its
122 * value, which will be tested against the value, in theSelector,
123 * corresponding to key.
124 * If theSelector does not contain key, this just returns null.
125 * Otherwise, if theSelector contains a String, this returns a predicate
126 * computing whether the value equals the extracted value.
127 * Otherwise, if the value is a List, this returns a predicate
128 * computing whether the extracted value is contained in the List.
129 * @param theSelector a map of field names to expected values
130 * @param key the field name to be handled by this predicate
131 * @param field the Function to extract the field value from the Solution
132 * @param listok whether this field supports a list of values in the selector
133 * @return the predicate for testing the field value
134 * @throws ServiceException if the value of key, in theSelector is neither a String nor a List.
137 private static Predicate<MLPSolution> has(Map<String, ?> theSelector, String key, Function<MLPSolution, String> field, boolean listok) throws ServiceException {
138 Object o = theSelector.get(key);
142 log.trace("using {} based selection {}", key, o);
143 if (o instanceof String) {
144 String s = (String)o;
145 return(arg -> s.equals(field.apply(arg)));
147 if (listok && o instanceof List) {
149 return(arg -> l.contains(field.apply(arg)));
151 log.debug("unknown {} criteria representation {}", key, o.getClass().getName());
152 throw new ServiceException("Invalid Selector");
157 * Returns a predicate for testing an MLPSolution against a selector.
158 * @param theSelector the criteria to be met in a matching solution
159 * @return a predicate for checking for matching solutions
160 * @throws ServiceException if theSelector is malformed
163 public static Predicate<MLPSolution> compileSelector(Map<String, ?> theSelector) throws ServiceException {
164 if (theSelector == null) {
167 log.trace("compileSelector {}", theSelector);
168 Boolean ao = (Boolean)theSelector.get(Solution.Fields.active);
169 boolean active = ao == null? true: ao.booleanValue();
170 Instant since = Instant.ofEpochSecond((Long)theSelector.get(Solution.Fields.modified));
172 arg -> arg.isActive() == active,
173 arg -> arg.getModified().compareTo(since) >= 0,
174 has(theSelector, Solution.Fields.solutionId, arg -> arg.getSolutionId(), false),
175 has(theSelector, Solution.Fields.modelTypeCode, arg -> arg.getModelTypeCode(), true),
176 has(theSelector, Solution.Fields.toolkitTypeCode, arg -> arg.getToolkitTypeCode(), true),
177 contains(theSelector, Solution.Fields.tags, arg -> {
178 Set<String> ret = new HashSet<String>();
179 for (MLPTag tag: arg.getTags()) {
180 ret.add(tag.getTag());
184 has(theSelector, Solution.Fields.name, arg ->arg.getName(), false)