mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-2449 rm api changes for writing resources (#1066)
* CB-2449 rm api changes for writing resources * CB-2455 feat(plugin-resource-manager): Do not rewrite script with the same name * CB-2449 test for writing resource in rm Co-authored-by: Konstantin Vasilev <konstantin.vasiliev@dbeaver.com>
This commit is contained in:
co-authored by
Konstantin Vasilev
parent
3fc7444e8c
commit
67f0853df0
+5
-1
@@ -438,7 +438,8 @@ public class LocalResourceController implements RMController {
|
||||
public String setResourceContents(
|
||||
@NotNull String projectId,
|
||||
@NotNull String resourcePath,
|
||||
@NotNull byte[] data) throws DBException
|
||||
@NotNull byte[] data,
|
||||
boolean forceOverwrite) throws DBException
|
||||
{
|
||||
validateResourcePath(resourcePath);
|
||||
Number fileSizeLimit = WebAppUtils.getWebApplication()
|
||||
@@ -452,6 +453,9 @@ public class LocalResourceController implements RMController {
|
||||
data.length);
|
||||
}
|
||||
Path targetPath = getTargetPath(projectId, resourcePath);
|
||||
if (!forceOverwrite && Files.exists(targetPath)) {
|
||||
throw new DBException("Resource '" + resourcePath + "' exists");
|
||||
}
|
||||
if (!Files.exists(targetPath.getParent())) {
|
||||
throw new DBException("Parent folder '" + targetPath.getParent().getFileName() + "' doesn't exist");
|
||||
}
|
||||
|
||||
@@ -57,7 +57,8 @@ extend type Mutation {
|
||||
rmWriteResourceStringContent(
|
||||
projectId: String!,
|
||||
resourcePath: String!,
|
||||
data: String!): String!
|
||||
data: String!,
|
||||
forceOverwrite: Boolean!): String!
|
||||
|
||||
rmCreateProject(
|
||||
projectName: String!,
|
||||
|
||||
+2
-1
@@ -80,7 +80,8 @@ public interface DBWServiceRM extends DBWService {
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull @WebObjectId String projectId,
|
||||
@NotNull String resourcePath,
|
||||
@NotNull String data) throws DBException;
|
||||
@NotNull String data,
|
||||
boolean forceOverwrite) throws DBException;
|
||||
|
||||
@WebAction(requirePermissions = {DBWConstants.PERMISSION_ADMIN, RMConstants.PERMISSION_RM_ADMIN})
|
||||
WebProjectInfo createProject(
|
||||
|
||||
+2
-1
@@ -64,7 +64,8 @@ public class WebServiceBindingRM extends WebServiceBindingBase<DBWServiceRM> {
|
||||
env -> getService(env).writeResourceStringContent(getWebSession(env),
|
||||
env.getArgument("projectId"),
|
||||
env.getArgument("resourcePath"),
|
||||
env.getArgument("data")))
|
||||
env.getArgument("data"),
|
||||
env.getArgument("forceOverwrite")))
|
||||
|
||||
.dataFetcher("rmCreateProject", env -> getService(env).createProject(
|
||||
getWebSession(env),
|
||||
|
||||
+8
-2
@@ -89,11 +89,17 @@ public class WebServiceRM implements DBWServiceRM {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String writeResourceStringContent(@NotNull WebSession webSession, @NotNull String projectId, @NotNull String resourcePath, @NotNull String data) throws DBException {
|
||||
public String writeResourceStringContent(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull String projectId,
|
||||
@NotNull String resourcePath,
|
||||
@NotNull String data,
|
||||
boolean forceOverwrite
|
||||
) throws DBException {
|
||||
checkIsRmEnabled(webSession);
|
||||
try {
|
||||
byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
|
||||
return getResourceController(webSession).setResourceContents(projectId, resourcePath, bytes);
|
||||
return getResourceController(webSession).setResourceContents(projectId, resourcePath, bytes, forceOverwrite);
|
||||
} catch (Exception e) {
|
||||
throw new DBWebException("Error writing resource '" + resourcePath + "' data", e);
|
||||
}
|
||||
|
||||
@@ -22,5 +22,6 @@ Require-Bundle: org.eclipse.core.runtime,
|
||||
io.cloudbeaver.server,
|
||||
io.cloudbeaver.resources.drivers.base,
|
||||
io.cloudbeaver.product.ce,
|
||||
io.cloudbeaver.service.auth
|
||||
io.cloudbeaver.service.auth,
|
||||
io.cloudbeaver.service.rm
|
||||
Export-Package: io.cloudbeaver.test.platform
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ import java.net.http.HttpClient;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@RunWith(Suite.class)
|
||||
@Suite.SuiteClasses({PlatformTest.class, AuthenticationTest.class })
|
||||
@Suite.SuiteClasses({PlatformTest.class, AuthenticationTest.class, ResourceManagerTest.class })
|
||||
public class CEServerTestSuite {
|
||||
|
||||
public static final String GQL_API_URL = "http://localhost:18978/api/gql";
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2022 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.cloudbeaver.test.platform;
|
||||
|
||||
import io.cloudbeaver.model.rm.local.LocalResourceController;
|
||||
import io.cloudbeaver.server.CBApplication;
|
||||
import io.cloudbeaver.utils.WebTestUtils;
|
||||
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.net.CookieManager;
|
||||
import java.net.http.HttpClient;
|
||||
import java.util.Map;
|
||||
|
||||
public class ResourceManagerTest {
|
||||
|
||||
public static final String GQL_TEMPLATE_RM_WRITE_RESOURCE = "rmWriteResource.json";
|
||||
public static final String GQL_TEMPLATE_RM_DELETE_RESOURCE = "navDeleteNode.json";
|
||||
|
||||
@Test
|
||||
public void createDeleteResourceTest() throws Exception {
|
||||
Assert.assertTrue(CBApplication.getInstance().getAppConfiguration().isResourceManagerEnabled());
|
||||
HttpClient client = HttpClient.newBuilder()
|
||||
.cookieHandler(new CookieManager())
|
||||
.version(HttpClient.Version.HTTP_2)
|
||||
.build();
|
||||
Map<String, Object> authInfo = WebTestUtils.authenticateUser(
|
||||
client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL);
|
||||
Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));
|
||||
Assert.assertTrue(createResource(client, false));
|
||||
Assert.assertFalse(createResource(client, false));
|
||||
Assert.assertTrue(createResource(client, true));
|
||||
Assert.assertEquals(1, deleteResource(client));
|
||||
}
|
||||
|
||||
|
||||
private boolean createResource(HttpClient client, boolean forceOverwrite) throws Exception {
|
||||
String input = WebTestUtils.readScriptTemplate(
|
||||
GQL_TEMPLATE_RM_WRITE_RESOURCE, CEServerTestSuite.getScriptsPath()
|
||||
).replaceAll("\\{forceOverwrite}", CommonUtils.toString(forceOverwrite));
|
||||
Map<String, Object> map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client);
|
||||
Map<String, Object> data = JSONUtils.getObjectOrNull(map, "data");
|
||||
if (data != null) {
|
||||
return LocalResourceController.DEFAULT_CHANGE_ID.equals(JSONUtils.getString(data, "rmWriteResourceStringContent"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private int deleteResource(HttpClient client) throws Exception {
|
||||
String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_RM_DELETE_RESOURCE, CEServerTestSuite.getScriptsPath());
|
||||
Map<String, Object> map = WebTestUtils.doPost(CEServerTestSuite.GQL_API_URL, input, client);
|
||||
Map<String, Object> data = JSONUtils.getObjectOrNull(map, "data");
|
||||
if (data != null) {
|
||||
return JSONUtils.getInteger(data, "navDeleteNodes");
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"query": "\n mutation navDeleteNodes($nodePaths: [ID!]!) {\n navDeleteNodes(nodePaths: $nodePaths)\n}\n ",
|
||||
"variables": {
|
||||
"nodePaths": [
|
||||
"ext://resources/u_test/testScript.sql"
|
||||
]
|
||||
},
|
||||
"operationName": "navDeleteNodes"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"query": "\n mutation writeContent($projectId: String!, $resourcePath: String!, $data: String!, $forceOverwrite: Boolean!) {\n rmWriteResourceStringContent(\n projectId: $projectId\n resourcePath: $resourcePath\n data: $data\n forceOverwrite: $forceOverwrite\n )\n}\n ",
|
||||
"variables": {
|
||||
"projectId": "u_test",
|
||||
"resourcePath": "testScript.sql",
|
||||
"data": "TEST SCRIPT;",
|
||||
"forceOverwrite": {forceOverwrite}
|
||||
},
|
||||
"operationName": "writeContent"
|
||||
}
|
||||
@@ -1,3 +1,13 @@
|
||||
mutation writeResourceContent($projectId: String!, $resourcePath: String!, $data: String!) {
|
||||
rmWriteResourceStringContent(projectId: $projectId, resourcePath: $resourcePath, data: $data)
|
||||
mutation writeResourceContent(
|
||||
$projectId: String!,
|
||||
$resourcePath: String!,
|
||||
$data: String!,
|
||||
$forceOverwrite: Boolean!
|
||||
) {
|
||||
rmWriteResourceStringContent(
|
||||
projectId: $projectId,
|
||||
resourcePath: $resourcePath,
|
||||
data: $data,
|
||||
forceOverwrite: $forceOverwrite
|
||||
)
|
||||
}
|
||||
@@ -563,6 +563,7 @@ export interface MutationRmMoveResourceArgs {
|
||||
|
||||
export interface MutationRmWriteResourceStringContentArgs {
|
||||
data: Scalars['String'];
|
||||
forceOverwrite: Scalars['Boolean'];
|
||||
projectId: Scalars['String'];
|
||||
resourcePath: Scalars['String'];
|
||||
}
|
||||
@@ -2446,6 +2447,7 @@ export type WriteResourceContentMutationVariables = Exact<{
|
||||
projectId: Scalars['String'];
|
||||
resourcePath: Scalars['String'];
|
||||
data: Scalars['String'];
|
||||
forceOverwrite: Scalars['Boolean'];
|
||||
}>;
|
||||
|
||||
|
||||
@@ -3907,11 +3909,12 @@ export const ReadResourceDocument = `
|
||||
}
|
||||
`;
|
||||
export const WriteResourceContentDocument = `
|
||||
mutation writeResourceContent($projectId: String!, $resourcePath: String!, $data: String!) {
|
||||
mutation writeResourceContent($projectId: String!, $resourcePath: String!, $data: String!, $forceOverwrite: Boolean!) {
|
||||
rmWriteResourceStringContent(
|
||||
projectId: $projectId
|
||||
resourcePath: $resourcePath
|
||||
data: $data
|
||||
forceOverwrite: $forceOverwrite
|
||||
)
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -40,7 +40,7 @@ export class NavResourceNodeService {
|
||||
async saveScript(resourceData: IResourceData, name: string, script: string): Promise<string> {
|
||||
const resourcePath = createPath(resourceData.resourcePath, name);
|
||||
// await this.resourceManagerResource.createResource(resourceData.key.projectId, resourcePath, false);
|
||||
await this.resourceManagerResource.writeResource(resourceData.key.projectId, resourcePath, script);
|
||||
await this.resourceManagerResource.writeResource(resourceData.key.projectId, resourcePath, script, false);
|
||||
await this.navTreeResource.refreshTree(resourceData.nodeId);
|
||||
|
||||
return createPath(RESOURCES_NODE_PATH, resourceData.key.projectId, resourcePath);
|
||||
@@ -57,7 +57,12 @@ export class NavResourceNodeService {
|
||||
}
|
||||
|
||||
async write(resourceData: IResourceData, value: string) {
|
||||
await this.resourceManagerResource.writeResource(resourceData.key.projectId, resourceData.resourcePath, value);
|
||||
await this.resourceManagerResource.writeResource(
|
||||
resourceData.key.projectId,
|
||||
resourceData.resourcePath,
|
||||
value,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
getResourceData(nodeId: string): IResourceData | undefined {
|
||||
|
||||
@@ -59,11 +59,12 @@ export class ResourceManagerResource extends CachedMapResource<IResourceManagerP
|
||||
await this.load({ projectId, folder:folder ? resourcePath : this.getFolder(resourcePath) });
|
||||
}
|
||||
|
||||
async writeResource(projectId: string, resourcePath: string, data: string) {
|
||||
async writeResource(projectId: string, resourcePath: string, data: string, forceOverwrite: boolean) {
|
||||
await this.graphQLService.sdk.writeResourceContent({
|
||||
projectId,
|
||||
resourcePath,
|
||||
data,
|
||||
forceOverwrite,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user