-
-
Notifications
You must be signed in to change notification settings - Fork 295
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds
com.structurizr.api.AdminApiClient
as a client for the cloud s…
…ervice/on-premises admin APIs.
- Loading branch information
1 parent
8a7da17
commit 1a90ec8
Showing
9 changed files
with
788 additions
and
502 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
rootProject.name = 'structurizr' | ||
rootProject.name = 'structurizr-java' | ||
|
||
include 'structurizr-client' | ||
include 'structurizr-core' |
54 changes: 54 additions & 0 deletions
54
structurizr-client/src/com/structurizr/api/AbstractApiClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.structurizr.api; | ||
|
||
import com.structurizr.util.StringUtils; | ||
|
||
public abstract class AbstractApiClient { | ||
|
||
protected static final String VERSION = Package.getPackage("com.structurizr.api").getImplementationVersion(); | ||
protected static final String STRUCTURIZR_FOR_JAVA_AGENT = "structurizr-java/" + VERSION; | ||
|
||
protected static final String STRUCTURIZR_CLOUD_SERVICE_API_URL = "https://api.structurizr.com"; | ||
protected static final String WORKSPACE_PATH = "/workspace"; | ||
|
||
protected String url; | ||
protected String agent = STRUCTURIZR_FOR_JAVA_AGENT; | ||
|
||
String getUrl() { | ||
return url; | ||
} | ||
|
||
protected void setUrl(String url) { | ||
if (url == null || url.trim().length() == 0) { | ||
throw new IllegalArgumentException("The API URL must not be null or empty."); | ||
} | ||
|
||
if (url.endsWith("/")) { | ||
this.url = url.substring(0, url.length() - 1); | ||
} else { | ||
this.url = url; | ||
} | ||
} | ||
|
||
/** | ||
* Gets the agent string used to identify this client instance. | ||
* | ||
* @return "structurizr-java/{version}", unless overridden | ||
*/ | ||
public String getAgent() { | ||
return agent; | ||
} | ||
|
||
/** | ||
* Sets the agent string used to identify this client instance. | ||
* | ||
* @param agent the agent string | ||
*/ | ||
public void setAgent(String agent) { | ||
if (StringUtils.isNullOrEmpty(agent)) { | ||
throw new IllegalArgumentException("An agent must be provided."); | ||
} | ||
|
||
this.agent = agent.trim(); | ||
} | ||
|
||
} |
156 changes: 156 additions & 0 deletions
156
structurizr-client/src/com/structurizr/api/AdminApiClient.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package com.structurizr.api; | ||
|
||
import com.fasterxml.jackson.databind.DeserializationFeature; | ||
import com.fasterxml.jackson.databind.ObjectMapper; | ||
import com.structurizr.util.StringUtils; | ||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
import org.apache.hc.core5.http.HttpStatus; | ||
|
||
import java.net.URI; | ||
import java.net.http.HttpClient; | ||
import java.net.http.HttpRequest; | ||
import java.net.http.HttpResponse; | ||
import java.util.List; | ||
|
||
/** | ||
* A client for the Structurizr Admin API. | ||
*/ | ||
public class AdminApiClient extends AbstractApiClient { | ||
|
||
private static final Log log = LogFactory.getLog(AdminApiClient.class); | ||
|
||
private final String username; | ||
private final String apiKey; | ||
|
||
/** | ||
* Creates a new API client with the specified on-premises API URL and key. | ||
* | ||
* @param url the URL of your Structurizr instance | ||
* @param username the username (only required for the Structurizr cloud service) | ||
* @param apiKey the API key of your workspace | ||
*/ | ||
public AdminApiClient(String url, String username, String apiKey) { | ||
setUrl(url); | ||
|
||
this.username = username; | ||
|
||
if (apiKey == null || apiKey.trim().length() == 0) { | ||
throw new IllegalArgumentException("The API key must not be null or empty."); | ||
} | ||
|
||
this.apiKey = apiKey; | ||
} | ||
|
||
/** | ||
* Gets a list of all workspaces. | ||
* | ||
* @return a List of WorkspaceMetadata objects | ||
* @throws StructurizrClientException if an error occurs | ||
*/ | ||
public List<WorkspaceMetadata> getWorkspaces() throws StructurizrClientException { | ||
try { | ||
HttpRequest request = HttpRequest.newBuilder() | ||
.uri(URI.create(url + WORKSPACE_PATH)) | ||
.header(HttpHeaders.AUTHORIZATION, createAuthorizationHeader()) | ||
.header(HttpHeaders.USER_AGENT, agent) | ||
.build(); | ||
HttpClient client = HttpClient.newHttpClient(); | ||
|
||
ObjectMapper objectMapper = new ObjectMapper(); | ||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | ||
|
||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | ||
String json = response.body(); | ||
|
||
if (response.statusCode() == HttpStatus.SC_OK) { | ||
Workspaces workspaces = objectMapper.readValue(response.body(), Workspaces.class); | ||
return workspaces.getWorkspaces(); | ||
} else { | ||
ApiResponse apiResponse = ApiResponse.parse(json); | ||
throw new StructurizrClientException(apiResponse.getMessage()); | ||
} | ||
} catch (Exception e) { | ||
log.error(e); | ||
throw new StructurizrClientException(e); | ||
} | ||
} | ||
|
||
/** | ||
* Creates a new workspace. | ||
* | ||
* @return a WorkspaceMetadata object representing the new workspace | ||
* @throws StructurizrClientException if an error occurs | ||
*/ | ||
public WorkspaceMetadata createWorkspace() throws StructurizrClientException { | ||
try { | ||
HttpRequest request = HttpRequest.newBuilder() | ||
.uri(URI.create(url + WORKSPACE_PATH)) | ||
.POST(HttpRequest.BodyPublishers.noBody()) | ||
.header(HttpHeaders.AUTHORIZATION, createAuthorizationHeader()) | ||
.header(HttpHeaders.USER_AGENT, agent) | ||
.build(); | ||
HttpClient client = HttpClient.newHttpClient(); | ||
|
||
ObjectMapper objectMapper = new ObjectMapper(); | ||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | ||
|
||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | ||
String json = response.body(); | ||
|
||
if (response.statusCode() == HttpStatus.SC_OK) { | ||
return objectMapper.readValue(json, WorkspaceMetadata.class); | ||
} else { | ||
ApiResponse apiResponse = ApiResponse.parse(json); | ||
throw new StructurizrClientException(apiResponse.getMessage()); | ||
} | ||
} catch (Exception e) { | ||
log.error(e); | ||
throw new StructurizrClientException(e); | ||
} | ||
} | ||
|
||
/** | ||
* Deletes a workspace. | ||
* | ||
* @param workspaceId the ID of the workspace to delete | ||
* @throws StructurizrClientException if an error occurs | ||
*/ | ||
public void deleteWorkspace(int workspaceId) throws StructurizrClientException { | ||
try { | ||
HttpRequest request = HttpRequest.newBuilder() | ||
.uri(URI.create(url + WORKSPACE_PATH + "/" + workspaceId)) | ||
.DELETE() | ||
.header(HttpHeaders.AUTHORIZATION, createAuthorizationHeader()) | ||
.header(HttpHeaders.USER_AGENT, agent) | ||
.build(); | ||
HttpClient client = HttpClient.newHttpClient(); | ||
|
||
ObjectMapper objectMapper = new ObjectMapper(); | ||
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | ||
|
||
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); | ||
String json = response.body(); | ||
|
||
if (response.statusCode() == HttpStatus.SC_OK) { | ||
ApiResponse apiResponse = ApiResponse.parse(json); | ||
log.debug(apiResponse.getMessage()); | ||
} else { | ||
ApiResponse apiResponse = ApiResponse.parse(json); | ||
throw new StructurizrClientException(apiResponse.getMessage()); | ||
} | ||
} catch (Exception e) { | ||
log.error(e); | ||
throw new StructurizrClientException(e); | ||
} | ||
} | ||
|
||
private String createAuthorizationHeader() { | ||
if (StringUtils.isNullOrEmpty(username)) { | ||
return apiKey; | ||
} else { | ||
return username + ":" + apiKey; | ||
} | ||
} | ||
|
||
} |
Oops, something went wrong.