Skip to content

Commit

Permalink
gremlin: remove okhttp and gson dependencies (#162)
Browse files Browse the repository at this point in the history
  • Loading branch information
benbroadaway authored Jul 19, 2024
1 parent 661cca6 commit 3341af4
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 126 deletions.
18 changes: 6 additions & 12 deletions tasks/gremlin/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,15 @@
<artifactId>slf4j-api</artifactId>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.7.5</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>logging-interceptor</artifactId>
<version>2.7.5</version>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,8 @@
* =====
*/

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class AttackResult {

protected final Gson gson = new GsonBuilder().create();

private final String id;

public AttackResult(String id) {
Expand All @@ -39,10 +34,12 @@ public String id() {

public String details(TaskParams.AttackParams in) {
try {
return gson.toJson(new GremlinClient(in)
var map = new GremlinClient(in)
.url("attacks/" + id)
.successCode(200)
.get());
.get();

return Utils.objectMapper().writeValueAsString(map);
} catch (Exception e) {
throw new RuntimeException("Error occurred while getting attack details", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,26 +20,23 @@
* =====
*/

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.squareup.okhttp.*;
import com.squareup.okhttp.logging.HttpLoggingInterceptor;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
import java.net.URLEncoder;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.ArrayDeque;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class GremlinClient {

private static final OkHttpClient client = new OkHttpClient();
private static final Gson gson = new GsonBuilder().create();
private final HttpClient client;

private final GremlinClientParams params;

Expand All @@ -48,10 +45,16 @@ public class GremlinClient {

public GremlinClient(GremlinClientParams params) {
this.params = params;
this.client = getClient(params);
}

public GremlinClient url(String url) {
this.url = params.apiUrl() + url;
if (url.endsWith("/")) {
this.url = url;
} else {
this.url = url + "/";
}

return this;
}

Expand All @@ -61,71 +64,88 @@ public GremlinClient successCode(int successCode) {
}

public Map<String, Object> post(Map<String, Object> data) throws IOException {
RequestBody body = RequestBody.create(
MediaType.parse("application/json; charset=utf-8"), gson.toJson(data));
Request request = requestBuilder()
.addHeader("Content-Type", "application/json")
.post(body)
HttpRequest request = requestBuilder()
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(Utils.objectMapper().writeValueAsString(data)))
.build();

return call(request);
}

public Map<String, Object> get() throws IOException {
Request request = requestBuilder()
.get()
HttpRequest request = requestBuilder()
.GET()
.build();

return call(request);
}

public void delete() throws IOException {
Request request = requestBuilder()
.delete()
public void delete() {
HttpRequest request = requestBuilder()
.DELETE()
.build();

deleteCall(request);
}

private Request.Builder requestBuilder() {
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
if (params.teamId() != null) {
urlBuilder.addQueryParameter("teamId", params.teamId());
}
private HttpRequest.Builder requestBuilder() {

return new Request.Builder()
.addHeader("X-Gremlin-Agent", "concord/" + Version.getVersion())
.addHeader("Authorization", "Key " + params.apiKey())
.url(urlBuilder.build());
var rawUrl = params.teamId() == null
? url
: url + toParameterString(Map.of("teamId", params.teamId()));

return HttpRequest.newBuilder(URI.create(rawUrl))
.timeout(Duration.ofSeconds(params.connectTimeout()))
.header("X-Gremlin-Agent", "concord/" + Version.getVersion())
.header("Authorization", "Key " + params.apiKey());
}

@SuppressWarnings("unchecked")
private Map<String, Object> call(Request request) throws IOException {
setupClientParams();
private static String toParameterString(Map<String, String> params) {
if (params.isEmpty()) {
return "";
}

StringBuilder sb = new StringBuilder("?");
var paramQueue = new ArrayDeque<>(params.entrySet().stream().toList());

Response response = getClientResponse(request);
int statusCode = response.code();
try (ResponseBody responseBody = response.body()) {
String results = null;
if (responseBody != null) {
results = responseBody.string();
while (!paramQueue.isEmpty()) {
var param = paramQueue.poll();

sb.append(URLEncoder.encode(param.getKey(), StandardCharsets.UTF_8))
.append("=")
.append(URLEncoder.encode(param.getValue(), StandardCharsets.UTF_8));

if (!paramQueue.isEmpty()) {
sb.append("&");
}
Map<String, Object> objResults = Collections.singletonMap("results", results);
assertResponseCode(statusCode, objResults.toString(), successCode);
return gson.fromJson(objResults.toString(), Map.class);
}

return sb.toString();
}

private void deleteCall(Request request) throws IOException {
setupClientParams();
private Map<String, Object> call(HttpRequest request) throws IOException {
String results = null;
var response = getClientResponse(request, HttpResponse.BodyHandlers.ofString());
var responseBody = response.body();
int statusCode = response.statusCode();
if (responseBody != null) {
results = responseBody;
}
Map<String, Object> objResults = Collections.singletonMap("results", results);
assertResponseCode(statusCode, objResults.toString(), successCode);

Response response = getClientResponse(request);
int statusCode = response.code();
try (ResponseBody responseBody = response.body()) {
String results = null;
if (responseBody != null) {
results = responseBody.string();
}
assertResponseCode(statusCode, results, successCode);
return Map.of("results", Utils.objectMapper().readValue(responseBody, Map.class));
}

private void deleteCall(HttpRequest request) {
var response = getClientResponse(request, HttpResponse.BodyHandlers.ofString());
int statusCode = response.statusCode();
var responseBody = response.body();
String results = null;
if (responseBody != null) {
results = responseBody;
}
assertResponseCode(statusCode, results, successCode);
}

private static void assertResponseCode(int code, String result, int successCode) {
Expand All @@ -148,58 +168,26 @@ private static void assertResponseCode(int code, String result, int successCode)
}
}

private Response getClientResponse(Request request) {
Response response;
private <T> HttpResponse<T> getClientResponse(HttpRequest request, HttpResponse.BodyHandler<T> bodyHandler) {
try {
response = client.newCall(request).execute();
} catch (Exception e) {
return client.send(request, bodyHandler);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IllegalStateException("Thread interrupted", e);
} catch (IOException e) {
throw new RuntimeException("Error: " + e);
}
return response;
}

private HttpClient getClient(GremlinClientParams params) {
var clientBuilder = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(params.connectTimeout()));

private void setupClientParams() {
try {
client.setConnectTimeout(params.connectTimeout(), TimeUnit.SECONDS);
client.setReadTimeout(params.readTimeout(), TimeUnit.SECONDS);
client.setWriteTimeout(params.writeTimeout(), TimeUnit.SECONDS);

if (params.debug()) {
client.interceptors().add(new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY));
}

if (params.useProxy()) {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}

@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
}
};

// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());

// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
client.setProxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(params.proxyHost(), params.proxyPort())));
client.setSslSocketFactory(sslSocketFactory);
}
} catch (Exception e) {
throw new RuntimeException("Error: " + e);
if (params.useProxy()) {
clientBuilder.proxy(ProxySelector.of(new InetSocketAddress(params.proxyHost(), params.proxyPort())));
}

return clientBuilder.build();
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ public K8SAttackResult(String id) {
@Override
public String details(TaskParams.AttackParams in) {
try {
return gson.toJson(new GremlinClient(in)
var map = new GremlinClient(in)
.url("kubernetes/attacks/" + id())
.successCode(200)
.get());
.get();

return Utils.objectMapper().writeValueAsString(map);
} catch (Exception e) {
throw new RuntimeException("Error occurred while getting attack details", e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,35 @@
* =====
*/

import com.fasterxml.jackson.databind.ObjectMapper;
import com.walmartlabs.concord.common.ConfigurationUtils;
import com.walmartlabs.concord.sdk.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static com.walmartlabs.concord.plugins.gremlin.TaskParams.AttackParams;
import static com.walmartlabs.concord.plugins.gremlin.TaskParams.KubernetesParams;
import static com.walmartlabs.concord.plugins.gremlin.Utils.K8S_TARGET_KIND.*;
import static com.walmartlabs.concord.sdk.MapUtils.*;
import static com.walmartlabs.concord.plugins.gremlin.Utils.K8S_TARGET_KIND.DAEMONSET;
import static com.walmartlabs.concord.plugins.gremlin.Utils.K8S_TARGET_KIND.DEPLOYMENT;
import static com.walmartlabs.concord.plugins.gremlin.Utils.K8S_TARGET_KIND.POD;
import static com.walmartlabs.concord.plugins.gremlin.Utils.K8S_TARGET_KIND.STATEFULSET;
import static com.walmartlabs.concord.sdk.MapUtils.assertList;
import static com.walmartlabs.concord.sdk.MapUtils.getList;
import static com.walmartlabs.concord.sdk.MapUtils.getString;

public class Utils {

private static final Logger log = LoggerFactory.getLogger(GremlinTask.class);
private static final Logger log = LoggerFactory.getLogger(Utils.class);
private static final ObjectMapper MAPPER = new ObjectMapper();

private static final String ATTACK_GUID = "attackGuid";
private static final String ATTACK_DETAILS = "attackDetails";
Expand All @@ -47,13 +60,17 @@ enum K8S_TARGET_KIND {
POD
}

public static ObjectMapper objectMapper() {
return MAPPER;
}

private static final Set<String> K8S_TARGET_KINDS = Arrays.stream(K8S_TARGET_KIND.values()).map(Enum::name).collect(Collectors.toSet());

public static Map<String, Object> performAttack(AttackParams in, String type, List<String> params) {
AttackResult attack = createAttack(in, type, params);
String attackGuid = attack.id();
String attackDetails = attack.details(in);
log.info("URL of Gremlin Attack report: {}", in.appUrl() + attackGuid);
log.info("URL of Gremlin Attack report: {}{}", in.appUrl(), attackGuid);

Map<String, Object> result = new HashMap<>();
result.put(ATTACK_DETAILS, attackDetails);
Expand Down

0 comments on commit 3341af4

Please sign in to comment.