e2c9cfc1bb6a71ba957b8f2b674491595a232353
hiram
  Fri Jul 24 09:51:39 2026 -0700
refactor the ottoRequest table access with relay requests from Euro/Asia nodes to the RR system refs #31811

diff --git src/hg/hubApi/findGenome.c src/hg/hubApi/findGenome.c
index 292780da6a9..0025898f646 100644
--- src/hg/hubApi/findGenome.c
+++ src/hg/hubApi/findGenome.c
@@ -569,50 +569,46 @@
 /* Require a session cookie.  Robots that have not
  *   passed the challenge will not have one. */
 char *cookieName = hUserCookie();
 char *userId = findCookieData(cookieName);
 if (isEmpty(userId))
     apiErrAbort(err400, err400Msg, "can not find required inputs for endpoint '/assemblyRequest'");
 
 /* the ottoRequest table has no name/betterName columns, fold them into comment */
 struct dyString *fullComment = dyStringNew(0);
 dyStringPrintf(fullComment, "name: '%s'", name);
 if (isNotEmpty(betterName))
     dyStringPrintf(fullComment, "; betterName: '%s'", betterName);
 if (isNotEmpty(comment))
     dyStringPrintf(fullComment, "; comment: '%s'", comment);
 
+/* Record the request in the ottoRequest table (asmId placed in both fromDb
+ * and toDb in case toDb does not allow empty).  Done locally (this host has
+ * hgcentral write grants) or relayed to genome.ucsc.edu (it doesn't) -- see
+ * inUcscEduDomain()/onGenomeRRMachine(). */
+char *ottoStatus;
+if (inUcscEduDomain() && !onGenomeRRMachine())
+    ottoStatus = relaySubmitOttoRequest("assembly", asmId, asmId, email, dyStringContents(fullComment));
+else
+    ottoStatus = submitOttoRequest("assembly", asmId, asmId, email, dyStringContents(fullComment));
+
+if (sameString(ottoStatus, "error"))
+    apiErrAbort(err500, err500Msg, "internal error recording assembly request");
+
 char nowTime[256];
 time_t seconds = clock1();
 struct tm *timeNow = localtime(&seconds);
 strftime(nowTime, sizeof nowTime, "%Y-%m-%d %H:%M:%S", timeNow);
 
 struct dyString *msg = dyStringNew(0);
 dyStringPrintf(msg, "%s\nAssembly request\nasmId: %s\nname: %s\nemail: %s\nbetterName: %s\ncomment: %s",
     nowTime, asmId, name, email,
     isNotEmpty(betterName) ? betterName : "",
     isNotEmpty(comment) ? comment : "");
 
 struct jsonWrite *jw = apiStartOutput();
 jsonWriteString(jw, "msg", dyStringContents(msg));
 apiFinishOutput(0, NULL, jw);
 
-char *ottoTable = cfgOption("ottoTable");        /* probably ottoRequest */
-if (isNotEmpty(ottoTable))
-    {
-    struct sqlConnection *conn = hConnectOtto();
-    if (sqlTableExists(conn, ottoTable))
-        {
-        /* asmId placed in both fromDb and toDb in case toDb does not allow empty */
-        struct dyString *update = dyStringNew(0);
-        sqlDyStringPrintf(update,
-            "INSERT INTO %s (requestType, fromDb, toDb, email, comment, requestTime, status, buildDir) "
-            "VALUES ('assembly', '%s', '%s', '%s', '%s', now(), 0, '')",
-            ottoTable, asmId, asmId, email, dyStringContents(fullComment));
-        sqlUpdate(conn, dyStringCannibalize(&update));
-        }
-    hDisconnectOtto(&conn);
-    }
-
 dyStringFree(&fullComment);
 dyStringFree(&msg);
 }       /*    void apiAssemblyRequest(char *words[MAX_PATH_INFO])    */