Skip to content

Commit 4c6c497

Browse files
committed
Merge pull request '#25533 parameters' (#64) from feature/25533/parameters into develop
2 parents 373929d + 9f11d1c commit 4c6c497

69 files changed

Lines changed: 3113 additions & 920 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/main/java/eu/openanalytics/containerproxy/api/ProxyController.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,17 @@
2727

2828
import javax.inject.Inject;
2929

30+
import eu.openanalytics.containerproxy.service.InvalidParametersException;
3031
import org.springframework.http.HttpStatus;
3132
import org.springframework.http.MediaType;
3233
import org.springframework.http.ResponseEntity;
3334
import org.springframework.web.bind.annotation.PathVariable;
34-
import org.springframework.web.bind.annotation.RequestBody;
3535
import org.springframework.web.bind.annotation.RequestMapping;
3636
import org.springframework.web.bind.annotation.RequestMethod;
3737
import org.springframework.web.bind.annotation.RequestParam;
3838
import org.springframework.web.bind.annotation.RestController;
3939

4040
import eu.openanalytics.containerproxy.model.runtime.Proxy;
41-
import eu.openanalytics.containerproxy.model.runtime.RuntimeSetting;
4241
import eu.openanalytics.containerproxy.model.spec.ProxySpec;
4342
import eu.openanalytics.containerproxy.service.ProxyService;
4443

@@ -79,21 +78,20 @@ public ResponseEntity<Proxy> getProxy(@PathVariable String proxyId) {
7978
}
8079

8180
@RequestMapping(value="/api/proxy/{proxySpecId}", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
82-
public ResponseEntity<Proxy> startProxy(@PathVariable String proxySpecId, @RequestBody(required=false) Set<RuntimeSetting> runtimeSettings) {
81+
public ResponseEntity<Proxy> startProxy(@PathVariable String proxySpecId) throws InvalidParametersException {
8382
ProxySpec baseSpec = proxyService.findProxySpec(s -> s.getId().equals(proxySpecId), false);
8483
if (baseSpec == null) return new ResponseEntity<>(HttpStatus.NOT_FOUND);
8584

86-
ProxySpec spec = proxyService.resolveProxySpec(baseSpec, null, runtimeSettings);
87-
Proxy proxy = proxyService.startProxy(spec, false);
88-
return new ResponseEntity<>(proxy, HttpStatus.CREATED);
89-
}
90-
91-
@RequestMapping(value="/api/proxy", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
92-
public ResponseEntity<Proxy> startProxy(@RequestBody ProxySpec proxySpec) {
93-
ProxySpec spec = proxyService.resolveProxySpec(null, proxySpec, null);
94-
Proxy proxy = proxyService.startProxy(spec, false);
85+
Proxy proxy = proxyService.startProxy(baseSpec, false);
9586
return new ResponseEntity<>(proxy, HttpStatus.CREATED);
9687
}
88+
89+
// TODO disable this by default
90+
// @RequestMapping(value="/api/proxy", method=RequestMethod.POST, produces=MediaType.APPLICATION_JSON_VALUE)
91+
// public ResponseEntity<Proxy> startProxy(@RequestBody ProxySpec proxySpec) {
92+
// Proxy proxy = proxyService.startProxy(proxySpec, false);
93+
// return new ResponseEntity<>(proxy, HttpStatus.CREATED);
94+
// }
9795

9896
@RequestMapping(value="/api/proxy/{proxyId}", method=RequestMethod.DELETE, produces=MediaType.APPLICATION_JSON_VALUE)
9997
public ResponseEntity<Map<String, String>> stopProxy(@PathVariable String proxyId) {

src/main/java/eu/openanalytics/containerproxy/backend/AbstractContainerBackend.java

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@
2020
*/
2121
package eu.openanalytics.containerproxy.backend;
2222

23-
import com.fasterxml.jackson.databind.MapperFeature;
24-
import com.fasterxml.jackson.databind.ObjectMapper;
25-
import com.fasterxml.jackson.databind.SerializationFeature;
26-
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
27-
import com.google.common.base.Charsets;
28-
import eu.openanalytics.containerproxy.ContainerProxyApplication;
2923
import eu.openanalytics.containerproxy.ContainerProxyException;
3024
import eu.openanalytics.containerproxy.auth.IAuthenticationBackend;
3125
import eu.openanalytics.containerproxy.backend.strategy.IProxyTargetMappingStrategy;
@@ -55,16 +49,14 @@
5549
import org.springframework.core.env.Environment;
5650

5751
import javax.inject.Inject;
58-
import java.io.File;
5952
import java.io.FileInputStream;
6053
import java.io.IOException;
6154
import java.io.OutputStream;
62-
import java.math.BigInteger;
6355
import java.nio.file.Files;
6456
import java.nio.file.Paths;
65-
import java.security.MessageDigest;
66-
import java.security.NoSuchAlgorithmException;
67-
import java.util.*;
57+
import java.util.HashMap;
58+
import java.util.Map;
59+
import java.util.Properties;
6860
import java.util.function.BiConsumer;
6961
import java.util.regex.Matcher;
7062
import java.util.regex.Pattern;
@@ -77,6 +69,7 @@ public abstract class AbstractContainerBackend implements IContainerBackend {
7769
protected static final String PROPERTY_CONTAINER_PROTOCOL = "container-protocol";
7870
protected static final String PROPERTY_PRIVILEGED = "privileged";
7971

72+
private static final String PARAM_CONTAINER_IMAGE = "CONTAINER_IMAGE";
8073
protected static final String DEFAULT_TARGET_PROTOCOL = "http";
8174
protected final Logger log = LogManager.getLogger(getClass());
8275

@@ -149,6 +142,11 @@ public SuccessOrFailure<Proxy> startProxy(Proxy proxy) throws ContainerProxyExce
149142

150143
}
151144

145+
@Override
146+
public String getContainerImage(Container container) {
147+
return (String) container.getParameters().get(PARAM_CONTAINER_IMAGE);
148+
}
149+
152150
protected void doStartProxy(Proxy proxy) throws Exception {
153151
for (ContainerSpec spec: proxy.getSpec().getContainerSpecs()) {
154152
if (authBackend != null) authBackend.customizeContainer(spec);
@@ -161,6 +159,7 @@ protected void doStartProxy(Proxy proxy) throws Exception {
161159

162160
Container c = startContainer(eSpec, proxy);
163161
c.setSpec(spec);
162+
c.getParameters().put(PARAM_CONTAINER_IMAGE, eSpec.getImage());
164163

165164
proxy.getContainers().add(c);
166165
}

src/main/java/eu/openanalytics/containerproxy/backend/IContainerBackend.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public interface IContainerBackend {
5252
* @throws ContainerProxyException If the startup fails for any reason.
5353
*/
5454
public SuccessOrFailure<Proxy> startProxy(Proxy proxy) throws ContainerProxyException;
55-
55+
5656
/**
5757
* Stop the given proxy. Any resources used by the proxy should be released.
5858
*
@@ -88,4 +88,6 @@ public interface IContainerBackend {
8888
* @param portBindings The portbindings of this container, as generated by the scanExistingContainers method.
8989
*/
9090
public void setupPortMappingExistingProxy(Proxy proxy, Container container, Map<Integer, Integer> portBindings) throws Exception;
91+
92+
public String getContainerImage(Container container);
9193
}

src/main/java/eu/openanalytics/containerproxy/backend/kubernetes/KubernetesBackend.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import io.fabric8.kubernetes.client.internal.readiness.Readiness;
7777
import io.fabric8.kubernetes.client.utils.Serialization;
7878
import org.apache.commons.io.IOUtils;
79+
import org.apache.commons.lang.StringUtils;
7980

8081
import javax.inject.Inject;
8182
import javax.json.JsonPatch;
@@ -367,6 +368,10 @@ private JsonPatch readPatchFromSpec(ContainerSpec containerSpec, Proxy proxy) th
367368
userService.getCurrentAuth().getCredentials());
368369
String expressionAwarePatch = expressionResolver.evaluateToString(patchAsString, context);
369370

371+
if (StringUtils.isBlank(expressionAwarePatch)) {
372+
return null;
373+
}
374+
370375
ObjectMapper yamlReader = new ObjectMapper(new YAMLFactory());
371376
yamlReader.registerModule(new JSR353Module());
372377
return yamlReader.readValue(expressionAwarePatch, JsonPatch.class);
@@ -503,6 +508,7 @@ protected void doStopProxy(Proxy proxy) throws Exception {
503508
// specify gracePeriod 0, this was the default in previous version of the fabric8 k8s client
504509
kubeClient.resource(pod).withGracePeriod(0).delete();
505510
}
511+
506512
Service service = Service.class.cast(container.getParameters().get(PARAM_SERVICE));
507513
if (service != null) {
508514
kubeClient.resource(service).withGracePeriod(0).delete();
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2021 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.model.runtime;
22+
23+
import java.util.HashSet;
24+
import java.util.List;
25+
import java.util.Map;
26+
27+
public class AllowedParametersForUser {
28+
29+
/**
30+
* Mapping of the id of the parameter to the (human friendly) names.
31+
*/
32+
private final Map<String, List<String>> values;
33+
34+
/**
35+
* List of all allowed combinations of the parameters for this specific user.
36+
*/
37+
private final HashSet<List<Integer>> allowedCombinations;
38+
39+
private final List<Integer> defaultValue;
40+
41+
public AllowedParametersForUser(Map<String, List<String>> values, HashSet<List<Integer>> allowedCombinations, List<Integer> defaultValue) {
42+
this.values = values;
43+
this.allowedCombinations = allowedCombinations;
44+
this.defaultValue = defaultValue;
45+
}
46+
47+
public HashSet<List<Integer>> getAllowedCombinations() {
48+
return allowedCombinations;
49+
}
50+
51+
public Map<String, List<String>> getValues() {
52+
return values;
53+
}
54+
55+
public List<Integer> getDefaultValue() {
56+
return defaultValue;
57+
}
58+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2021 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.model.runtime;
22+
23+
import com.fasterxml.jackson.core.JsonProcessingException;
24+
import com.fasterxml.jackson.databind.ObjectMapper;
25+
26+
import java.util.List;
27+
import java.util.Map;
28+
29+
public class ParameterNames {
30+
private final List<ParameterName> values;
31+
32+
public ParameterNames(List<ParameterName> values) {
33+
this.values = values;
34+
}
35+
36+
@Override
37+
public String toString() {
38+
ObjectMapper objectMapper = new ObjectMapper();
39+
try {
40+
return objectMapper.writeValueAsString(values);
41+
} catch (JsonProcessingException e) {
42+
throw new RuntimeException(e);
43+
}
44+
}
45+
46+
public List<ParameterName> getParametersNames() {
47+
return values;
48+
}
49+
50+
public static class ParameterName {
51+
52+
private final String displayName;
53+
private final String description;
54+
private final String value;
55+
56+
public ParameterName(String displayName, String description, String value) {
57+
this.displayName = displayName;
58+
this.description = description;
59+
this.value = value;
60+
}
61+
62+
public String getDisplayName() {
63+
return displayName;
64+
}
65+
66+
public String getDescription() {
67+
return description;
68+
}
69+
70+
public String getValue() {
71+
return value;
72+
}
73+
74+
}
75+
76+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* ContainerProxy
3+
*
4+
* Copyright (C) 2016-2021 Open Analytics
5+
*
6+
* ===========================================================================
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the Apache License as published by
10+
* The Apache Software Foundation, either version 2 of the License, or
11+
* (at your option) any later version.
12+
*
13+
* This program is distributed in the hope that it will be useful,
14+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
* Apache License for more details.
17+
*
18+
* You should have received a copy of the Apache License
19+
* along with this program. If not, see <http://www.apache.org/licenses/>
20+
*/
21+
package eu.openanalytics.containerproxy.model.runtime;
22+
23+
24+
import com.fasterxml.jackson.annotation.JsonCreator;
25+
import com.fasterxml.jackson.core.JsonProcessingException;
26+
import com.fasterxml.jackson.databind.ObjectMapper;
27+
28+
import java.util.Map;
29+
30+
public class ParameterValues {
31+
32+
private final Map<String, String> backendValues;
33+
private final String valueSetName;
34+
35+
@JsonCreator
36+
public ParameterValues(Map<String, String> backendValues, String valueSetName) {
37+
this.backendValues = backendValues;
38+
this.valueSetName = valueSetName;
39+
}
40+
41+
public int size() {
42+
return backendValues.size();
43+
}
44+
45+
public String getValue(String parameterId) {
46+
if (!backendValues.containsKey(parameterId)) {
47+
throw new IllegalArgumentException(String.format("The parameter with id \"%s\" does not exist!", parameterId));
48+
}
49+
return backendValues.get(parameterId);
50+
}
51+
52+
@Override
53+
public String toString() {
54+
ObjectMapper objectMapper = new ObjectMapper();
55+
try {
56+
return objectMapper.writeValueAsString(backendValues);
57+
} catch (JsonProcessingException e) {
58+
throw new RuntimeException(e);
59+
}
60+
}
61+
62+
public String getValueSetName() {
63+
return valueSetName;
64+
}
65+
}

src/main/java/eu/openanalytics/containerproxy/model/runtime/Proxy.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,9 @@ public Map<String, String> getRuntimeValuesJson() {
129129
// only output key<->value in JSON
130130
Map<String, String> result = new HashMap<>();
131131
for (RuntimeValue value : runtimeValues.values()) {
132-
result.put(value.getKey().getKeyAsEnvVar(), value.getValue());
132+
if (value.getKey().getIncludeInApi()) {
133+
result.put(value.getKey().getKeyAsEnvVar(), value.getValue());
134+
}
133135
}
134136
return result;
135137
}
@@ -180,13 +182,27 @@ public String getRuntimeValue(String keyAsEnvVar) {
180182
return getRuntimeValue(RuntimeValueKeyRegistry.getRuntimeValue(keyAsEnvVar));
181183
}
182184

185+
public Object getRuntimeObject(String keyAsEnvVar) {
186+
Objects.requireNonNull(keyAsEnvVar, "key may not be null");
187+
return getRuntimeObject(RuntimeValueKeyRegistry.getRuntimeValue(keyAsEnvVar));
188+
}
189+
183190
public <T> T getRuntimeObject(RuntimeValueKey<T> key) {
184191
Objects.requireNonNull(key, "key may not be null");
185192
RuntimeValue runtimeValue = runtimeValues.get(key);
186193
Objects.requireNonNull(runtimeValue, "did not found a value for key " + key.getKeyAsEnvVar());
187194
return runtimeValue.getObject();
188195
}
189196

197+
public <T> T getRuntimeObjectOrNull(RuntimeValueKey<T> key) {
198+
Objects.requireNonNull(key, "key may not be null");
199+
RuntimeValue runtimeValue = runtimeValues.get(key);
200+
if (runtimeValue == null) {
201+
return null;
202+
}
203+
return runtimeValue.getObject();
204+
}
205+
190206
public <T> String getRuntimeValue(RuntimeValueKey<T> key) {
191207
Objects.requireNonNull(key, "key may not be null");
192208
RuntimeValue runtimeValue = runtimeValues.get(key);

0 commit comments

Comments
 (0)