Skip to content

Commit

Permalink
fix: replace String.format() with newly created class OpenApiPathBuilder
Browse files Browse the repository at this point in the history
Signed-off-by: WillardHu <[email protected]>
  • Loading branch information
WillardHu committed Sep 14, 2021
1 parent 0b5d227 commit 85acf67
Show file tree
Hide file tree
Showing 9 changed files with 508 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@
package com.ctrip.framework.apollo.openapi.client.exception;

public class ApolloOpenApiException extends RuntimeException {

private int status;
private final int status;

public ApolloOpenApiException(int status, String reason, String message) {
super(String.format("Request to apollo open api failed, status code: %d, reason: %s, message: %s", status, reason,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,21 @@
package com.ctrip.framework.apollo.openapi.client.service;

import com.ctrip.framework.apollo.openapi.client.exception.ApolloOpenApiException;
import com.ctrip.framework.apollo.openapi.client.url.OpenApiPathBuilder;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.escape.Escaper;
import com.google.common.net.UrlEscapers;
import com.google.gson.Gson;
import java.io.IOException;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;

abstract class AbstractOpenApiService {
private static final Escaper pathEscaper = UrlEscapers.urlPathSegmentEscaper();
private static final Escaper queryParamEscaper = UrlEscapers.urlFormParameterEscaper();
import java.io.IOException;

abstract class AbstractOpenApiService {
private final String baseUrl;

protected final CloseableHttpClient client;
Expand All @@ -52,38 +43,30 @@ abstract class AbstractOpenApiService {
this.gson = gson;
}

protected CloseableHttpResponse get(String path) throws IOException {
HttpGet get = new HttpGet(String.format("%s/%s", baseUrl, path));
protected CloseableHttpResponse get(OpenApiPathBuilder path) throws IOException {
HttpGet get = new HttpGet(path.buildPath(baseUrl));

return execute(get);
}

protected CloseableHttpResponse post(String path, Object entity) throws IOException {
HttpPost post = new HttpPost(String.format("%s/%s", baseUrl, path));
protected CloseableHttpResponse post(OpenApiPathBuilder path, Object entity) throws IOException {
HttpPost post = new HttpPost(path.buildPath(baseUrl));

return execute(post, entity);
}

protected CloseableHttpResponse put(String path, Object entity) throws IOException {
HttpPut put = new HttpPut(String.format("%s/%s", baseUrl, path));
protected CloseableHttpResponse put(OpenApiPathBuilder path, Object entity) throws IOException {
HttpPut put = new HttpPut(path.buildPath(baseUrl));

return execute(put, entity);
}

protected CloseableHttpResponse delete(String path) throws IOException {
HttpDelete delete = new HttpDelete(String.format("%s/%s", baseUrl, path));
protected CloseableHttpResponse delete(OpenApiPathBuilder path) throws IOException {
HttpDelete delete = new HttpDelete(path.buildPath(baseUrl));

return execute(delete);
}

protected String escapePath(String path) {
return pathEscaper.escape(path);
}

protected String escapeParam(String param) {
return queryParamEscaper.escape(param);
}

private CloseableHttpResponse execute(HttpEntityEnclosingRequestBase requestBase, Object entity) throws IOException {
requestBase.setEntity(new StringEntity(gson.toJson(entity), ContentType.APPLICATION_JSON));

Expand All @@ -98,7 +81,6 @@ private CloseableHttpResponse execute(HttpUriRequest request) throws IOException
return response;
}


private void checkHttpResponseStatus(HttpResponse response) {
if (response.getStatusLine().getStatusCode() == 200) {
return;
Expand All @@ -118,5 +100,7 @@ private void checkHttpResponseStatus(HttpResponse response) {
protected void checkNotEmpty(String value, String name) {
Preconditions.checkArgument(!Strings.isNullOrEmpty(value), name + " should not be null or empty");
}



}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.ctrip.framework.apollo.openapi.client.service;

import com.ctrip.framework.apollo.openapi.client.url.OpenApiPathBuilder;
import com.ctrip.framework.apollo.openapi.dto.OpenAppDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenEnvClusterDTO;
import com.google.common.base.Joiner;
Expand All @@ -40,33 +41,38 @@ public AppOpenApiService(CloseableHttpClient client, String baseUrl, Gson gson)
public List<OpenEnvClusterDTO> getEnvClusterInfo(String appId) {
checkNotEmpty(appId, "App id");

String path = String.format("apps/%s/envclusters", escapePath(appId));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.appsPathVal(appId)
.customResource("envclusters");

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OPEN_ENV_CLUSTER_DTO_LIST_TYPE);
} catch (Throwable ex) {
throw new RuntimeException(String.format("Load env cluster information for appId: %s failed", appId), ex);
}
}

public List<OpenAppDTO> getAppsInfo(List<String> appIds) {
String path = "apps";
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.customResource("apps");

if (appIds != null && !appIds.isEmpty()) {
String param = Joiner.on(",").join(appIds);
path = String.format("apps?appIds=%s", escapeParam(param));
pathBuilder.addParam("appIds", param);
}

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OPEN_APP_DTO_LIST_TYPE);
} catch (Throwable ex) {
throw new RuntimeException(String.format("Load app information for appIds: %s failed", appIds), ex);
}
}

public List<OpenAppDTO> getAuthorizedApps() {
String path = "apps/authorized";
try(CloseableHttpResponse response = this.get(path)) {
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.customResource("apps/authorized");

try(CloseableHttpResponse response = this.get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OPEN_APP_DTO_LIST_TYPE);
} catch (Throwable ex) {
throw new RuntimeException("Load authorized apps failed", ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package com.ctrip.framework.apollo.openapi.client.service;

import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.openapi.client.url.OpenApiPathBuilder;
import com.ctrip.framework.apollo.openapi.dto.OpenClusterDTO;
import com.google.common.base.Strings;
import com.google.gson.Gson;
Expand All @@ -38,10 +39,12 @@ public OpenClusterDTO getCluster(String appId, String env, String clusterName) {
clusterName = ConfigConsts.CLUSTER_NAME_DEFAULT;
}

String path = String.format("envs/%s/apps/%s/clusters/%s", escapePath(env), escapePath(appId),
escapePath(clusterName));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName);

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenClusterDTO.class);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand All @@ -55,9 +58,12 @@ public OpenClusterDTO createCluster(String env, OpenClusterDTO openClusterDTO) {
checkNotEmpty(openClusterDTO.getName(), "Cluster name");
checkNotEmpty(openClusterDTO.getDataChangeCreatedBy(), "Created by");

String path = String.format("envs/%s/apps/%s/clusters", escapePath(env), escapePath(openClusterDTO.getAppId()));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(openClusterDTO.getAppId())
.customResource("clusters");

try (CloseableHttpResponse response = post(path, openClusterDTO)) {
try (CloseableHttpResponse response = post(pathBuilder, openClusterDTO)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenClusterDTO.class);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.openapi.client.exception.ApolloOpenApiException;
import com.ctrip.framework.apollo.openapi.client.url.OpenApiPathBuilder;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.google.common.base.Strings;
import com.google.gson.Gson;
Expand All @@ -43,10 +44,14 @@ public OpenItemDTO getItem(String appId, String env, String clusterName, String
checkNotEmpty(env, "Env");
checkNotEmpty(key, "Item key");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s/items/%s",
escapePath(env), escapePath(appId), escapePath(clusterName), escapePath(namespaceName), escapePath(key));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName)
.itemsPathVal(key);

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenItemDTO.class);
} catch (Throwable ex) {
// return null if item doesn't exist
Expand All @@ -72,10 +77,14 @@ public OpenItemDTO createItem(String appId, String env, String clusterName, Stri
checkNotEmpty(itemDTO.getKey(), "Item key");
checkNotEmpty(itemDTO.getDataChangeCreatedBy(), "Item created by");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s/items",
escapePath(env), escapePath(appId), escapePath(clusterName), escapePath(namespaceName));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName)
.customResource("items");

try (CloseableHttpResponse response = post(path, itemDTO)) {
try (CloseableHttpResponse response = post(pathBuilder, itemDTO)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenItemDTO.class);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand All @@ -97,11 +106,14 @@ public void updateItem(String appId, String env, String clusterName, String name
checkNotEmpty(itemDTO.getKey(), "Item key");
checkNotEmpty(itemDTO.getDataChangeLastModifiedBy(), "Item modified by");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s/items/%s",
escapePath(env), escapePath(appId), escapePath(clusterName), escapePath(namespaceName),
escapePath(itemDTO.getKey()));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName)
.itemsPathVal(itemDTO.getKey());

try (CloseableHttpResponse ignored = put(path, itemDTO)) {
try (CloseableHttpResponse ignored = put(pathBuilder, itemDTO)) {
} catch (Throwable ex) {
throw new RuntimeException(String
.format("Update item: %s for appId: %s, cluster: %s, namespace: %s in env: %s failed", itemDTO.getKey(),
Expand All @@ -126,11 +138,15 @@ public void createOrUpdateItem(String appId, String env, String clusterName, Str
itemDTO.setDataChangeLastModifiedBy(itemDTO.getDataChangeCreatedBy());
}

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s/items/%s?createIfNotExists=true",
escapePath(env), escapePath(appId), escapePath(clusterName), escapePath(namespaceName),
escapePath(itemDTO.getKey()));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName)
.itemsPathVal(itemDTO.getKey())
.addParam("createIfNotExists", "true");

try (CloseableHttpResponse ignored = put(path, itemDTO)) {
try (CloseableHttpResponse ignored = put(pathBuilder, itemDTO)) {
} catch (Throwable ex) {
throw new RuntimeException(String
.format("CreateOrUpdate item: %s for appId: %s, cluster: %s, namespace: %s in env: %s failed", itemDTO.getKey(),
Expand All @@ -151,11 +167,15 @@ public void removeItem(String appId, String env, String clusterName, String name
checkNotEmpty(key, "Item key");
checkNotEmpty(operator, "Operator");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s/items/%s?operator=%s",
escapePath(env), escapePath(appId), escapePath(clusterName), escapePath(namespaceName), escapePath(key),
escapeParam(operator));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName)
.itemsPathVal(key)
.addParam("operator", operator);

try (CloseableHttpResponse ignored = delete(path)) {
try (CloseableHttpResponse ignored = delete(pathBuilder)) {
} catch (Throwable ex) {
throw new RuntimeException(String
.format("Remove item: %s for appId: %s, cluster: %s, namespace: %s in env: %s failed", key, appId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.ctrip.framework.apollo.core.ConfigConsts;
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
import com.ctrip.framework.apollo.openapi.client.url.OpenApiPathBuilder;
import com.ctrip.framework.apollo.openapi.dto.OpenAppNamespaceDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenNamespaceLockDTO;
Expand Down Expand Up @@ -49,10 +50,13 @@ public OpenNamespaceDTO getNamespace(String appId, String env, String clusterNam
checkNotEmpty(appId, "App id");
checkNotEmpty(env, "Env");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s", escapePath(env), escapePath(appId),
escapePath(clusterName), escapePath(namespaceName));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName);

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenNamespaceDTO.class);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand All @@ -69,10 +73,13 @@ public List<OpenNamespaceDTO> getNamespaces(String appId, String env, String clu
checkNotEmpty(appId, "App id");
checkNotEmpty(env, "Env");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces", escapePath(env), escapePath(appId),
escapePath(clusterName));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.customResource("namespaces");

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OPEN_NAMESPACE_DTO_LIST_TYPE);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand All @@ -89,9 +96,11 @@ public OpenAppNamespaceDTO createAppNamespace(OpenAppNamespaceDTO appNamespaceDT
appNamespaceDTO.setFormat(ConfigFileFormat.Properties.getValue());
}

String path = String.format("apps/%s/appnamespaces", escapePath(appNamespaceDTO.getAppId()));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.appsPathVal(appNamespaceDTO.getAppId())
.customResource("appnamespaces");

try (CloseableHttpResponse response = post(path, appNamespaceDTO)) {
try (CloseableHttpResponse response = post(pathBuilder, appNamespaceDTO)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenAppNamespaceDTO.class);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand All @@ -111,10 +120,14 @@ public OpenNamespaceLockDTO getNamespaceLock(String appId, String env, String cl
checkNotEmpty(appId, "App id");
checkNotEmpty(env, "Env");

String path = String.format("envs/%s/apps/%s/clusters/%s/namespaces/%s/lock", escapePath(env), escapePath(appId),
escapePath(clusterName), escapePath(namespaceName));
OpenApiPathBuilder pathBuilder = OpenApiPathBuilder.newBuilder()
.envsPathVal(env)
.appsPathVal(appId)
.clustersPathVal(clusterName)
.namespacesPathVal(namespaceName)
.customResource("lock");

try (CloseableHttpResponse response = get(path)) {
try (CloseableHttpResponse response = get(pathBuilder)) {
return gson.fromJson(EntityUtils.toString(response.getEntity()), OpenNamespaceLockDTO.class);
} catch (Throwable ex) {
throw new RuntimeException(String
Expand Down
Loading

0 comments on commit 85acf67

Please sign in to comment.