show catalog by reading properties file
This commit is contained in:
parent
3a54b7ba01
commit
17455b0876
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -51,7 +51,6 @@ public abstract class AbstractCatalogStore
|
|||
private static final Logger log = Logger.get(AbstractCatalogStore.class);
|
||||
private static final JsonCodec<List<String>> 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<String, String> 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<String, String> catalogProperties = new HashMap<>(fromProperties(properties));
|
||||
return catalogProperties;
|
||||
}
|
||||
|
||||
public CatalogFileInputStream getCatalogFiles(String catalogName)
|
||||
throws IOException
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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<String, String> getCatalogProperties(String catalogName, int state, String baseDirectory) throws IOException;
|
||||
|
||||
void close();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, String> getCatalogpropertites(@NotNull @PathParam("catalogName") String catalogName,
|
||||
@Context HttpServletRequest servletRequest)
|
||||
{
|
||||
checkCatalogName(catalogName);
|
||||
Map<String, String> 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, String> getCatalogpropertites(HttpRequestSessionContext sessionContext, String catalogname)
|
||||
throws IOException
|
||||
{
|
||||
return showCatalogStore.getCatalogProperties(catalogname);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String> listCatalogNames(CatalogStoreType type)
|
||||
throws IOException
|
||||
{
|
||||
return ImmutableSet.copyOf(getCatalogStore(type).listCatalogNames());
|
||||
}
|
||||
|
||||
public Map<String, String> getCatalogProperties(String catalogName)
|
||||
throws IOException
|
||||
{
|
||||
Set<String> localCatalogs = listCatalogNames(CatalogStoreType.LOCAL);
|
||||
Set<String> 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
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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 (<i className="material-icons">storage</i>);
|
||||
}
|
||||
case dataType.CATALOG: {
|
||||
return (<i className="icon fa fa-server valign-middle"></i>);
|
||||
if (!flag) {
|
||||
return (<i className="icon fa fa-server valign-middle"></i>);
|
||||
}
|
||||
else {
|
||||
return <i className="icon fa fa-server valign-middle" style={{marginLeft: "14.5px", color : 'gray'}}></i>
|
||||
}
|
||||
// return (<i className="material-icons">source</i>);
|
||||
}
|
||||
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)}<span>{item.name}</span>{favorite.found ? <i className="icon fa fa-star valign-middle schema-tree-icons favorite" /> : null}
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenu id={item.fqn}>
|
||||
{favorite.found && favorite.self ?
|
||||
{favorite.found && favorite.self && !flag ?
|
||||
<MenuItem data={{ item: item, tree: tree }} onClick={(e, data) => {
|
||||
tree.removeFromFavorites(item);
|
||||
}}>
|
||||
|
|
@ -105,7 +116,7 @@ function renderItem(tree, item) {
|
|||
"icon fa fa-star valign-middle schema-tree-icons favoriteParent"} /> : null}
|
||||
</ContextMenuTrigger>
|
||||
<ContextMenu id={item.fqn}>
|
||||
{favorite.found && favorite.self ?
|
||||
{favorite.found && favorite.self && !flag ?
|
||||
<MenuItem data={{ item: item, tree: tree }} onClick={(e, data) => {
|
||||
tree.removeFromFavorites(item);
|
||||
}}>
|
||||
|
|
@ -123,6 +134,19 @@ function renderItem(tree, item) {
|
|||
}}>
|
||||
<i className="icon fa fa-refresh valign-middle" /><span>Refresh</span>
|
||||
</MenuItem>
|
||||
{/*<MenuItem data={{ item: item, tree: tree }} onClick={(e, data) => {*/}
|
||||
{/* tree.showCatalog(item);*/}
|
||||
{/*}}>*/}
|
||||
{/* <i className="icon fa fa-file-text-o show-catalog" /><span>Show Catalog</span>*/}
|
||||
{/*</MenuItem>*/}
|
||||
{item.type == dataType.CATALOG ?
|
||||
<MenuItem data={{ item: item, tree: tree }} onClick={(e, data) => {
|
||||
tree.showCatalog(item);
|
||||
}}>
|
||||
<i className="icon fa fa-file-text-o valign-middle contextmenu-icons show-catalog" /><span>Show Catalog</span>
|
||||
</MenuItem>
|
||||
: null
|
||||
}
|
||||
{item.type == dataType.CATALOG ?
|
||||
<MenuItem data={{ item: item, tree: tree }} onClick={(e, data) => {
|
||||
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 {
|
|||
<div style={{ height: "calc(100vh - 200px)" }}>
|
||||
<TreeView {...this.state} ref={this.treeRef}></TreeView>
|
||||
</div>
|
||||
</div>
|
||||
<ModalDialog onClose={this.showModal} header={"Show Catalog"} footer={""}
|
||||
show={this.state.show}>
|
||||
<ShowCatalog onClose={this.showModal.bind(this)} catalog_name={this.state.catalog_name} showText={this.showObj}/>
|
||||
</ModalDialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
<Row style={{display: "flex",alignItems:'center'}}>
|
||||
<Col style={{flexDirection: "column", marginRight: '10px', width:"70%"}}>
|
||||
<FormControl name="name" type="text" placeholder={"property name"}
|
||||
value={item}
|
||||
readOnly="true"/>
|
||||
</Col>
|
||||
<Col style={{flexDirection: "column", width:"100%"}}>
|
||||
<FormControl name="value" type="text" placeholder={"property value"}
|
||||
value={obj.get(item)}
|
||||
readOnly="true"/>
|
||||
</Col>
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
return (
|
||||
arr
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
let showMap = this._objToStrMap(this.showObj);
|
||||
let catalogProperties = this.deleteMapKey(showMap,'connector.name');
|
||||
return(
|
||||
<div>
|
||||
<div className={"hetu-foem-body"} style={{position: "relative", paddingLeft: "20px", paddingRight: "20px", overflowY: "auto"}}>
|
||||
<Form>
|
||||
<FormGroup>
|
||||
<Row>
|
||||
<Col style={{display: "flex", alignItems:'center'}}>
|
||||
<FormLabel className={"hetu-form-label"}>Data Source Type</FormLabel>
|
||||
</Col>
|
||||
<Col>
|
||||
<div style={{display: "block"}}>
|
||||
<input className="form-control" value={showMap.get('connector.name')} readOnly="true"/>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col style={{display: "flex", alignItems:'center'}}>
|
||||
<FormLabel className={"hetu-form-label"}>Catalog Name</FormLabel>
|
||||
</Col>
|
||||
<Col>
|
||||
<div style={{display: "block"}}>
|
||||
<input className="form-control" value={this.state.catalog_name} disabled="true"/>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
{catalogProperties.size == 0 ?
|
||||
null
|
||||
:
|
||||
<Row>
|
||||
<Col style={{display: "flex", alignItems: 'center'}}>
|
||||
<FormLabel className={"hetu-form-label"}>Catalog Properties</FormLabel>
|
||||
</Col>
|
||||
<Col>
|
||||
<div style={{display: "block"}}>
|
||||
{this.renderCatalogProperties(catalogProperties)}
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
}
|
||||
</FormGroup>
|
||||
</Form>
|
||||
</div>
|
||||
<div className={'catalog-btn-part'}>
|
||||
<Button onClick={this.handleClose} className={"btn btn-lg"}>Close</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ShowCatalog
|
||||
Loading…
Reference in New Issue