devmadhuu commented on code in PR #9915: URL: https://github.com/apache/ozone/pull/9915#discussion_r3333468255
########## hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/chatbot/ChatbotConfigKeys.java: ########## @@ -0,0 +1,196 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.hadoop.ozone.recon.chatbot; + +import org.apache.hadoop.hdds.annotation.InterfaceAudience; +import org.apache.hadoop.hdds.annotation.InterfaceStability; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; + +/** + * Configuration keys for Recon Chatbot service. + */ [email protected] [email protected] +public final class ChatbotConfigKeys { + + public static final String OZONE_RECON_CHATBOT_PREFIX = "ozone.recon.chatbot."; + + // ── Feature toggle ────────────────────────────────────────── + public static final String OZONE_RECON_CHATBOT_ENABLED = OZONE_RECON_CHATBOT_PREFIX + "enabled"; + public static final boolean OZONE_RECON_CHATBOT_ENABLED_DEFAULT = false; + + // ── Provider selection ────────────────────────────────────── + /** + * Active default provider: openai, gemini, anthropic. + */ + public static final String OZONE_RECON_CHATBOT_PROVIDER = OZONE_RECON_CHATBOT_PREFIX + "provider"; + public static final String OZONE_RECON_CHATBOT_PROVIDER_DEFAULT = "gemini"; + + // ── Default model ─────────────────────────────────────────── + public static final String OZONE_RECON_CHATBOT_DEFAULT_MODEL = OZONE_RECON_CHATBOT_PREFIX + "default.model"; + public static final String OZONE_RECON_CHATBOT_DEFAULT_MODEL_DEFAULT = "gemini-2.5-flash"; + + // ── HTTP timeout for provider calls ───────────────────────── + public static final String OZONE_RECON_CHATBOT_TIMEOUT_MS = OZONE_RECON_CHATBOT_PREFIX + "timeout.ms"; + public static final int OZONE_RECON_CHATBOT_TIMEOUT_MS_DEFAULT = 120000; + + // ── Per-provider API keys (resolved via JCEKS / CredentialHelper) ── + public static final String OZONE_RECON_CHATBOT_OPENAI_API_KEY = OZONE_RECON_CHATBOT_PREFIX + "openai.api.key"; + public static final String OZONE_RECON_CHATBOT_GEMINI_API_KEY = OZONE_RECON_CHATBOT_PREFIX + "gemini.api.key"; + public static final String OZONE_RECON_CHATBOT_ANTHROPIC_API_KEY = OZONE_RECON_CHATBOT_PREFIX + + "anthropic.api.key"; + + // ── Per-provider base URL overrides (optional) ────────────── + public static final String OZONE_RECON_CHATBOT_OPENAI_BASE_URL = OZONE_RECON_CHATBOT_PREFIX + "openai.base.url"; + public static final String OZONE_RECON_CHATBOT_OPENAI_BASE_URL_DEFAULT = "https://api.openai.com"; + + // ── Execution policy ──────────────────────────────────────── + public static final String OZONE_RECON_CHATBOT_EXEC_MAX_RECORDS = OZONE_RECON_CHATBOT_PREFIX + + "exec.max.records"; Review Comment: If this is really needed. ########## hadoop-ozone/recon/src/main/java/org/apache/hadoop/ozone/recon/chatbot/agent/ToolExecutor.java: ########## @@ -0,0 +1,373 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.hadoop.ozone.recon.chatbot.agent; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; +import org.apache.commons.lang3.StringUtils; +import org.apache.hadoop.hdds.conf.OzoneConfiguration; +import org.apache.hadoop.hdds.recon.ReconConfigKeys; +import org.apache.hadoop.ozone.recon.chatbot.ChatbotConfigKeys; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Executes tool calls by making HTTP requests to Recon API endpoints. + */ +@Singleton +public class ToolExecutor { + + private static final Logger LOG = + LoggerFactory.getLogger(ToolExecutor.class); + private static final ObjectMapper MAPPER = new ObjectMapper(); + + // We define the specific String suffixes for APIs we want to explicitly watch out for + private static final String LIST_KEYS_ENDPOINT_SUFFIX = "/keys/listKeys"; + + private final String reconBaseUrl; + private final int connectTimeoutMs; + private final int readTimeoutMs; + private final int defaultMaxRecords; // Max records to fetch in total + private final int defaultMaxPages; // Max pages to loop through + private final int defaultPageSize; // Default size of one page + + @Inject + public ToolExecutor(OzoneConfiguration configuration) { + // Resolve the Recon HTTP address from ozone-site.xml (ozone.recon.http-address). + // The configured value is typically "0.0.0.0:9888" (bind address), so we always + // substitute 0.0.0.0 with 127.0.0.1 so the loopback call actually reaches this process. + String rawAddress = configuration.get( + ReconConfigKeys.OZONE_RECON_HTTP_ADDRESS_KEY, + ReconConfigKeys.OZONE_RECON_HTTP_ADDRESS_DEFAULT); + this.reconBaseUrl = "http://" + rawAddress.replace("0.0.0.0", "127.0.0.1"); + + this.connectTimeoutMs = configuration.getInt( + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_CONNECT_TIMEOUT_MS, + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_CONNECT_TIMEOUT_MS_DEFAULT); + this.readTimeoutMs = configuration.getInt( + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_READ_TIMEOUT_MS, + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_READ_TIMEOUT_MS_DEFAULT); + this.defaultMaxRecords = configuration.getInt( + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_MAX_RECORDS, + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_MAX_RECORDS_DEFAULT); + this.defaultMaxPages = configuration.getInt( + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_MAX_PAGES, + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_MAX_PAGES_DEFAULT); + this.defaultPageSize = configuration.getInt( + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_PAGE_SIZE, + ChatbotConfigKeys.OZONE_RECON_CHATBOT_EXEC_PAGE_SIZE_DEFAULT); + + LOG.info("ToolExecutor initialized with Recon URL: {}, connectTimeoutMs={}, " + Review Comment: Pls check if configs are needed in this class to read. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected] --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
