diff --git a/server/bundles/io.cloudbeaver.model/plugin.xml b/server/bundles/io.cloudbeaver.model/plugin.xml index 9b42539f54..f503391bb6 100644 --- a/server/bundles/io.cloudbeaver.model/plugin.xml +++ b/server/bundles/io.cloudbeaver.model/plugin.xml @@ -4,6 +4,7 @@ + diff --git a/server/bundles/io.cloudbeaver.model/schema/io.cloudbeaver.server.feature.exsd b/server/bundles/io.cloudbeaver.model/schema/io.cloudbeaver.server.feature.exsd new file mode 100644 index 0000000000..93c93336c8 --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/schema/io.cloudbeaver.server.feature.exsd @@ -0,0 +1,34 @@ + + + + + + + + Web feature + + + + + + + + + + + + + + + + + + + + Web service description + + + + + + diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebServerFeatureDescriptor.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebServerFeatureDescriptor.java new file mode 100644 index 0000000000..6e04d75767 --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebServerFeatureDescriptor.java @@ -0,0 +1,72 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 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.registry; + +import io.cloudbeaver.DBWFeatureSet; +import io.cloudbeaver.utils.WebAppUtils; +import org.eclipse.core.runtime.IConfigurationElement; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.DBPImage; +import org.jkiss.dbeaver.model.impl.AbstractContextDescriptor; + +/** + * WebFeatureDescriptor + */ +public class WebServerFeatureDescriptor extends AbstractContextDescriptor implements DBWFeatureSet { + + public static final String EXTENSION_ID = "io.cloudbeaver.server.feature"; //$NON-NLS-1$ + + private final String id; + private final String label; + private final String description; + private final DBPImage icon; + + public WebServerFeatureDescriptor(IConfigurationElement config) + { + super(config); + this.id = config.getAttribute("id"); + this.label = config.getAttribute("label"); + this.description = config.getAttribute("description"); + this.icon = iconToImage(config.getAttribute("icon")); + } + + @NotNull + public String getId() { + return id; + } + + @NotNull + public String getLabel() { + return label; + } + + public String getDescription() { + return description; + } + + @Override + public DBPImage getIcon() { + return icon; + } + + @Override + public boolean isEnabled() { + return true; + } + +} diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebServerFeatureRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebServerFeatureRegistry.java new file mode 100644 index 0000000000..32a8c7a59c --- /dev/null +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebServerFeatureRegistry.java @@ -0,0 +1,68 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 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.registry; + +import io.cloudbeaver.DBWFeatureSet; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtensionRegistry; +import org.eclipse.core.runtime.Platform; +import org.jkiss.dbeaver.Log; + +import java.util.ArrayList; +import java.util.List; + +public class WebServerFeatureRegistry { + + private static final Log log = Log.getLog(WebServerFeatureRegistry.class); + + private static final String TAG_FEATURE = "feature"; //$NON-NLS-1$ + + private static WebServerFeatureRegistry instance = null; + + public synchronized static WebServerFeatureRegistry getInstance() { + if (instance == null) { + instance = new WebServerFeatureRegistry(); + instance.loadExtensions(Platform.getExtensionRegistry()); + } + return instance; + } + + private String[] serverFeatures = new String[0]; + + private WebServerFeatureRegistry() { + } + + private synchronized void loadExtensions(IExtensionRegistry registry) { + IConfigurationElement[] extConfigs = registry.getConfigurationElementsFor(WebServerFeatureDescriptor.EXTENSION_ID); + List features = new ArrayList<>(); + for (IConfigurationElement ext : extConfigs) { + if (TAG_FEATURE.equals(ext.getName())) { + features.add( + new WebServerFeatureDescriptor(ext)); + } + } + this.serverFeatures = features + .stream() + .map(DBWFeatureSet::getId) + .toArray(String[]::new); + } + + public String[] getServerFeatures() { + return serverFeatures; + } + +} diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index 665ce1045d..cd50318ad2 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -157,6 +157,7 @@ type ServerConfig { enabledFeatures: [ID!]! disabledBetaFeatures: [ID!] @since(version: "24.0.5") + serverFeatures: [ID!] @since(version: "24.3.0") enabledAuthProviders: [ID!]! supportedLanguages: [ ServerLanguage! ]! services: [ WebServiceConfig ] diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java index 02b99023ec..afd236fc54 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebServerConfig.java @@ -16,14 +16,18 @@ */ package io.cloudbeaver.model; +import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.config.PasswordPolicyConfiguration; +import io.cloudbeaver.registry.WebServerFeatureRegistry; import io.cloudbeaver.registry.WebServiceDescriptor; import io.cloudbeaver.registry.WebServiceRegistry; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; +import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings; +import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; import org.jkiss.dbeaver.registry.language.PlatformLanguageDescriptor; import org.jkiss.dbeaver.registry.language.PlatformLanguageRegistry; import org.jkiss.dbeaver.runtime.DBWorkbench; @@ -39,15 +43,18 @@ */ public class WebServerConfig { - private final CBApplication application; + private final WebApplication application; - public WebServerConfig(CBApplication application) { + public WebServerConfig(@NotNull WebApplication application) { this.application = application; } @Property public String getName() { - return CommonUtils.notEmpty(application.getServerConfiguration().getServerName()); + if (application instanceof CBApplication cbApp) { + return CommonUtils.notEmpty(cbApp.getServerConfiguration().getServerName()); + } + return ""; } @Property @@ -62,7 +69,10 @@ public String getWorkspaceId() { @Property public String getServerURL() { - return CommonUtils.notEmpty(application.getServerConfiguration().getServerURL()); + if (application instanceof CBApplication cbApp) { + return CommonUtils.notEmpty(cbApp.getServerConfiguration().getServerURL()); + } + return ""; } @Property @@ -78,7 +88,10 @@ public String getHostName() { @Property public String getContainerId() { - return CommonUtils.notEmpty(application.getContainerId()); + if (application instanceof CBApplication cbApp) { + return CommonUtils.notEmpty(cbApp.getContainerId()); + } + return ""; } @Property @@ -93,22 +106,34 @@ public boolean isSupportsCustomConnections() { @Property public boolean isSupportsConnectionBrowser() { - return application.getAppConfiguration().isSupportsConnectionBrowser(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().isSupportsConnectionBrowser(); + } + return false; } @Property public boolean isSupportsWorkspaces() { - return application.getAppConfiguration().isSupportsUserWorkspaces(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().isSupportsUserWorkspaces(); + } + return false; } @Property public boolean isPublicCredentialsSaveEnabled() { - return application.getAppConfiguration().isPublicCredentialsSaveEnabled(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().isPublicCredentialsSaveEnabled(); + } + return false; } @Property public boolean isAdminCredentialsSaveEnabled() { - return application.getAppConfiguration().isAdminCredentialsSaveEnabled(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().isAdminCredentialsSaveEnabled(); + } + return false; } @Property @@ -118,12 +143,18 @@ public boolean isLicenseRequired() { @Property public boolean isLicenseValid() { - return application.isLicenseValid(); + if (application instanceof CBApplication cbApp) { + return cbApp.isLicenseValid(); + } + return false; } @Property public String getLicenseStatus() { - return application.getLicenseStatus(); + if (application instanceof CBApplication cbApp) { + return cbApp.getLicenseStatus(); + } + return ""; } @Property @@ -138,7 +169,10 @@ public boolean isDevelopmentMode() { @Property public boolean isRedirectOnFederatedAuth() { - return application.getAppConfiguration().isRedirectOnFederatedAuth(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().isRedirectOnFederatedAuth(); + } + return false; } @Property @@ -148,12 +182,18 @@ public boolean isResourceManagerEnabled() { @Property public long getSessionExpireTime() { - return application.getServerConfiguration().getMaxSessionIdleTime(); + if (application instanceof CBApplication cbApp) { + return cbApp.getServerConfiguration().getMaxSessionIdleTime(); + } + return 0; } @Property public String getLocalHostAddress() { - return application.getLocalHostAddress(); + if (application instanceof CBApplication cbApp) { + return cbApp.getLocalHostAddress(); + } + return ""; } @Property @@ -164,12 +204,24 @@ public String[] getEnabledFeatures() { @Property @Nullable public String[] getDisabledBetaFeatures() { - return application.getAppConfiguration().getDisabledBetaFeatures(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().getDisabledBetaFeatures(); + } + return new String[0]; + } + + @Property + @NotNull + public String[] getServerFeatures() { + return WebServerFeatureRegistry.getInstance().getServerFeatures(); } @Property public String[] getEnabledAuthProviders() { - return application.getAppConfiguration().getEnabledAuthProviders(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().getEnabledAuthProviders(); + } + return new String[0]; } @Property @@ -198,12 +250,18 @@ public Map getProductConfiguration() { @Property public DBNBrowseSettings getDefaultNavigatorSettings() { - return application.getAppConfiguration().getDefaultNavigatorSettings(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().getDefaultNavigatorSettings(); + } + return new DataSourceNavigatorSettings(); } @Property public Map getResourceQuotas() { - return application.getAppConfiguration().getResourceQuotas(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().getResourceQuotas(); + } + return Map.of(); } @Property @@ -213,7 +271,10 @@ public WebProductInfo getProductInfo() { @Property public String[] getDisabledDrivers() { - return application.getAppConfiguration().getDisabledDrivers(); + if (application instanceof CBApplication cbApp) { + return cbApp.getAppConfiguration().getDisabledDrivers(); + } + return new String[0]; } @Property @@ -223,7 +284,10 @@ public Boolean isDistributed() { @Property public String getDefaultAuthRole() { - return application.getDefaultAuthRole(); + if (application instanceof CBApplication cbApp) { + return cbApp.getDefaultAuthRole(); + } + return ""; } @Property @@ -233,6 +297,9 @@ public String getDefaultUserTeam() { @Property public PasswordPolicyConfiguration getPasswordPolicyConfiguration() { - return application.getSecurityManagerConfiguration().getPasswordPolicyConfiguration(); + if (application instanceof CBApplication cbApp) { + return cbApp.getSecurityManagerConfiguration().getPasswordPolicyConfiguration(); + } + return new PasswordPolicyConfiguration(); } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index d2751c20e7..22f0166156 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -76,7 +76,7 @@ public class WebServiceCore implements DBWServiceCore { @Override public WebServerConfig getServerConfig() { - return new WebServerConfig(CBApplication.getInstance()); + return new WebServerConfig(WebAppUtils.getWebApplication()); } @Override