| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388 |
- import java.sql.*;
- import java.util.*;
- /**
- * Verify effective lobster execution policy for a tenant + company.
- * Mirrors LobsterExecutionPolicyService.resolve merge logic.
- */
- public class VerifyLobsterExecutionPolicy {
- private static final String HOST = "cq-cdb-8fjmemkb.sql.tencentcdb.com";
- private static final int PORT = 27220;
- private static final String MASTER_USER = "root";
- private static final String MASTER_PWD = "Ylrz_1q2w3e4r5t6y";
- private static final String MASTER = "ylrz_saas";
- private static final long TENANT_ID = 33L;
- private static final long COMPANY_ID = 338L;
- public static void main(String[] args) throws Exception {
- long tenantId = args.length > 0 ? Long.parseLong(args[0]) : TENANT_ID;
- long companyId = args.length > 1 ? Long.parseLong(args[1]) : COMPANY_ID;
- TenantDb tenant = resolveTenantDb(tenantId);
- System.out.println("=== Tenant " + tenantId + " db=" + tenant.database + " companyId=" + companyId + " ===\n");
- try (Connection c = connect(tenant.database, tenant.user, tenant.password)) {
- printGlobalConfig(c);
- printTaskCopies(c, companyId);
- printTagBindings(c, companyId);
- printEffectivePolicies(c, companyId);
- printSupplementary(c, companyId);
- }
- }
- private static void printSupplementary(Connection c, long companyId) throws SQLException {
- System.out.println("--- Supplementary stats ---");
- runQuery(c, "tag rel by template_id",
- "SELECT template_id, COUNT(*) cnt FROM company_lobster_tag_user_rel "
- + "WHERE company_id=? AND del_flag=0 GROUP BY template_id ORDER BY cnt DESC LIMIT 10", companyId);
- runQuery(c, "instance by status",
- "SELECT status, COUNT(*) cnt FROM lobster_workflow_instance "
- + "WHERE company_id=? GROUP BY status", companyId);
- runQuery(c, "tag-template bindings",
- "SELECT id, tag_code, task_template_id, status FROM company_tag_template_binding "
- + "WHERE company_id=? AND del_flag=0 ORDER BY id DESC LIMIT 8", companyId);
- }
- private static void runQuery(Connection c, String label, String sql, long companyId) throws SQLException {
- System.out.println("[" + label + "]");
- if (!tableExists(c, sql.contains("company_lobster_tag_user_rel") ? "company_lobster_tag_user_rel"
- : sql.contains("lobster_workflow_instance") ? "lobster_workflow_instance"
- : "company_tag_template_binding")) {
- System.out.println(" (table missing)");
- return;
- }
- try (PreparedStatement ps = c.prepareStatement(sql)) {
- ps.setLong(1, companyId);
- try (ResultSet rs = ps.executeQuery()) {
- int n = 0;
- while (rs.next()) {
- n++;
- printRow(rs);
- }
- if (n == 0) System.out.println(" (empty)");
- }
- }
- System.out.println();
- }
- private static void printGlobalConfig(Connection c) throws SQLException {
- System.out.println("--- lobster_execution_config (tenant-global, company_id=0) ---");
- if (!tableExists(c, "lobster_execution_config")) {
- System.out.println("(table missing -> code defaults: HYBRID, autoStart=true)\n");
- return;
- }
- String sql = "SELECT id, company_id, default_execution_mode, auto_start_instance_on_tag, "
- + "quality_gate_enabled, quality_pass_score_percent, message_dedup_enabled, update_time "
- + "FROM lobster_execution_config WHERE company_id=0 LIMIT 1";
- try (Statement st = c.createStatement(); ResultSet rs = st.executeQuery(sql)) {
- if (!rs.next()) {
- System.out.println("(no row -> code defaults: HYBRID, autoStart=true)\n");
- return;
- }
- printRow(rs);
- }
- System.out.println();
- }
- private static void printTaskCopies(Connection c, long companyId) throws SQLException {
- System.out.println("--- company_workflow_lobster task_copy (company_id=" + companyId + ") ---");
- if (!tableExists(c, "company_workflow_lobster")) {
- System.out.println("(table missing)\n");
- return;
- }
- String sql = "SELECT id, template_name, template_kind, status, execution_mode, "
- + "enable_content_personalization, enable_flow_personalization, "
- + "strict_fixed_workflow, auto_start_instance_on_tag, source_template_id, update_time "
- + "FROM company_workflow_lobster "
- + "WHERE company_id=? AND del_flag=0 AND template_kind='task_copy' "
- + "ORDER BY update_time DESC LIMIT 20";
- try (PreparedStatement ps = c.prepareStatement(sql)) {
- ps.setLong(1, companyId);
- try (ResultSet rs = ps.executeQuery()) {
- int n = 0;
- while (rs.next()) {
- n++;
- System.out.println("#" + n + " id=" + rs.getLong("id")
- + " name=" + rs.getString("template_name")
- + " status=" + rs.getInt("status"));
- System.out.println(" execution_mode=" + nv(rs.getString("execution_mode"))
- + " contentPers=" + nv(rs.getObject("enable_content_personalization"))
- + " flowPers=" + nv(rs.getObject("enable_flow_personalization"))
- + " strict=" + nv(rs.getObject("strict_fixed_workflow"))
- + " autoStart=" + nv(rs.getObject("auto_start_instance_on_tag")));
- System.out.println(" source_template_id=" + nv(rs.getObject("source_template_id"))
- + " updated=" + rs.getTimestamp("update_time"));
- }
- if (n == 0) System.out.println("(no task_copy rows)");
- }
- }
- System.out.println();
- }
- private static void printTagBindings(Connection c, long companyId) throws SQLException {
- System.out.println("--- company_lobster_tag_user_rel (sample bindings, company_id=" + companyId + ") ---");
- if (!tableExists(c, "company_lobster_tag_user_rel")) {
- System.out.println("(table missing)\n");
- return;
- }
- String sql = "SELECT rel.id, rel.template_id, rel.binding_id, rel.tag_code, rel.channel_type, "
- + "rel.channel_contact_id, wf.template_name, wf.execution_mode, wf.strict_fixed_workflow "
- + "FROM company_lobster_tag_user_rel rel "
- + "LEFT JOIN company_workflow_lobster wf ON wf.id=rel.template_id AND wf.company_id=rel.company_id "
- + "WHERE rel.company_id=? AND rel.del_flag=0 "
- + "ORDER BY rel.id DESC LIMIT 10";
- try (PreparedStatement ps = c.prepareStatement(sql)) {
- ps.setLong(1, companyId);
- try (ResultSet rs = ps.executeQuery()) {
- int n = 0;
- while (rs.next()) {
- n++;
- System.out.println("rel#" + rs.getLong("id")
- + " template_id=" + rs.getLong("template_id")
- + " binding_id=" + nv(rs.getObject("binding_id"))
- + " tag=" + rs.getString("tag_code")
- + " contact=" + rs.getLong("channel_contact_id"));
- System.out.println(" wf=" + nv(rs.getString("template_name"))
- + " wf.execution_mode=" + nv(rs.getString("execution_mode"))
- + " strict=" + nv(rs.getObject("strict_fixed_workflow")));
- }
- if (n == 0) System.out.println("(no tag-user rel rows)");
- }
- }
- System.out.println();
- }
- private static void printEffectivePolicies(Connection c, long companyId) throws SQLException {
- System.out.println("--- Effective policy (LobsterExecutionPolicyService.resolve logic) ---");
- Global g = loadGlobal(c);
- List<TaskCopy> copies = loadTaskCopies(c, companyId);
- System.out.println("Global baseline:");
- System.out.println(" executionMode=" + g.mode + " autoStartInstanceOnTag=" + g.autoStart
- + " qualityGate=" + g.qualityGate);
- System.out.println("\nPer task_copy (templateId -> merged effective):");
- if (copies.isEmpty()) {
- Policy p = merge(g, null);
- printPolicy("(no template / prompt-only contacts)", p);
- } else {
- for (TaskCopy tc : copies) {
- Policy p = merge(g, tc);
- printPolicy("templateId=" + tc.id + " \"" + tc.name + "\"", p);
- }
- }
- System.out.println("\nOrchestrator routing summary:");
- if (copies.isEmpty()) {
- Policy p = merge(g, null);
- System.out.println(" [unbound] preferInstance=" + p.preferInstance()
- + " allowPromptFallback=" + p.allowPromptFallback()
- + " allowFlow=" + p.allowFlow
- + " allowContent=" + p.allowContent
- + " -> " + describeRoute(p));
- } else {
- for (TaskCopy tc : copies) {
- Policy p = merge(g, tc);
- System.out.println(" [templateId=" + tc.id + "] preferInstance=" + p.preferInstance()
- + " allowPromptFallback=" + p.allowPromptFallback()
- + " allowFlow=" + p.allowFlow
- + " allowContent=" + p.allowContent
- + " -> " + describeRoute(p));
- }
- Policy unbound = merge(g, null);
- System.out.println(" [unbound/no tag rel] preferInstance=" + unbound.preferInstance()
- + " allowPromptFallback=" + unbound.allowPromptFallback()
- + " -> " + describeRoute(unbound));
- }
- }
- private static String describeRoute(Policy p) {
- if (p.strict) {
- return "INSTANCE-only (strict fixed, no prompt fallback, no flow personalization)";
- }
- switch (p.mode) {
- case "HYBRID":
- return "try instance first (autoStart=" + p.autoStart + "), else PROMPT chat fallback";
- case "INSTANCE":
- return "INSTANCE only; prompt fallback only if instance path fails";
- case "PROMPT":
- return "PROMPT chat only, no instance path";
- default:
- return p.mode;
- }
- }
- private static void printPolicy(String label, Policy p) {
- System.out.println(" " + label);
- System.out.println(" mode=" + p.mode + " strict=" + p.strict
- + " autoStart=" + p.autoStart
- + " contentPers=" + p.allowContent + " flowPers=" + p.allowFlow);
- }
- private static Global loadGlobal(Connection c) throws SQLException {
- Global g = new Global();
- g.mode = "HYBRID";
- g.autoStart = true;
- g.qualityGate = true;
- if (!tableExists(c, "lobster_execution_config")) return g;
- String sql = "SELECT default_execution_mode, auto_start_instance_on_tag, quality_gate_enabled "
- + "FROM lobster_execution_config WHERE company_id=0 LIMIT 1";
- try (Statement st = c.createStatement(); ResultSet rs = st.executeQuery(sql)) {
- if (rs.next()) {
- if (rs.getString("default_execution_mode") != null && !rs.getString("default_execution_mode").isBlank()) {
- g.mode = rs.getString("default_execution_mode").trim().toUpperCase();
- }
- g.autoStart = intToBool(rs.getObject("auto_start_instance_on_tag"), true);
- g.qualityGate = intToBool(rs.getObject("quality_gate_enabled"), true);
- }
- }
- return g;
- }
- private static List<TaskCopy> loadTaskCopies(Connection c, long companyId) throws SQLException {
- List<TaskCopy> list = new ArrayList<>();
- if (!tableExists(c, "company_workflow_lobster")) return list;
- String sql = "SELECT id, template_name, execution_mode, enable_content_personalization, "
- + "enable_flow_personalization, strict_fixed_workflow, auto_start_instance_on_tag "
- + "FROM company_workflow_lobster "
- + "WHERE company_id=? AND del_flag=0 AND template_kind='task_copy' AND status=1 "
- + "ORDER BY update_time DESC";
- try (PreparedStatement ps = c.prepareStatement(sql)) {
- ps.setLong(1, companyId);
- try (ResultSet rs = ps.executeQuery()) {
- while (rs.next()) {
- TaskCopy t = new TaskCopy();
- t.id = rs.getLong("id");
- t.name = rs.getString("template_name");
- t.executionMode = rs.getString("execution_mode");
- t.contentPers = (Integer) rs.getObject("enable_content_personalization");
- t.flowPers = (Integer) rs.getObject("enable_flow_personalization");
- t.strict = (Integer) rs.getObject("strict_fixed_workflow");
- t.autoStart = (Integer) rs.getObject("auto_start_instance_on_tag");
- list.add(t);
- }
- }
- }
- return list;
- }
- private static Policy merge(Global g, TaskCopy tc) {
- Policy p = new Policy();
- p.mode = g.mode;
- p.autoStart = g.autoStart;
- p.allowContent = true;
- p.allowFlow = true;
- p.strict = false;
- if (tc != null) {
- if (tc.executionMode != null && !tc.executionMode.isBlank()) {
- p.mode = tc.executionMode.trim().toUpperCase();
- }
- if (tc.contentPers != null) p.allowContent = intToBool(tc.contentPers, true);
- if (tc.flowPers != null) p.allowFlow = intToBool(tc.flowPers, true);
- if (tc.strict != null) p.strict = intToBool(tc.strict, false);
- if (tc.autoStart != null) p.autoStart = intToBool(tc.autoStart, false);
- }
- if (p.strict) {
- p.allowFlow = false;
- if ("PROMPT".equals(p.mode)) p.mode = "INSTANCE";
- }
- return p;
- }
- private static boolean intToBool(Object v, boolean def) {
- if (v == null) return def;
- if (v instanceof Number) return ((Number) v).intValue() != 0;
- return Boolean.parseBoolean(v.toString());
- }
- private static String nv(Object o) {
- return o == null ? "null(inherit)" : String.valueOf(o);
- }
- private static void printRow(ResultSet rs) throws SQLException {
- ResultSetMetaData md = rs.getMetaData();
- for (int i = 1; i <= md.getColumnCount(); i++) {
- if (i > 1) System.out.print(" | ");
- System.out.print(md.getColumnLabel(i) + "=" + rs.getObject(i));
- }
- System.out.println();
- }
- private static boolean tableExists(Connection c, String table) throws SQLException {
- try (PreparedStatement ps = c.prepareStatement(
- "SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?")) {
- ps.setString(1, table);
- try (ResultSet rs = ps.executeQuery()) {
- return rs.next() && rs.getInt(1) > 0;
- }
- }
- }
- private static TenantDb resolveTenantDb(long tenantId) throws SQLException {
- try (Connection master = connect(MASTER, MASTER_USER, MASTER_PWD);
- PreparedStatement ps = master.prepareStatement(
- "SELECT db_url, db_account, db_pwd FROM tenant_info WHERE id=?")) {
- ps.setLong(1, tenantId);
- try (ResultSet rs = ps.executeQuery()) {
- if (!rs.next()) throw new IllegalStateException("tenant_info id=" + tenantId + " not found");
- return parseJdbcUrl(rs.getString("db_url"), rs.getString("db_account"), rs.getString("db_pwd"));
- }
- }
- }
- private static Connection connect(String db, String user, String pwd) throws SQLException {
- return DriverManager.getConnection(
- "jdbc:mysql://" + HOST + ":" + PORT + "/" + db
- + "?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true",
- user, pwd);
- }
- private static TenantDb parseJdbcUrl(String jdbcUrl, String user, String password) {
- String body = jdbcUrl.substring("jdbc:mysql://".length());
- int slash = body.indexOf('/');
- int q = body.indexOf('?');
- String hostPort = body.substring(0, slash);
- String database = body.substring(slash + 1, q > 0 ? q : body.length());
- TenantDb t = new TenantDb();
- t.database = database;
- t.user = user;
- t.password = password;
- return t;
- }
- static class TenantDb {
- String database, user, password;
- }
- static class Global {
- String mode = "HYBRID";
- boolean autoStart = true;
- boolean qualityGate = true;
- }
- static class TaskCopy {
- long id;
- String name;
- String executionMode;
- Integer contentPers, flowPers, strict, autoStart;
- }
- static class Policy {
- String mode;
- boolean strict, autoStart, allowContent, allowFlow;
- boolean preferInstance() {
- if (strict) return true;
- return "INSTANCE".equals(mode) || "HYBRID".equals(mode);
- }
- boolean allowPromptFallback() {
- if (strict) return false;
- return "PROMPT".equals(mode) || "HYBRID".equals(mode);
- }
- }
- }
|