---

# (DD08) Business Logic — CurrencyRateAPI.getApiKeyService() [14 LOC]

| Field | Value |
|-------|-------|
| Fully Qualified Name | `com.github.blaxk3.api.CurrencyRateAPI` |
| Layer | Utility (Package: `com.github.blaxk3.api`) |
| Module | `api` (Package: `com.github.blaxk3.api`) |

## 1. Role

### CurrencyRateAPI.getApiKeyService()

This method serves as the **API key resolver** for the currency exchange rate service integration. It loads application configuration from the classpath resource `config.properties` and extracts the value of the `API_KEY` property, which is required to authenticate requests to the Exchangerate API (v6.exchangerate-api.com). The method implements a **resource-loaded singleton utility pattern**: it reads a static configuration file on every invocation (no caching), making it a configuration-dependent accessor rather than a cached constant lookup. Its role in the larger system is a foundational dependency — the returned API key is consumed by `getURL()` to construct the authenticated base URL for all downstream exchange rate queries (currency code listing and currency conversion). If the configuration file is missing or an I/O error occurs during loading, the method gracefully returns `null` and logs an error, allowing the failure to propagate upstream to the caller of `getURL()`.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
    START(["getApiKeyService()"])
    A["Initialize Properties object"] --> B{"Is input stream null?"}
    B -->|No| C["Load config.properties into Properties"]
    B -->|Yes| D["Log: Unable to find config.properties"]
    D --> E["Return null"]
    C --> F["Return properties.getProperty(API_KEY)"]
    E --> END(["Return / Next"])
    F --> END
    B -.-> G["Catch IOException"]
    G --> H["Log: Error loading config.properties"]
    H --> I["Return null"]
    I --> END
```

**Processing Summary:**

The method follows a straightforward resource-loading pattern:

1. **Create Properties object** — A new `java.util.Properties` instance is instantiated to hold the key-value pairs from the configuration file.
2. **Open classpath resource stream** — The method attempts to load `config.properties` from the classpath using `getClass().getClassLoader().getResourceAsStream("config.properties")`. The try-with-resources block ensures the input stream is closed automatically.
3. **Null stream check** — If the resource is not found on the classpath, `getResourceAsStream` returns `null`. In this case, an error is logged and `null` is returned.
4. **Load properties** — If the stream is valid, `properties.load(input)` parses the properties file and populates the `Properties` object with key-value pairs.
5. **Extract API_KEY** — `properties.getProperty("API_KEY")` retrieves the value associated with the `API_KEY` key. This value is the Exchangerate API authentication token.
6. **Error handling** — If any `IOException` occurs during file reading, an error is logged with the exception stack trace and `null` is returned.

**CRITICAL — Constant Resolution:**
No external constant classes are referenced in this method. The configuration resource name `"config.properties"` and property key `"API_KEY"` are hardcoded literal strings within the method body.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | This is a no-argument method. It acts as a configuration accessor that retrieves the API authentication key from the application's classpath resource file. |

**Instance fields / external state read:**

| Field | Type | Business Description |
|-------|------|---------------------|
| `this.getClass().getClassLoader()` | ClassLoader | Used to resolve `config.properties` from the application classpath. The method relies on the classloader's ability to find resources at runtime. |

## 4. CRUD Operations / Called Services

This method performs **no database or SC (Service Component) operations**. It only reads from a classpath resource file.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| - | (none) | - | - | No database or SC calls. This method reads a static configuration file (`config.properties`) from the classpath and extracts the `API_KEY` property. |

**Analysis:** This method has zero CRUD operations. It is a pure configuration reader with no interaction with any database tables, entities, or service components. The `logger.error()` calls are side-effect logging only and do not constitute data operations.

## 5. Dependency Trace

### Pre-computed evidence from code analysis graph:

| # | Caller (Screen/Batch) | Call Chain (Full Path to Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|----------------------------------|-------------------------------|
| 1 | Utility:CurrencyRateAPI | `CurrencyRateAPI.getURL` -> `CurrencyRateAPI.getApiKeyService` | - |

**Caller Details:**

The only known caller of `getApiKeyService()` is the sibling method `getURL()` within the same `CurrencyRateAPI` class. `getURL()` concatenates the returned API key with the Exchangerate API base URL (`https://v6.exchangerate-api.com/v6/`) to produce the fully authenticated endpoint URL. Downstream, `getURL()` is consumed by `getCurrencyCode()` and `convert()`, which build specific API endpoint URLs for listing currency codes and performing currency conversion respectively.

## 6. Per-Branch Detail Blocks

**Block 1** — [SET] (L25)

> Initialize the Properties object that will hold the configuration file contents.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Properties properties = new Properties();` // Create empty properties container |

**Block 2** — [TRY-RESOURCE] (L26)

> Attempt to load config.properties from the classpath. The try-with-resources ensures the InputStream is closed after use.

| # | Type | Code |
|---|------|------|
| 1 | SET | `InputStream input = getClass().getClassLoader().getResourceAsStream("config.properties")` // Open classpath resource; returns null if not found |

**Block 3** — [IF] `(input == null)` (L27)

> The configuration file `config.properties` was not found on the classpath. This is an error condition — the application cannot operate without the API key.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `logger.error("Unable to find config.properties")` // Log missing configuration |
| 2 | RETURN | `return null;` // Propagate null to caller; API key unavailable |

**Block 4** — [ELSE: implicit] (L29)

> The input stream was successfully opened. Load the properties file.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `properties.load(input)` // Parse properties file into the Properties object |

**Block 5** — [RETURN] (L30)

> Extract and return the API key value.

| # | Type | Code |
|---|------|------|
| 1 | CALL | `properties.getProperty("API_KEY")` // Retrieve the Exchangerate API authentication token from loaded config |
| 2 | RETURN | `return properties.getProperty("API_KEY");` // Return the API key string, or null if key is not set |

**Block 6** — [CATCH] `(IOException e)` (L31)

> An I/O error occurred while reading the configuration file (e.g., file exists but is unreadable, disk error, or malformed format).

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `logger.error("Error loading config.properties", e)` // Log the error with full exception stack trace |
| 2 | RETURN | `return null;` // Propagate null to caller; API key unavailable due to read error |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `API_KEY` | Field | API authentication key — the Exchangerate API access token required to authenticate REST API requests |
| `config.properties` | Resource | Application configuration file — a Java Properties file loaded from the classpath containing key-value pairs for application settings |
| Exchangerate API | Service | v6.exchangerate-api.com — a third-party REST API that provides real-time and historical foreign exchange currency conversion rates |
| `getURL()` | Method | URL builder — concatenates the API key with the Exchangerate base URL to produce the authenticated endpoint |
| `getCurrencyCode()` | Method | Currency code list — queries the API for all available currency codes from the latest USD conversion rates |
| `convert()` | Method | Currency conversion — queries the API to convert an amount from one currency to another |
| classpath | Technical | Java class loading path — the set of directories and JARs on which the JVM searches for resources like `config.properties` |
| Properties | Technical | Java configuration class — `java.util.Properties` provides a key-value store for loading and accessing `.properties` files |

---
