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

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

## 1. Role

### CurrencyRateAPI.getApiKeyService()

This method is a small but critical configuration access routine that retrieves the Exchange Rate API credential from the application classpath at runtime. Its business purpose is to centralize secret resolution so that the rest of `CurrencyRateAPI` can build the external service URL without hard-coding credentials into source code. The method follows a simple resource-loading and delegation pattern: it creates a `Properties` container, opens `config.properties`, loads the file, and returns the `API_KEY` entry.

If the configuration file cannot be found, the method logs an error and returns `null`, preventing downstream URL construction from using an invalid or missing credential. If the file is found but cannot be loaded because of an `IOException`, the method also logs the failure and returns `null`. In this sense, the method acts as a defensive credential gateway and a dependency boundary between application code and runtime configuration. It has no business branching beyond error handling, but it determines whether the API integration can be initialized successfully.

## 2. Processing Pattern (Detailed Business Logic)

```mermaid
flowchart TD
START["getApiKeyService()"]
LOAD["Create Properties instance"]
RESOURCE["Open config.properties from classpath"]
CHECK["input == null?"]
LOG_MISSING["Log error - unable to find config.properties"]
RETURN_NULL_1["Return null"]
LOAD_PROP["Load properties from input stream"]
GET_KEY["Read property API_KEY = \"YOUR_API_KEY\""]
RETURN_KEY["Return API key value"]
CATCH_IO["Catch IOException"]
LOG_IO["Log error - error loading config.properties"]
RETURN_NULL_2["Return null"]
START --> LOAD
LOAD --> RESOURCE
RESOURCE --> CHECK
CHECK -->|Yes| LOG_MISSING
LOG_MISSING --> RETURN_NULL_1
CHECK -->|No| LOAD_PROP
LOAD_PROP --> GET_KEY
GET_KEY --> RETURN_KEY
LOAD_PROP --> CATCH_IO
CATCH_IO --> LOG_IO
LOG_IO --> RETURN_NULL_2
```

The method begins by creating a `Properties` object used as an in-memory container for key/value configuration data. It then attempts to open `config.properties` from the application classpath, which is the externalized runtime source for the Exchange Rate API key. If the resource stream is missing, the method logs the failure and stops immediately by returning `null`. When the resource is available, the method loads the properties file and extracts the `API_KEY` entry, which is the value used by `getURL()` to compose the outbound service endpoint. If loading the file throws an `IOException`, the method logs the exception details and returns `null` as a safe failure outcome.

## 3. Parameter Analysis

| No | Parameter Name | Type | Business Description |
|----|---------------|------|---------------------|
| - | (none) | - | - |

This method takes no parameters. Its behavior is driven by external runtime state: the presence of `config.properties` on the classpath and the `API_KEY` property value inside that file. It also reads the logger instance declared on `CurrencyRateAPI` to record operational failures.

## 4. CRUD Operations / Called Services

This method does not perform database CRUD operations and does not invoke business service components or SC/CBS endpoints. Its only functional dependencies are standard library classes and a properties resource.

| CRUD | SC / CBS | SC Code | Entity / DB | Operation Description |
|------|----------|---------|-------------|----------------------|
| R | `getResourceAsStream` | - | `config.properties` | Reads the application configuration resource from the classpath to locate the external API credential. |
| R | `Properties.load` | - | `config.properties` | Loads key/value pairs from the configuration stream into memory for later lookup. |
| R | `Properties.getProperty` | - | `API_KEY` entry | Reads the configured Exchange Rate API key value from the loaded properties set. |

## 5. Dependency Trace

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

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

Trace who calls this method and what this method ultimately calls.

| # | Caller (Screen/Batch) | Call Chain (Full Path to this Method) | Terminal (SC / CRUD / Entity) |
|---|----------------------|--------------------------------------|-------------------------------|
| 1 | Controller:CurrencyRateAPI | `CurrencyRateAPI.getURL` -> `CurrencyRateAPI.getApiKeyService` | `config.properties [R]` |

`getApiKeyService()` is called by `getURL()` within the same `CurrencyRateAPI` class. The method does not fan out to any internal service layer or external SC/CBS endpoint; instead, it terminates in classpath configuration access. The only downstream dependency is the `config.properties` resource, which supplies the credential value returned to the caller.

## 6. Per-Branch Detail Blocks

**Block 1** — [TRY] `(attempt to open config.properties from classpath)` (L24)

> Opens the configuration resource and prepares to read the API credential.

| # | Type | Code |
|---|------|------|
| 1 | SET | `Properties properties = new Properties();` |
| 2 | EXEC | `getClass().getClassLoader().getResourceAsStream("config.properties");` // load classpath resource |
| 3 | SET | `InputStream input = ...` |

**Block 1.1** — [IF] `(input == null)` (L25)

> Handles the missing configuration file case.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `logger.error("Unable to find config.properties");` // record missing resource |
| 2 | RETURN | `return null;` |

**Block 1.2** — [ELSE] `(input != null)` (L28)

> Loads the properties file and resolves the API key value.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `properties.load(input);` // load key/value pairs from config.properties |
| 2 | RETURN | `return properties.getProperty("API_KEY");` // return configured API key |

**Block 1.3** — [CATCH] `(IOException e)` (L30)

> Handles I/O failure while reading the configuration resource.

| # | Type | Code |
|---|------|------|
| 1 | EXEC | `logger.error("Error loading config.properties", e);` // record load failure |
| 2 | RETURN | `return null;` |

## 7. Glossary

| Term | Type | Business Meaning |
|------|------|------------------|
| `config.properties` | Resource | Application configuration file stored on the classpath; used to supply runtime secrets and integration settings. |
| `API_KEY` | Field | Exchange Rate API credential value used to authenticate outbound requests to the currency-rate service. |
| `Properties` | Technical term | Java key/value container used to load and read configuration entries from a resource file. |
| `classpath` | Technical term | Runtime resource lookup path used to locate packaged configuration files. |
| `InputStream` | Technical term | Stream abstraction used to read the contents of `config.properties`. |
| `IOException` | Technical term | Checked exception indicating a failure while reading the configuration resource. |
| `logger` | Technical term | Application logging facility used to record missing-resource and load-failure events. |
| Exchange Rate API | Business term | External currency exchange service whose URL is assembled using the returned API key. |
| `getURL` | Method | Companion method that builds the final Exchange Rate API endpoint using the credential returned by this method. |
