Browse Source
* commit '18a7bf34c1a4d63ecaddf340488472f279ac047f': 无jira任务,修复打包报错 无jira任务,修复打包报错 REPORT-114392 FR-FBP版本本地设计适配 去除模板主题中的frm选项 REPORT-114392 FR-FBP版本本地设计适配 修复数据连接预览 REPORT-114392 FR-FBP版本本地设计适配 修复国际化 REPORT-114392 FR-FBP版本本地设计适配 修复数据连接 REPORT-114392 FR-FBP版本本地设计适配 修复数据连接保存 REPORT-114392 FR-FBP版本本地设计适配 关闭环境监测 REPORT-127453 frm问题处理 REPORT-114391 【微服务适配】远程&本地设计器能够正常启动 修复序列化问题 REPORT-114391 【微服务适配】远程&本地设计器能够正常启动 代码规范 REPORT-114391 【微服务适配】远程&本地设计器能够正常启动 修复图表配置+优化环境切换 REPORT-114391 【微服务适配】远程&本地设计器能够正常启动 优化断开提醒 REPORT-114391 【微服务适配】远程&本地设计器能够正常启动 优化启动与切换fbp-1.0
22 changed files with 441 additions and 66 deletions
@ -0,0 +1,159 @@
|
||||
package com.fr.design; |
||||
|
||||
import com.fr.design.dialog.FineJOptionPane; |
||||
import com.fr.design.i18n.Toolkit; |
||||
import com.fr.design.mainframe.DesignerContext; |
||||
import com.fr.design.ui.util.UIUtil; |
||||
import com.fr.event.Event; |
||||
import com.fr.event.EventDispatcher; |
||||
import com.fr.event.Listener; |
||||
import com.fr.log.FineLoggerFactory; |
||||
import com.fr.stable.StableUtils; |
||||
import com.fr.third.org.apache.http.client.config.RequestConfig; |
||||
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; |
||||
import com.fr.third.org.apache.http.client.methods.HttpGet; |
||||
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; |
||||
import com.fr.third.org.apache.http.impl.client.HttpClients; |
||||
import com.fr.workspace.WorkContext; |
||||
import com.fr.workspace.Workspace; |
||||
import com.fr.workspace.WorkspaceEvent; |
||||
import com.fr.workspace.base.WorkspaceConstants; |
||||
import com.fr.workspace.connect.WorkspaceConnectionInfo; |
||||
import com.fr.workspace.engine.channel.WorkspaceChannelFactory; |
||||
import com.fr.workspace.engine.exception.WorkspaceConnectionException; |
||||
|
||||
import javax.swing.JOptionPane; |
||||
import javax.swing.UIManager; |
||||
|
||||
/** |
||||
* RPC连接处理中心 |
||||
* |
||||
* @author Roger |
||||
* @since 11.0 |
||||
* Created on 2023/12/13 |
||||
*/ |
||||
public class RPCConnectHandlerCenter { |
||||
|
||||
private static volatile boolean alerting = false; |
||||
private static final int TIMEOUT = 5000; |
||||
|
||||
private static Listener<Workspace> listener = new Listener<Workspace>() { |
||||
@Override |
||||
public void on(Event event, Workspace workspace) { |
||||
//暂时先不做重连处理,3次RPC连接失败后提示切换工作目录
|
||||
showRPCDisconnectDialog(); |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* 开启事件监听 |
||||
*/ |
||||
public static void startListener() { |
||||
if (!WorkContext.getCurrent().isLocal()) { |
||||
EventDispatcher.listen(WorkspaceEvent.LostConnect, listener); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 弹窗提示连接断开 |
||||
*/ |
||||
public static void showRPCDisconnectDialog() { |
||||
UIUtil.invokeLaterIfNeeded(RPCConnectHandlerCenter::showDialog); |
||||
} |
||||
|
||||
/** |
||||
* RPC连接测试 |
||||
* |
||||
* @param info 连接信息 |
||||
* @return 是否连接成功 |
||||
*/ |
||||
public static boolean checkRPCConnect(WorkspaceConnectionInfo info) { |
||||
try { |
||||
return WorkspaceChannelFactory.testConnection(info); |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* http连接检测,从DesignerSocketIO中移过来的,先保留着 |
||||
* |
||||
* @param info 连接信息 |
||||
* @return 是否连接成功 |
||||
*/ |
||||
public static boolean checkHttpConnect(WorkspaceConnectionInfo info) { |
||||
CloseableHttpClient httpclient = HttpClients.createDefault(); |
||||
HttpGet httpGet = new HttpGet(StableUtils.pathJoin(info.getUrl(), WorkspaceConstants.CONTROLLER_PREFIX, WorkspaceConstants.VT)); |
||||
RequestConfig requestConfig = RequestConfig |
||||
.custom() |
||||
.setConnectTimeout(TIMEOUT) |
||||
.setConnectionRequestTimeout(TIMEOUT) |
||||
.build(); |
||||
httpGet.setConfig(requestConfig); |
||||
try { |
||||
CloseableHttpResponse response = httpclient.execute(httpGet); |
||||
if (isErrorStatus(response.getStatusLine().getStatusCode())) { |
||||
//这边nginx做负载,服务器被kill掉,返回的是502,不会抛错,导致checkRPCConnect通过
|
||||
//针对500-600的错误码加个判断,其他类型的状态码暂不考虑,如果有遇到再处理,不然怕影响范围大
|
||||
throw new WorkspaceConnectionException("Response " + response.getStatusLine().toString()); |
||||
} |
||||
} catch (Exception e) { |
||||
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||
return false; |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* 提示连接已经断开,如果已经在提示中了就直接返回 |
||||
*/ |
||||
private static void showDialog() { |
||||
if (alerting) { |
||||
return; |
||||
} |
||||
synchronized (RPCConnectHandlerCenter.class) { |
||||
if (alerting) { |
||||
return; |
||||
} |
||||
alerting = true; |
||||
try { |
||||
FineJOptionPane.showMessageDialog( |
||||
DesignerContext.getDesignerFrame(), |
||||
Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"), |
||||
UIManager.getString("OptionPane.messageDialogTitle"), |
||||
JOptionPane.ERROR_MESSAGE, |
||||
UIManager.getIcon("OptionPane.errorIcon")); |
||||
EnvChangeEntrance.getInstance().chooseEnv(); |
||||
} finally { |
||||
alerting = false; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 错误状态码 |
||||
* 5xx(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。代码 说明 |
||||
* 500 (服务器内部错误) 服务器遇到错误,无法完成请求。 |
||||
* 501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。 |
||||
* 502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。 |
||||
* 503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。 |
||||
* 504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。 |
||||
* 505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。 |
||||
* |
||||
* @param status 错误状态码 |
||||
* @return 是否是错误状态码 |
||||
*/ |
||||
private static boolean isErrorStatus(int status) { |
||||
return status >= 500 && status <= 600; |
||||
} |
||||
|
||||
/** |
||||
* 停止事件监听 |
||||
*/ |
||||
public static void stopListener() { |
||||
if (!WorkContext.getCurrent().isLocal()) { |
||||
EventDispatcher.stopListen(listener); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,129 @@
|
||||
package com.fr.design.data.datapane.preview; |
||||
|
||||
import com.fr.data.auth.AuthenticationType; |
||||
import com.fr.data.auth.kerberos.KerberosAuthentication; |
||||
import com.fr.data.auth.kerberos.KerberosUtils; |
||||
import com.fr.data.impl.Connection; |
||||
import com.fr.data.impl.JDBCDatabaseConnection; |
||||
import com.fr.data.impl.NameDatabaseConnection; |
||||
import com.fr.data.pool.DBCPConnectionPoolAttr; |
||||
import com.fr.data.security.ssh.BaseSsh; |
||||
import com.fr.data.security.ssh.SshType; |
||||
import com.fr.data.security.ssh.impl.KeyVerifySsh; |
||||
import com.fr.data.security.ssl.BaseSsl; |
||||
import com.fr.data.security.ssl.SslType; |
||||
import com.fr.data.security.ssl.impl.NormalSsl; |
||||
import com.fr.decision.privilege.TransmissionTool; |
||||
import com.fr.decision.webservice.bean.datasource.ConnectionInfoBean; |
||||
import com.fr.decision.webservice.bean.datasource.JDBCConnectionBean; |
||||
import com.fr.decision.webservice.utils.DecisionServiceConstants; |
||||
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.ConnectionProcessorFactory; |
||||
import com.fr.decision.webservice.v10.datasource.connection.processor.impl.JDBCConnectionProcessor; |
||||
import com.fr.security.encryption.transmission.TransmissionEncryptors; |
||||
import com.fr.stable.StringUtils; |
||||
import com.fr.third.fasterxml.jackson.databind.ObjectMapper; |
||||
|
||||
/** |
||||
* 数据连接传输工具类 |
||||
* |
||||
* @author Destiny.Lin |
||||
* @since 11.0 |
||||
* Created on 2024/7/25 |
||||
*/ |
||||
public class ConnectionInfoBeanHelper { |
||||
private static ObjectMapper objectMapper = new ObjectMapper(); |
||||
|
||||
/** |
||||
* 创建数据连接Bean,可自定义是否携带密码 |
||||
*/ |
||||
public static ConnectionInfoBean createConnectionInfoBean(String name, Connection connection, boolean withPassword) throws Exception { |
||||
if (connection instanceof NameDatabaseConnection) { |
||||
name = ((NameDatabaseConnection) connection).getName(); |
||||
connection = ((NameDatabaseConnection) connection).createDatabase(); |
||||
} |
||||
if (JDBCConnectionProcessor.KEY.acceptConnections().contains(connection.getClass())) { |
||||
ConnectionInfoBean bean = new ConnectionInfoBean(); |
||||
bean.setConnectionData(objectMapper.writeValueAsString(convertToJDBCConnectionBean(connection, withPassword))); |
||||
bean.setConnectionType(JDBCConnectionProcessor.CONNECTION_TYPE); |
||||
bean.setConnectionType(JDBCConnectionProcessor.KEY.getConnectionType(connection)); |
||||
bean.setConnectionName(name); |
||||
bean.setCreator(connection.getCreator()); |
||||
return bean; |
||||
} else { |
||||
return ConnectionProcessorFactory.createConnectionInfoBean(name, connection); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* 创建数据连接Bean,默认携带密码 |
||||
*/ |
||||
public static ConnectionInfoBean createConnectionInfoBean(String name, Connection connection) throws Exception { |
||||
return createConnectionInfoBean(name, connection, true); |
||||
} |
||||
|
||||
/** |
||||
* 创建数据连接bean |
||||
*/ |
||||
public static ConnectionInfoBean createConnectionInfoBean(Connection connection) throws Exception { |
||||
return createConnectionInfoBean(connection.getConnectionName(), connection, true); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* jdbc的特殊处理 |
||||
*/ |
||||
private static JDBCConnectionBean convertToJDBCConnectionBean(Connection connection, boolean withPassword) { |
||||
JDBCDatabaseConnection jdbcConnection = (JDBCDatabaseConnection) connection; |
||||
JDBCConnectionBean jdbcConnectionBean = new JDBCConnectionBean(); |
||||
DBCPConnectionPoolAttr poolAttr = new DBCPConnectionPoolAttr(); |
||||
try { |
||||
poolAttr = (DBCPConnectionPoolAttr) jdbcConnection.getDbcpAttr().clone(); |
||||
} catch (CloneNotSupportedException ignore) { |
||||
} |
||||
poolAttr.setValidationQuery(TransmissionTool.encrypt(poolAttr.getValidationQuery())); |
||||
KerberosAuthentication kerberosAuthentication = null; |
||||
if (jdbcConnection.getAuthentication().type() == AuthenticationType.KERBEROS) { |
||||
//获取数据连接信息的时候,做一下兼容处理(兼容旧的kerberos形式)
|
||||
KerberosUtils.compatibilityProcess(((KerberosAuthentication) jdbcConnection.getAuthentication())); |
||||
kerberosAuthentication = ((KerberosAuthentication) jdbcConnection.getAuthentication()); |
||||
} |
||||
//因为设计器创建连接时database属性为空,所以这里直接取数据库保存的fetchSize值,默认值为-1
|
||||
return jdbcConnectionBean |
||||
.newCharsetName(jdbcConnection.getNewCharsetName()) |
||||
.originalCharsetName(jdbcConnection.getOriginalCharsetName()) |
||||
.database(jdbcConnection.getDatabase()) |
||||
.user(jdbcConnection.getUser()) |
||||
.driver(jdbcConnection.getDriver()) |
||||
// 关键中的关键,由设计器发出的请求如果要携带密码,不能传明文,必须必须必须传加密后的密码
|
||||
.password(withPassword ? TransmissionEncryptors.getInstance().encrypt(jdbcConnection.getPassword()) : DecisionServiceConstants.DEFAULT_PASSWORD) |
||||
.schema(jdbcConnection.getSchema()) |
||||
.url(jdbcConnection.getURL()) |
||||
.creator(jdbcConnection.getCreator()) |
||||
.source(jdbcConnection.getDriverSource()) |
||||
.connectionPoolAttr(poolAttr.create()) |
||||
.authType(kerberosAuthentication != null ? "kerberos" : StringUtils.EMPTY) |
||||
.principal(kerberosAuthentication != null ? kerberosAuthentication.getPrincipal() : StringUtils.EMPTY) |
||||
.keyPath(kerberosAuthentication != null ? kerberosAuthentication.getKeyPath() : StringUtils.EMPTY) |
||||
.krb5Path(kerberosAuthentication != null ? KerberosUtils.getKrb5Path(kerberosAuthentication.getKeyPath(), kerberosAuthentication.getPrincipal()) : StringUtils.EMPTY) |
||||
.useJaas(jdbcConnection.getAuthentication().type() == AuthenticationType.KERBEROS && ((KerberosAuthentication) jdbcConnection.getAuthentication()).getUseJaas()) |
||||
.fetchSize(jdbcConnection.getFetchSize()).identity(connection.getIdentity()) |
||||
.sshType(jdbcConnection.getSsh().getSshType().toString()) |
||||
.sshIp(((BaseSsh) jdbcConnection.getSsh()).getIp()) |
||||
.usingSsh(jdbcConnection.getSsh().isUsingSsh()) |
||||
.sshUser(((BaseSsh) jdbcConnection.getSsh()).getUser()) |
||||
.sshPort(((BaseSsh) jdbcConnection.getSsh()).getPort()) |
||||
.redirectPort(jdbcConnection.getSsh().getRedirectPort()) |
||||
.redirectIp((jdbcConnection.getSsh()).getRedirectIp()) |
||||
.sshTimeOut(((BaseSsh) jdbcConnection.getSsh()).getTimeOut()) |
||||
.sshSecret(withPassword ? ((BaseSsh) jdbcConnection.getSsh()).getSecret() : DecisionServiceConstants.DEFAULT_PASSWORD) |
||||
.sshPrivateKeyPath(jdbcConnection.getSsh().getSshType() == SshType.KEY ? ((KeyVerifySsh) jdbcConnection.getSsh()).getPrivateKeyPath() : StringUtils.EMPTY) |
||||
.usingSsl((jdbcConnection.getSsl()).isUsingSsl()) |
||||
.sslType(jdbcConnection.getSsl().getSslType().toString()) |
||||
.sslClientCertificate(((BaseSsl) jdbcConnection.getSsl()).getClientCertificate()) |
||||
.sslClientPrivateKey(((BaseSsl) jdbcConnection.getSsl()).getClientPrivateKey()) |
||||
.caCertificate(((BaseSsl) jdbcConnection.getSsl()).getCaCertificate()) |
||||
.properties(jdbcConnection.getProperties()) |
||||
.verifyCa(jdbcConnection.getSsl().getSslType() == SslType.NORMAL && ((NormalSsl) jdbcConnection.getSsl()).isVerifyCa()); |
||||
} |
||||
|
||||
} |
Loading…
Reference in new issue