Skip to content

Commit

Permalink
Allow updating workspace names (#9686)
Browse files Browse the repository at this point in the history
* Allow updating workspace names

* Add additional unit test

* Fix code styling

* Update slug as well

* Update indentations

* Pull name update into separate endpoint
  • Loading branch information
timroes authored Jan 31, 2022
1 parent c873898 commit 8f22595
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 0 deletions.
33 changes: 33 additions & 0 deletions airbyte-api/src/main/openapi/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,29 @@ paths:
$ref: "#/components/responses/NotFoundResponse"
"422":
$ref: "#/components/responses/InvalidInputResponse"
/v1/workspaces/update_name:
post:
tags:
- workspace
summary: Update workspace name
operationId: updateWorkspaceName
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/WorkspaceUpdateName"
required: true
responses:
"200":
description: Successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/WorkspaceRead"
"404":
$ref: "#/components/responses/NotFoundResponse"
"422":
$ref: "#/components/responses/InvalidInputResponse"
/v1/workspaces/tag_feedback_status_as_done:
post:
tags:
Expand Down Expand Up @@ -1972,6 +1995,16 @@ components:
type: boolean
feedbackDone:
type: boolean
WorkspaceUpdateName:
type: object
required:
- workspaceId
- name
properties:
workspaceId:
$ref: "#/components/schemas/WorkspaceId"
name:
type: string
WorkspaceUpdate:
type: object
required:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
import io.airbyte.api.model.WorkspaceRead;
import io.airbyte.api.model.WorkspaceReadList;
import io.airbyte.api.model.WorkspaceUpdate;
import io.airbyte.api.model.WorkspaceUpdateName;
import io.airbyte.commons.features.FeatureFlags;
import io.airbyte.commons.io.FileTtlManager;
import io.airbyte.commons.version.AirbyteVersion;
Expand Down Expand Up @@ -266,6 +267,11 @@ public WorkspaceRead updateWorkspace(final WorkspaceUpdate workspaceUpdate) {
return execute(() -> workspacesHandler.updateWorkspace(workspaceUpdate));
}

@Override
public WorkspaceRead updateWorkspaceName(final WorkspaceUpdateName workspaceUpdateName) {
return execute(() -> workspacesHandler.updateWorkspaceName(workspaceUpdateName));
}

@Override
public void updateWorkspaceFeedback(final WorkspaceGiveFeedback workspaceGiveFeedback) {
execute(() -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.airbyte.api.model.WorkspaceRead;
import io.airbyte.api.model.WorkspaceReadList;
import io.airbyte.api.model.WorkspaceUpdate;
import io.airbyte.api.model.WorkspaceUpdateName;
import io.airbyte.config.StandardWorkspace;
import io.airbyte.config.persistence.ConfigNotFoundException;
import io.airbyte.config.persistence.ConfigRepository;
Expand Down Expand Up @@ -167,6 +168,21 @@ public WorkspaceRead updateWorkspace(final WorkspaceUpdate workspaceUpdate) thro
return buildWorkspaceReadFromId(workspaceUpdate.getWorkspaceId());
}

public WorkspaceRead updateWorkspaceName(final WorkspaceUpdateName workspaceUpdateName)
throws JsonValidationException, ConfigNotFoundException, IOException {
final UUID workspaceId = workspaceUpdateName.getWorkspaceId();

final StandardWorkspace persistedWorkspace = configRepository.getStandardWorkspace(workspaceId, false);

persistedWorkspace
.withName(workspaceUpdateName.getName())
.withSlug(generateUniqueSlug(workspaceUpdateName.getName()));

configRepository.writeStandardWorkspace(persistedWorkspace);

return buildWorkspaceReadFromId(workspaceId);
}

public NotificationRead tryNotification(final Notification notification) {
try {
final NotificationClient notificationClient = NotificationClient.createNotificationClient(NotificationConverter.toConfig(notification));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import io.airbyte.api.model.WorkspaceRead;
import io.airbyte.api.model.WorkspaceReadList;
import io.airbyte.api.model.WorkspaceUpdate;
import io.airbyte.api.model.WorkspaceUpdateName;
import io.airbyte.commons.json.Jsons;
import io.airbyte.config.Notification;
import io.airbyte.config.Notification.NotificationType;
Expand All @@ -44,6 +45,7 @@
import java.util.UUID;
import java.util.function.Supplier;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;

Expand Down Expand Up @@ -344,6 +346,51 @@ void testUpdateWorkspace() throws JsonValidationException, ConfigNotFoundExcepti
assertEquals(expectedWorkspaceRead, actualWorkspaceRead);
}

@Test
@DisplayName("Updating workspace name should update name and slug")
void testUpdateWorkspaceNoNameUpdate() throws JsonValidationException, ConfigNotFoundException, IOException {
final WorkspaceUpdateName workspaceUpdate = new WorkspaceUpdateName()
.workspaceId(workspace.getWorkspaceId())
.name("New Workspace Name");

final StandardWorkspace expectedWorkspace = new StandardWorkspace()
.withWorkspaceId(workspace.getWorkspaceId())
.withCustomerId(workspace.getCustomerId())
.withEmail("test@airbyte.io")
.withName("New Workspace Name")
.withSlug("new-workspace-name")
.withAnonymousDataCollection(workspace.getAnonymousDataCollection())
.withSecurityUpdates(workspace.getSecurityUpdates())
.withNews(workspace.getNews())
.withInitialSetupComplete(workspace.getInitialSetupComplete())
.withDisplaySetupWizard(workspace.getDisplaySetupWizard())
.withTombstone(false)
.withNotifications(workspace.getNotifications());

when(configRepository.getStandardWorkspace(workspace.getWorkspaceId(), false))
.thenReturn(workspace)
.thenReturn(expectedWorkspace);

final WorkspaceRead actualWorkspaceRead = workspacesHandler.updateWorkspaceName(workspaceUpdate);

final WorkspaceRead expectedWorkspaceRead = new WorkspaceRead()
.workspaceId(workspace.getWorkspaceId())
.customerId(workspace.getCustomerId())
.email("test@airbyte.io")
.name("New Workspace Name")
.slug("new-workspace-name")
.initialSetupComplete(workspace.getInitialSetupComplete())
.displaySetupWizard(workspace.getDisplaySetupWizard())
.news(workspace.getNews())
.anonymousDataCollection(workspace.getAnonymousDataCollection())
.securityUpdates(workspace.getSecurityUpdates())
.notifications(List.of(generateApiNotification()));

verify(configRepository).writeStandardWorkspace(expectedWorkspace);

assertEquals(expectedWorkspaceRead, actualWorkspaceRead);
}

@Test
public void testSetFeedbackDone() throws JsonValidationException, ConfigNotFoundException, IOException {
final WorkspaceGiveFeedback workspaceGiveFeedback = new WorkspaceGiveFeedback()
Expand Down
92 changes: 92 additions & 0 deletions docs/reference/api/generated-api-html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ <h4><a href="#Workspace">Workspace</a></h4>
<li><a href="#listWorkspaces"><code><span class="http-method">post</span> /v1/workspaces/list</code></a></li>
<li><a href="#updateWorkspace"><code><span class="http-method">post</span> /v1/workspaces/update</code></a></li>
<li><a href="#updateWorkspaceFeedback"><code><span class="http-method">post</span> /v1/workspaces/tag_feedback_status_as_done</code></a></li>
<li><a href="#updateWorkspaceName"><code><span class="http-method">post</span> /v1/workspaces/update_name</code></a></li>
</ul>

<h1><a name="Connection">Connection</a></h1>
Expand Down Expand Up @@ -7447,6 +7448,88 @@ <h4 class="field-label">404</h4>
<a href="#NotFoundKnownExceptionInfo">NotFoundKnownExceptionInfo</a>
</div> <!-- method -->
<hr/>
<div class="method"><a name="updateWorkspaceName"/>
<div class="method-path">
<a class="up" href="#__Methods">Up</a>
<pre class="post"><code class="huge"><span class="http-method">post</span> /v1/workspaces/update_name</code></pre></div>
<div class="method-summary">Update workspace name (<span class="nickname">updateWorkspaceName</span>)</div>
<div class="method-notes"></div>


<h3 class="field-label">Consumes</h3>
This API call consumes the following media types via the <span class="header">Content-Type</span> request header:
<ul>
<li><code>application/json</code></li>
</ul>

<h3 class="field-label">Request body</h3>
<div class="field-items">
<div class="param">WorkspaceUpdateName <a href="#WorkspaceUpdateName">WorkspaceUpdateName</a> (required)</div>

<div class="param-desc"><span class="param-type">Body Parameter</span> &mdash; </div>

</div> <!-- field-items -->




<h3 class="field-label">Return type</h3>
<div class="return-type">
<a href="#WorkspaceRead">WorkspaceRead</a>

</div>

<!--Todo: process Response Object and its headers, schema, examples -->

<h3 class="field-label">Example data</h3>
<div class="example-data-content-type">Content-Type: application/json</div>
<pre class="example"><code>{
"news" : true,
"displaySetupWizard" : true,
"initialSetupComplete" : true,
"anonymousDataCollection" : true,
"customerId" : "046b6c7f-0b8a-43b9-b35d-6489e6daee91",
"name" : "name",
"firstCompletedSync" : true,
"feedbackDone" : true,
"email" : "email",
"slug" : "slug",
"securityUpdates" : true,
"notifications" : [ {
"slackConfiguration" : {
"webhook" : "webhook"
},
"sendOnSuccess" : false,
"sendOnFailure" : true
}, {
"slackConfiguration" : {
"webhook" : "webhook"
},
"sendOnSuccess" : false,
"sendOnFailure" : true
} ],
"workspaceId" : "046b6c7f-0b8a-43b9-b35d-6489e6daee91"
}</code></pre>

<h3 class="field-label">Produces</h3>
This API call produces the following media types according to the <span class="header">Accept</span> request header;
the media type will be conveyed by the <span class="header">Content-Type</span> response header.
<ul>
<li><code>application/json</code></li>
</ul>

<h3 class="field-label">Responses</h3>
<h4 class="field-label">200</h4>
Successful operation
<a href="#WorkspaceRead">WorkspaceRead</a>
<h4 class="field-label">404</h4>
Object with given id was not found.
<a href="#NotFoundKnownExceptionInfo">NotFoundKnownExceptionInfo</a>
<h4 class="field-label">422</h4>
Input failed validation
<a href="#InvalidInputExceptionInfo">InvalidInputExceptionInfo</a>
</div> <!-- method -->
<hr/>

<h2><a name="__Models">Models</a></h2>
[ Jump to <a href="#__Methods">Methods</a> ]
Expand Down Expand Up @@ -7571,6 +7654,7 @@ <h3>Table of Contents</h3>
<li><a href="#WorkspaceRead"><code>WorkspaceRead</code> - </a></li>
<li><a href="#WorkspaceReadList"><code>WorkspaceReadList</code> - </a></li>
<li><a href="#WorkspaceUpdate"><code>WorkspaceUpdate</code> - </a></li>
<li><a href="#WorkspaceUpdateName"><code>WorkspaceUpdateName</code> - </a></li>
</ol>

<div class="model">
Expand Down Expand Up @@ -8711,5 +8795,13 @@ <h3><a name="WorkspaceUpdate"><code>WorkspaceUpdate</code> - </a> <a class="up"
<div class="param">notifications (optional)</div><div class="param-desc"><span class="param-type"><a href="#Notification">array[Notification]</a></span> </div>
</div> <!-- field-items -->
</div>
<div class="model">
<h3><a name="WorkspaceUpdateName"><code>WorkspaceUpdateName</code> - </a> <a class="up" href="#__Models">Up</a></h3>
<div class='model-description'></div>
<div class="field-items">
<div class="param">workspaceId </div><div class="param-desc"><span class="param-type"><a href="#UUID">UUID</a></span> format: uuid</div>
<div class="param">name </div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
</div> <!-- field-items -->
</div>
</body>
</html>

0 comments on commit 8f22595

Please sign in to comment.