diff --git a/hetu-listener/src/main/java/io/hetu/core/eventlistener/util/HetuLogUtil.java b/hetu-listener/src/main/java/io/hetu/core/eventlistener/util/HetuLogUtil.java index 01d493065..d7c657226 100644 --- a/hetu-listener/src/main/java/io/hetu/core/eventlistener/util/HetuLogUtil.java +++ b/hetu-listener/src/main/java/io/hetu/core/eventlistener/util/HetuLogUtil.java @@ -41,8 +41,8 @@ public class HetuLogUtil private static String getCurrentDate(String logConversionPattern) { - if (logConversionPattern == null){ - logConversionPattern="yyyy-MM-dd.HH"; + if (logConversionPattern == null) { + logConversionPattern = "yyyy-MM-dd.HH"; } SimpleDateFormat formatter = new SimpleDateFormat(logConversionPattern); String dateString = formatter.format(new Date()); @@ -72,7 +72,7 @@ public class HetuLogUtil private void createFile(String auditLogFile) { - if (auditLogFile == null){ + if (auditLogFile == null) { return; } System.setProperty("hetu-LogOutput", auditLogFile); diff --git a/presto-main/src/main/java/io/prestosql/catalog/AbstractCatalogStore.java b/presto-main/src/main/java/io/prestosql/catalog/AbstractCatalogStore.java index 472f6bb34..511a7114c 100644 --- a/presto-main/src/main/java/io/prestosql/catalog/AbstractCatalogStore.java +++ b/presto-main/src/main/java/io/prestosql/catalog/AbstractCatalogStore.java @@ -51,7 +51,6 @@ public abstract class AbstractCatalogStore private static final Logger log = Logger.get(AbstractCatalogStore.class); private static final JsonCodec> LIST_CODEC = JsonCodec.listJsonCodec(String.class); private static final String CATALOG_NAME_PROPERTY = "connector.name"; - protected final String baseDirectory; protected final HetuFileSystemClient fileSystemClient; private final int maxFileSizeInBytes; @@ -235,6 +234,25 @@ public abstract class AbstractCatalogStore return new CatalogInfo(catalogName, connectorName, null, createdTime, version, catalogProperties); } + public Map getCatalogProperties(String catalogName, int state, String baseDirectory) + throws IOException + { + Properties properties = new Properties(); + CatalogFilePath catalogPath = new CatalogFilePath(baseDirectory, catalogName); + Path path; + if (state == 0) { + path = catalogPath.getPropertiesPath(); + } + else { + path = catalogPath.getStaticPath(); + } + try (InputStream inputStream = fileSystemClient.newInputStream(path)) { + properties.load(inputStream); + } + Map catalogProperties = new HashMap<>(fromProperties(properties)); + return catalogProperties; + } + public CatalogFileInputStream getCatalogFiles(String catalogName) throws IOException { diff --git a/presto-main/src/main/java/io/prestosql/catalog/CatalogFilePath.java b/presto-main/src/main/java/io/prestosql/catalog/CatalogFilePath.java index 76bf98a0c..d14dfe9a7 100644 --- a/presto-main/src/main/java/io/prestosql/catalog/CatalogFilePath.java +++ b/presto-main/src/main/java/io/prestosql/catalog/CatalogFilePath.java @@ -31,6 +31,7 @@ public final class CatalogFilePath private final Path propertiesPath; private final Path metadataPath; private final Path lockPath; + private final Path staticPath; /* * baseDirectory @@ -73,6 +74,7 @@ public final class CatalogFilePath this.metadataPath = Paths.get(catalogDirPath.toString(), catalogName + ".metadata"); // lock files directory this.lockPath = Paths.get(catalogBasePath); + this.staticPath = Paths.get(baseDirectory, catalogName + ".properties"); } public static Path getCatalogBasePath(String baseDirectory) @@ -104,4 +106,9 @@ public final class CatalogFilePath { return lockPath; } + + public Path getStaticPath() + { + return staticPath; + } } diff --git a/presto-main/src/main/java/io/prestosql/catalog/CatalogResource.java b/presto-main/src/main/java/io/prestosql/catalog/CatalogResource.java index 596075c68..b43543a25 100644 --- a/presto-main/src/main/java/io/prestosql/catalog/CatalogResource.java +++ b/presto-main/src/main/java/io/prestosql/catalog/CatalogResource.java @@ -193,7 +193,6 @@ public class CatalogResource @Context HttpServletRequest servletRequest) { CatalogInfo catalogInfo = toCatalogInfo(catalogInfoJson); - try (CatalogFileInputStream configFiles = toCatalogFiles(catalogConfigFileBodyParts, globalConfigFilesBodyParts)) { return service.createCatalog(catalogInfo, configFiles, diff --git a/presto-main/src/main/java/io/prestosql/catalog/CatalogStore.java b/presto-main/src/main/java/io/prestosql/catalog/CatalogStore.java index 20b2724da..2c56b07c7 100644 --- a/presto-main/src/main/java/io/prestosql/catalog/CatalogStore.java +++ b/presto-main/src/main/java/io/prestosql/catalog/CatalogStore.java @@ -16,6 +16,7 @@ package io.prestosql.catalog; import java.io.IOException; +import java.util.Map; import java.util.Set; import java.util.concurrent.locks.Lock; @@ -86,5 +87,7 @@ public interface CatalogStore */ void releaseCatalogLock(String catalogName); + Map getCatalogProperties(String catalogName, int state, String baseDirectory) throws IOException; + void close(); } diff --git a/presto-main/src/main/java/io/prestosql/catalog/DynamicCatalogStore.java b/presto-main/src/main/java/io/prestosql/catalog/DynamicCatalogStore.java index d414a8ace..b4cbcc4be 100644 --- a/presto-main/src/main/java/io/prestosql/catalog/DynamicCatalogStore.java +++ b/presto-main/src/main/java/io/prestosql/catalog/DynamicCatalogStore.java @@ -27,6 +27,7 @@ import io.prestosql.filesystem.FileSystemClientManager; import io.prestosql.metadata.CatalogManager; import io.prestosql.metadata.InternalNode; import io.prestosql.metadata.InternalNodeManager; +import io.prestosql.metadata.StaticCatalogStoreConfig; import io.prestosql.spi.PrestoException; import io.prestosql.spi.connector.CatalogName; @@ -76,6 +77,7 @@ public class DynamicCatalogStore public DynamicCatalogStore(ConnectorManager connectorManager, DataCenterConnectorManager dataCenterConnectorManager, DynamicCatalogConfig dynamicCatalogConfig, + StaticCatalogStoreConfig staticCatalogConfig, CatalogManager catalogManager, InternalNodeManager nodeManager, ServiceSelectorManager selectorManager, diff --git a/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogModule.java b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogModule.java new file mode 100644 index 000000000..5acd002a0 --- /dev/null +++ b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogModule.java @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2018-2020. Huawei Technologies Co., Ltd. All rights reserved. + * 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.prestosql.catalog.showcatalog; + +import com.google.inject.Binder; +import com.google.inject.Scopes; +import io.airlift.configuration.AbstractConfigurationAwareModule; +import org.glassfish.jersey.media.multipart.MultiPartFeature; + +import static io.airlift.jaxrs.JaxrsBinder.jaxrsBinder; + +public class ShowCatalogModule + extends AbstractConfigurationAwareModule +{ + @Override + protected void setup(Binder binder) + { + jaxrsBinder(binder).bind(ShowCatalogResource.class); + jaxrsBinder(binder).bind(MultiPartFeature.class); + binder.bind(ShowCatalogService.class).in(Scopes.SINGLETON); + } +} diff --git a/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogResource.java b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogResource.java new file mode 100644 index 000000000..2ff5cac35 --- /dev/null +++ b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogResource.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2018-2021. Huawei Technologies Co., Ltd. All rights reserved. + * 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.prestosql.catalog.showcatalog; + +import com.google.inject.Inject; +import io.prestosql.server.HttpRequestSessionContext; +import io.prestosql.spi.security.GroupProvider; +import org.assertj.core.util.VisibleForTesting; + +import javax.servlet.http.HttpServletRequest; +import javax.validation.constraints.NotNull; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +import java.util.Map; + +import static io.prestosql.catalog.DynamicCatalogService.badRequest; +import static java.util.Objects.requireNonNull; +import static javax.ws.rs.core.Response.Status.BAD_REQUEST; + +@Path("/v1/showCatalog") +public class ShowCatalogResource +{ + private static final int MAX_NAME_LENGTH = 255; + private static final String VALID_CATALOG_NAME_REGEX = "[\\p{Alnum}_]+"; + private final ShowCatalogService service; + private final GroupProvider groupProvider; + + @Inject + public ShowCatalogResource(ShowCatalogService service, GroupProvider groupProvider) + { + this.service = requireNonNull(service, "service is null"); + this.groupProvider = groupProvider; + } + + @VisibleForTesting + void checkCatalogName(String catalogName) + { + if (catalogName.length() > MAX_NAME_LENGTH) { + throw badRequest(BAD_REQUEST, "The length of catalog name is too long"); + } + + // check dc + int dotIndex = catalogName.indexOf("."); + if (dotIndex >= 0) { + if (dotIndex == 0 || dotIndex == catalogName.length() - 1) { + throw badRequest(BAD_REQUEST, "Invalid catalog name"); + } + String dc = catalogName.substring(0, dotIndex); + String catalog = catalogName.substring(dotIndex + 1); + if (!dc.matches(VALID_CATALOG_NAME_REGEX) || !catalog.matches(VALID_CATALOG_NAME_REGEX)) { + throw badRequest(BAD_REQUEST, "Invalid catalog name"); + } + return; + } + + if (!catalogName.matches(VALID_CATALOG_NAME_REGEX)) { + throw badRequest(BAD_REQUEST, "Invalid catalog name"); + } + } + + @GET + @Path("/{catalogName}") + @Produces(MediaType.APPLICATION_JSON) + public Map getCatalogpropertites(@NotNull @PathParam("catalogName") String catalogName, + @Context HttpServletRequest servletRequest) + { + checkCatalogName(catalogName); + Map response; + try { + response = service.getCatalogpropertites(new HttpRequestSessionContext(servletRequest, groupProvider), catalogName); + } + catch (WebApplicationException ex) { + throw ex; + } + catch (Throwable ex) { + throw badRequest(BAD_REQUEST, "show catalog failed. please check your request info."); + } + + return response; + } +} diff --git a/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogService.java b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogService.java new file mode 100644 index 000000000..cbedba210 --- /dev/null +++ b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogService.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018-2021. Huawei Technologies Co., Ltd. All rights reserved. + * 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.prestosql.catalog.showcatalog; + +import com.google.inject.Inject; +import io.prestosql.server.HttpRequestSessionContext; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +import java.io.IOException; +import java.util.Map; + +import static java.util.Objects.requireNonNull; +import static javax.ws.rs.core.MediaType.TEXT_PLAIN_TYPE; + +public class ShowCatalogService +{ + private final ShowCatalogStore showCatalogStore; + + @Inject + public ShowCatalogService(ShowCatalogStore showCatalogStore) + { + this.showCatalogStore = requireNonNull(showCatalogStore, "dynamicCatalogStore is null"); + } + + public static WebApplicationException badRequest(Response.Status status, String message) + { + throw new WebApplicationException( + Response.status(status) + .type(TEXT_PLAIN_TYPE) + .entity(message) + .build()); + } + + public Map getCatalogpropertites(HttpRequestSessionContext sessionContext, String catalogname) + throws IOException + { + return showCatalogStore.getCatalogProperties(catalogname); + } +} diff --git a/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogStore.java b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogStore.java new file mode 100644 index 000000000..fd284d249 --- /dev/null +++ b/presto-main/src/main/java/io/prestosql/catalog/showcatalog/ShowCatalogStore.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2018-2021. Huawei Technologies Co., Ltd. All rights reserved. + * 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.prestosql.catalog.showcatalog; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Inject; +import io.prestosql.catalog.CatalogStore; +import io.prestosql.catalog.DynamicCatalogConfig; +import io.prestosql.catalog.LocalCatalogStore; +import io.prestosql.catalog.ShareCatalogStore; +import io.prestosql.filesystem.FileSystemClientManager; +import io.prestosql.metadata.StaticCatalogStoreConfig; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +public class ShowCatalogStore +{ + private final StaticCatalogStoreConfig staticCatalogConfig; + private final DynamicCatalogConfig dynamicCatalogConfig; + private CatalogStore localCatalogStore; + private CatalogStore shareCatalogStore; + + @Inject + public ShowCatalogStore(DynamicCatalogConfig dynamicCatalogConfig, + StaticCatalogStoreConfig staticCatalogConfig) + { + this.dynamicCatalogConfig = dynamicCatalogConfig; + this.staticCatalogConfig = staticCatalogConfig; + } + + public void loadCatalogStores(FileSystemClientManager fileSystemClientManager) + throws IOException + { + if (!dynamicCatalogConfig.isDynamicCatalogEnabled()) { + return; + } + + int maxCatalogFileSize = (int) dynamicCatalogConfig.getCatalogMaxFileSize().toBytes(); + String localConfigurationDir = dynamicCatalogConfig.getCatalogConfigurationDir(); + Properties properties = new Properties(); + properties.put("fs.client.type", "local"); + this.localCatalogStore = new LocalCatalogStore(localConfigurationDir, + fileSystemClientManager.getFileSystemClient(properties, Paths.get(localConfigurationDir)), + maxCatalogFileSize); + + String shareConfigurationDir = dynamicCatalogConfig.getCatalogShareConfigurationDir(); + this.shareCatalogStore = new ShareCatalogStore(shareConfigurationDir, + fileSystemClientManager.getFileSystemClient(dynamicCatalogConfig.getShareFileSystemProfile(), Paths.get(shareConfigurationDir)), + maxCatalogFileSize); + } + + private CatalogStore getCatalogStore(CatalogStoreType type) + { + if (type == CatalogStoreType.LOCAL) { + return localCatalogStore; + } + else { + return shareCatalogStore; + } + } + + public synchronized Set listCatalogNames(CatalogStoreType type) + throws IOException + { + return ImmutableSet.copyOf(getCatalogStore(type).listCatalogNames()); + } + + public Map getCatalogProperties(String catalogName) + throws IOException + { + Set localCatalogs = listCatalogNames(CatalogStoreType.LOCAL); + Set shareCatalogs = listCatalogNames(CatalogStoreType.SHARE); + if (localCatalogs.contains(catalogName)) { + return localCatalogStore.getCatalogProperties(catalogName, 0, dynamicCatalogConfig.getCatalogConfigurationDir()); + } + else if (shareCatalogs.contains(catalogName)) { + return shareCatalogStore.getCatalogProperties(catalogName, 0, dynamicCatalogConfig.getCatalogShareConfigurationDir()); + } + else { + return localCatalogStore.getCatalogProperties(catalogName, 1, staticCatalogConfig.getCatalogConfigurationDir().toString()); + } + } + + public enum CatalogStoreType { + LOCAL, + SHARE + } +} diff --git a/presto-main/src/main/java/io/prestosql/server/CoordinatorModule.java b/presto-main/src/main/java/io/prestosql/server/CoordinatorModule.java index 57b86d00e..6e3f19ce4 100644 --- a/presto-main/src/main/java/io/prestosql/server/CoordinatorModule.java +++ b/presto-main/src/main/java/io/prestosql/server/CoordinatorModule.java @@ -26,6 +26,7 @@ import io.airlift.discovery.server.EmbeddedDiscoveryModule; import io.airlift.units.Duration; import io.prestosql.catalog.CatalogModule; import io.prestosql.catalog.DynamicCatalogConfig; +import io.prestosql.catalog.showcatalog.ShowCatalogModule; import io.prestosql.client.QueryResults; import io.prestosql.cost.CostCalculator; import io.prestosql.cost.CostCalculator.EstimatedExchanges; @@ -113,6 +114,7 @@ import io.prestosql.memory.TotalReservationOnBlockedNodesLowMemoryKiller; import io.prestosql.metadata.CatalogManager; import io.prestosql.operator.ForScheduler; import io.prestosql.queryeditorui.QueryEditorUIModule; +import io.prestosql.queryhistory.QueryHistoryModule; import io.prestosql.server.remotetask.RemoteTaskStats; import io.prestosql.spi.memory.ClusterMemoryPoolManager; import io.prestosql.spi.resourcegroups.QueryType; @@ -227,6 +229,12 @@ public class CoordinatorModule // catalog resource install(installModuleIf(DynamicCatalogConfig.class, DynamicCatalogConfig::isDynamicCatalogEnabled, new CatalogModule())); + //showcatalog resourece + install(new ShowCatalogModule()); + + //QueryHistory Module + binder.install(new QueryHistoryModule()); + // resource for serving static content jaxrsBinder(binder).bind(WebUiResource.class); diff --git a/presto-main/src/main/java/io/prestosql/server/PrestoServer.java b/presto-main/src/main/java/io/prestosql/server/PrestoServer.java index b2111aa5b..047284081 100755 --- a/presto-main/src/main/java/io/prestosql/server/PrestoServer.java +++ b/presto-main/src/main/java/io/prestosql/server/PrestoServer.java @@ -33,6 +33,7 @@ import io.airlift.node.NodeModule; import io.airlift.tracetoken.TraceTokenModule; import io.prestosql.catalog.DynamicCatalogScanner; import io.prestosql.catalog.DynamicCatalogStore; +import io.prestosql.catalog.showcatalog.ShowCatalogStore; import io.prestosql.discovery.HetuDiscoveryModule; import io.prestosql.dynamicfilter.CrossRegionDynamicFilterListener; import io.prestosql.dynamicfilter.DynamicFilterCacheManager; @@ -154,6 +155,7 @@ public class PrestoServer injector.getInstance(StaticFunctionNamespaceStore.class).loadFunctionNamespaceManagers(); injector.getInstance(StaticCatalogStore.class).loadCatalogs(); injector.getInstance(DynamicCatalogStore.class).loadCatalogStores(fileSystemClientManager); + injector.getInstance(ShowCatalogStore.class).loadCatalogStores(fileSystemClientManager); injector.getInstance(DynamicCatalogScanner.class).start(); injector.getInstance(SessionPropertyDefaults.class).loadConfigurationManager(); injector.getInstance(ResourceGroupManager.class).loadConfigurationManager(); diff --git a/presto-main/src/main/java/io/prestosql/server/ServerMainModule.java b/presto-main/src/main/java/io/prestosql/server/ServerMainModule.java index 60e0c0237..8296575ad 100644 --- a/presto-main/src/main/java/io/prestosql/server/ServerMainModule.java +++ b/presto-main/src/main/java/io/prestosql/server/ServerMainModule.java @@ -37,6 +37,7 @@ import io.prestosql.catalog.CatalogStoreUtil; import io.prestosql.catalog.DynamicCatalogConfig; import io.prestosql.catalog.DynamicCatalogScanner; import io.prestosql.catalog.DynamicCatalogStore; +import io.prestosql.catalog.showcatalog.ShowCatalogStore; import io.prestosql.client.NodeVersion; import io.prestosql.client.ServerInfo; import io.prestosql.connector.CatalogConnectorStore; @@ -515,6 +516,9 @@ public class ServerMainModule binder.bind(CatalogStoreUtil.class).in(Scopes.SINGLETON); configBinder(binder).bindConfig(DynamicCatalogConfig.class); + // show catalog + binder.bind(ShowCatalogStore.class).in(Scopes.SINGLETON); + // plugin manager binder.bind(PluginManager.class).in(Scopes.SINGLETON); configBinder(binder).bindConfig(PluginManagerConfig.class); diff --git a/presto-main/src/main/resources/webapp/src/queryeditor/actions/CatalogActions.js b/presto-main/src/main/resources/webapp/src/queryeditor/actions/CatalogActions.js index f76784761..0b6b717c4 100644 --- a/presto-main/src/main/resources/webapp/src/queryeditor/actions/CatalogActions.js +++ b/presto-main/src/main/resources/webapp/src/queryeditor/actions/CatalogActions.js @@ -14,6 +14,8 @@ */ import alt from '../alt'; import CatalogApiUtils from "../utils/CatalogApiUtils"; +import xhrform from "../utils/xhrform"; +import UserStore from "../stores/UserStore"; class CatalogActions { constructor() { diff --git a/presto-main/src/main/resources/webapp/src/queryeditor/components/SchemaTree.jsx b/presto-main/src/main/resources/webapp/src/queryeditor/components/SchemaTree.jsx index f101ae436..af799eb96 100644 --- a/presto-main/src/main/resources/webapp/src/queryeditor/components/SchemaTree.jsx +++ b/presto-main/src/main/resources/webapp/src/queryeditor/components/SchemaTree.jsx @@ -23,6 +23,11 @@ import TabActions from "../actions/TabActions"; import TabConstants from "../constants/TabConstants"; import _ from "lodash"; import QueryActions from "../actions/QueryActions"; +import ModalDialog from "./ModalDialog"; +import ShowCatalog from "./ShowCatalog"; +import {color} from "echarts/lib/export"; + +let flag = true; function getIcon(type) { switch (type) { @@ -35,7 +40,12 @@ function getIcon(type) { // return (storage); } case dataType.CATALOG: { - return (); + if (!flag) { + return (); + } + else { + return + } // return (source); } default: { @@ -45,9 +55,10 @@ function getIcon(type) { } function renderItem(tree, item) { - let style = (item.children == undefined || item.children instanceof Array && item.children.length == 0) ? { marginLeft: "14.5px" } : {}; + flag = item.children == undefined || item.children instanceof Array && item.children.length == 0 ; + let style = (item.children == undefined || item.children instanceof Array && item.children.length == 0) ? { marginLeft: "14.5px",color: "gray" } : {}; let tableStyle = {}; - Object.assign(tableStyle, style, { cursor: "pointer" }) + //Object.assign(tableStyle, style, { cursor: "pointer" }) let favorite = tree.isFavorite(item); if (item.type == dataType.TABLE) { if (item.fqn == tree.selectedTableName) { @@ -59,7 +70,7 @@ function renderItem(tree, item) { {getIcon(item.type)}{item.name}{favorite.found ? : null} - {favorite.found && favorite.self ? + {favorite.found && favorite.self && !flag ? { tree.removeFromFavorites(item); }}> @@ -105,7 +116,7 @@ function renderItem(tree, item) { "icon fa fa-star valign-middle schema-tree-icons favoriteParent"} /> : null} - {favorite.found && favorite.self ? + {favorite.found && favorite.self && !flag ? { tree.removeFromFavorites(item); }}> @@ -123,6 +134,19 @@ function renderItem(tree, item) { }}> Refresh + {/* {*/} + {/* tree.showCatalog(item);*/} + {/*}}>*/} + {/* Show Catalog*/} + {/**/} + {item.type == dataType.CATALOG ? + { + tree.showCatalog(item); + }}> + Show Catalog + + : null + } {item.type == dataType.CATALOG ? { tree.deleteCatalog(item); @@ -185,7 +209,13 @@ class SchemaTree extends React.Component { }, height: 0, model: this.getInitialModel(), - name: "name" + name: "name", + show: false, + catalog_name:"", + connection_password: "", + connector_name: "", + url: "", + user: "" }; this.selectedTableName = ""; this.treeRef = React.createRef(); @@ -194,6 +224,7 @@ class SchemaTree extends React.Component { schemas: [], tables: [] } + this.showObj = {} this.updateTree = this.updateTree.bind(this); this.selectTable = this.selectTable.bind(this); this.unselectTable = this.unselectTable.bind(this); @@ -203,6 +234,9 @@ class SchemaTree extends React.Component { this.reloadItem = this.reloadItem.bind(this); this.refreshItem = this.refreshItem.bind(this); this.deleteCatalog = this.deleteCatalog.bind(this); + this.showCatalog = this.showCatalog.bind(this); + this.showModal = this.showModal.bind(this); + this._objToStrMap = this._objToStrMap.bind(this); } updateTree() { @@ -256,6 +290,41 @@ class SchemaTree extends React.Component { element.style.color = "#222222"; } + showModal() { + let newState = !this.state.show; + this.setState({ + show: newState, + }); + } + + _objToStrMap(obj){ + let strMap = new Map(); + for (let k of Object.keys(obj)) { + strMap.set(k,obj[k]); + } + return strMap; + } + + + showCatalog(item) { + this.state.catalog_name = item.name; + let showText = item.name; + $.get(`../v1/showCatalog/${showText}`, function (showList) { + let showMap = this._objToStrMap(showList); + this.showObj = showList; + this.setState({ + connection_password : showMap.get('connection-password'), + connector_name : showMap.get('connector.name'), + url : showMap.get('connection-url'), + user : showMap.get('connection-user') + }) + }.bind(this)) + let newState = !this.state.show; + this.setState({ + show: newState, + }); + } + deleteCatalog(item) { let msg = 'Are you sure you want to delete the catalog?'; if (item.name.indexOf(".") !== -1) { @@ -406,7 +475,11 @@ class SchemaTree extends React.Component {
- + + + + ); } } diff --git a/presto-main/src/main/resources/webapp/src/queryeditor/components/ShowCatalog.jsx b/presto-main/src/main/resources/webapp/src/queryeditor/components/ShowCatalog.jsx new file mode 100644 index 000000000..a9eacaa6e --- /dev/null +++ b/presto-main/src/main/resources/webapp/src/queryeditor/components/ShowCatalog.jsx @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2018-2020. Huawei Technologies Co., Ltd. All rights reserved. + * 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. + */ +import React from 'react'; +import {Button, Col, Form, FormControl, FormGroup, FormLabel, Row} from "react-bootstrap"; + +const props = {}; + +class ShowCatalog extends React.Component { + constructor(props) { + super(props); + this.state = { + catalog_name:"", + connection_password: "", + connector_name: "", + url: "", + user: "" + } + this.showObj = {} + this.handleClose = this.handleClose.bind(this); + this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this); + this._objToStrMap = this._objToStrMap.bind(this); + this.deleteMapKey = this.deleteMapKey.bind(this); + this.renderCatalogProperties = this.renderCatalogProperties.bind(this); + } + + componentWillReceiveProps(nextProps) { + if (this.props.showText != nextProps.showText){ + this.state.catalog_name = nextProps.catalog_name; + // this.state.connection_password = nextProps.connection_password; + // this.state.connector_name = nextProps.connector_name; + // this.state.url = nextProps.url; + // this.state.user = nextProps.user; + // this.show = nextProps; + this.showObj = nextProps.showText + this.setState(); + // this.setState({ + // catalog_name : nextProps.catalog_name + // }) + } + } + + handleClose() { + this.props.onClose && this.props.onClose(); + } + + _objToStrMap(obj){ + let strMap = new Map(); + for (let k of Object.keys(obj)) { + strMap.set(k,obj[k]); + } + return strMap; + } + + deleteMapKey(obj,key) { + let newMap = new Map(); + for (let item of obj.keys()){ + if (item != key){ + newMap.set(item,obj.get(item)); + } + } + return newMap; + } + + renderCatalogProperties(obj) { + let arr = [] + for (let item of obj.keys()) { + arr.push( + + + + + + + + + ) + } + return ( + arr + ) + } + + render() { + let showMap = this._objToStrMap(this.showObj); + let catalogProperties = this.deleteMapKey(showMap,'connector.name'); + return( +
+
+
+ + + + Data Source Type + + +
+ +
+ +
+ + + Catalog Name + + +
+ +
+ +
+ {catalogProperties.size == 0 ? + null + : + + + Catalog Properties + + +
+ {this.renderCatalogProperties(catalogProperties)} +
+ +
+ } +
+
+
+
+ +
+
+ ) + } +} + +export default ShowCatalog \ No newline at end of file