Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d515bde
Introducing Doobie ORM with separate hikari pool
simonredfern Feb 2, 2026
2eab0a1
Fix: doobie import
simonredfern Feb 2, 2026
0e9ada2
Top APIs in v6.0.0 and /system/connectors
simonredfern Feb 3, 2026
f5277df
Connector Method names plus is_available_in_method_routing field
simonredfern Feb 3, 2026
cbe24d8
Adding consumer v6.0.0 and Redis Consumer counters count even if no rate
simonredfern Feb 5, 2026
cf03645
Adding operation_id to metrics. adding v6.0.0 to static resource docs so
simonredfern Feb 5, 2026
9fcd9d9
flushall_fast_build_and_run.sh
simonredfern Feb 8, 2026
c0d91cf
Merge remote-tracking branch 'upstream/develop' into develop
simonredfern Feb 9, 2026
f12097c
flushall_http4s_build_and_run.sh
simonredfern Feb 9, 2026
5918213
fix test using v6.0.0 getBanks PostApiCollection Endpoint
simonredfern Feb 9, 2026
bc43b07
Adding product_id
simonredfern Feb 9, 2026
5ae3cbc
increase MaxMetaspaceSize for build
Feb 9, 2026
30cbb7a
Adding API Product, Product gets product_id Connector Metrics and
simonredfern Feb 9, 2026
f229963
API Products, Products add product_id, Connector Metrics, Connector
simonredfern Feb 9, 2026
bf64eef
Products and API Products tags / user auth message
simonredfern Feb 10, 2026
a98cc78
"reverting" addtion of product_id
simonredfern Feb 10, 2026
ca17afa
Redis Connector call counters
simonredfern Feb 10, 2026
222b652
Added TODO about correlation_id in connector metrics
simonredfern Feb 10, 2026
6ec418f
Cleanup: Removed v6.0.0 Get Products and Get Product as they are
simonredfern Feb 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build_container.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ jobs:
echo ResetPasswordUrlEnabled=true >> obp-api/src/main/resources/props/test.default.props

echo consents.allowed=true >> obp-api/src/main/resources/props/test.default.props
MAVEN_OPTS="-Xmx3G -Xss2m" mvn clean package -Pprod 2>&1 | tee maven-build.log
MAVEN_OPTS="-Xmx3G -Xss2m -XX:MaxMetaspaceSize=1024M" mvn clean package -Pprod 2>&1 | tee maven-build.log

- name: Report failing tests (if any)
if: always()
Expand Down
120 changes: 120 additions & 0 deletions flushall_fast_build_and_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
#!/bin/bash

# Fast build script - skips clean, uses parallel builds, more RAM
#
# This script should be run from the OBP-API root directory:
# cd /path/to/OBP-API
# ./flushall_fast_build_and_run.sh
#
# Options:
# --clean Force a clean build (slower, but useful if you have issues)
# --offline Skip checking remote repos (faster if deps haven't changed)
#
# The http4s server will run in the background on port 8081
# The Jetty server will run in the foreground on port 8080

set -e # Exit on error

# Parse arguments
DO_CLEAN=""
OFFLINE_FLAG=""
for arg in "$@"; do
case $arg in
--clean)
DO_CLEAN="clean"
echo ">>> Clean build requested"
;;
--offline)
OFFLINE_FLAG="-o"
echo ">>> Offline mode enabled"
;;
esac
done

# Detect CPU cores for parallel builds
if command -v nproc &> /dev/null; then
CORES=$(nproc)
elif command -v sysctl &> /dev/null; then
CORES=$(sysctl -n hw.ncpu)
else
CORES=4
fi
echo ">>> Using $CORES CPU cores for parallel builds"

# Common Maven options for better performance
# - More heap memory (4G-8G)
# - More metaspace (2G)
# - Larger stack for Scala compiler
# - Java module opens for compatibility
export MAVEN_OPTS="-Xms4G -Xmx8G -XX:MaxMetaspaceSize=2G -Xss128m \
--add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.lang.invoke=ALL-UNNAMED \
--add-opens java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED"

echo "=========================================="
echo "Flushing Redis cache..."
echo "=========================================="
redis-cli <<EOF
flushall
exit
EOF

if [ $? -eq 0 ]; then
echo "Redis cache flushed successfully"
else
echo "Warning: Failed to flush Redis cache. Continuing anyway..."
fi

echo ""
echo "=========================================="
echo "Fast build: installing commons + packaging http4s runner..."
echo "=========================================="

# Build everything needed in ONE Maven invocation:
# - Install root pom and obp-commons first
# - Then package obp-http4s-runner (which depends on obp-api)
#
# Optimizations:
# - -T 1C: Use 1 thread per CPU core
# - No 'clean' by default (incremental build)
# - -DskipTests: Skip running tests
# - -Dmaven.test.skip: Skip compiling tests too
# - $OFFLINE_FLAG: Skip remote repo checks if --offline passed

mvn install -pl .,obp-commons \
-T 1C \
$OFFLINE_FLAG \
-DskipTests=true \
-Dmaven.test.skip=true \
-Dcheckstyle.skip=true \
-Dspotbugs.skip=true \
-Dpmd.skip=true

mvn package -pl obp-http4s-runner -am \
-T 1C \
$DO_CLEAN \
$OFFLINE_FLAG \
-DskipTests=true \
-Dmaven.test.skip=true \
-Dcheckstyle.skip=true \
-Dspotbugs.skip=true \
-Dpmd.skip=true

echo ""
echo "=========================================="
echo "Starting http4s server in background..."
echo "=========================================="
java -jar obp-http4s-runner/target/obp-http4s-runner.jar > http4s-server.log 2>&1 &
HTTP4S_PID=$!
echo "http4s server started with PID: $HTTP4S_PID (port 8081)"
echo "Logs are being written to: http4s-server.log"
echo ""
echo "To stop http4s server later: kill $HTTP4S_PID"
echo ""

echo "=========================================="
echo "Starting Jetty server (foreground)..."
echo "=========================================="
mvn jetty:run -pl obp-api $OFFLINE_FLAG
46 changes: 46 additions & 0 deletions flushall_http4s_build_and_run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#!/bin/bash

# Script to flush Redis, build the project, and run the http4s server
#
# This script should be run from the OBP-API root directory:
# cd /path/to/OBP-API
# ./flushall_http4s_build_and_run.sh
#
# The http4s server will run in the foreground on the port configured
# in your props file (default: 8086)

set -e # Exit on error

echo "=========================================="
echo "Flushing Redis cache..."
echo "=========================================="
redis-cli <<EOF
flushall
exit
EOF

if [ $? -eq 0 ]; then
echo "Redis cache flushed successfully"
else
echo "Warning: Failed to flush Redis cache. Continuing anyway..."
fi

echo ""
echo "=========================================="
echo "Building with Maven..."
echo "=========================================="
export MAVEN_OPTS="-Xms3G -Xmx6G -XX:MaxMetaspaceSize=2G"
mvn -pl obp-http4s-runner -am clean package -DskipTests=true -Dmaven.test.skip=true

echo ""
echo "=========================================="
echo "Starting http4s server (foreground)..."
echo "=========================================="
java \
--add-opens java.base/java.lang=ALL-UNNAMED \
--add-opens java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens java.base/java.util=ALL-UNNAMED \
--add-opens java.base/java.lang.invoke=ALL-UNNAMED \
--add-opens java.base/java.util.jar=ALL-UNNAMED \
--add-opens java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED \
-jar obp-http4s-runner/target/obp-http4s-runner.jar
13 changes: 13 additions & 0 deletions obp-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,19 @@
</exclusion>
</exclusions>
</dependency>

<!-- Doobie - Pure functional JDBC layer for raw SQL queries -->
<!-- Handles all JDBC types correctly (including SQL Server NVARCHAR) -->
<dependency>
<groupId>org.tpolecat</groupId>
<artifactId>doobie-core_${scala.version}</artifactId>
<version>1.0.0-RC4</version>
</dependency>
<dependency>
<groupId>org.tpolecat</groupId>
<artifactId>doobie-hikari_${scala.version}</artifactId>
<version>1.0.0-RC4</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
Expand Down
5 changes: 3 additions & 2 deletions obp-api/src/main/resources/props/sample.props.template
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ supported_locales = en_GB,es_ES,ro_RO
apiOptions.getBranchesIsPublic = true
apiOptions.getAtmsIsPublic = true
apiOptions.getProductsIsPublic = true
apiOptions.getApiProductsIsPublic = true
apiOptions.getTransactionTypesIsPublic = true
apiOptions.getCurrentFxRateIsPublic = true

Expand Down Expand Up @@ -1613,7 +1614,7 @@ ethereum.rpc.url=http://127.0.0.1:8545


##########################################################
# Redis Logging #
# Redis Logging Log Cache #
##########################################################
## Enable Redis logging (true/false)
redis_logging_enabled = false
Expand Down Expand Up @@ -1701,4 +1702,4 @@ securelogging_mask_email=true
# Host and port for http4s server (used by bootstrap.http4s.Http4sServer)
# Defaults (if not set) are 127.0.0.1 and 8086
http4s.host=127.0.0.1
http4s.port=8086
http4s.port=8086
4 changes: 4 additions & 0 deletions obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ import code.api.util._
import code.api.util.migration.Migration
import code.api.util.migration.Migration.DbFunction
import code.apicollection.ApiCollection
import code.apiproduct.ApiProduct
import code.apiproductattribute.ApiProductAttribute
import code.featuredapicollection.FeaturedApiCollection
import code.apicollectionendpoint.ApiCollectionEndpoint
import code.atmattribute.AtmAttribute
Expand Down Expand Up @@ -1119,6 +1121,8 @@ object ToSchemify {
MappedUserRefreshes,
ApiCollection,
ApiCollectionEndpoint,
ApiProduct,
ApiProductAttribute,
FeaturedApiCollection,
JsonSchemaValidation,
AuthenticationTypeValidation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2870,6 +2870,26 @@ object SwaggerDefinitionsJSON {
created = DateWithDayExampleObject,
logo_url = Some(logoURLExample.value)
)

lazy val consumerJsonV600: ConsumerJsonV600 = ConsumerJsonV600(
consumer_id = consumerIdExample.value,
consumer_key = consumerKeyExample.value,
app_name = appNameExample.value,
app_type = appTypeExample.value,
description = descriptionExample.value,
developer_email = emailExample.value,
company = companyExample.value,
redirect_url = redirectUrlExample.value,
certificate_pem = pem,
certificate_info = Some(certificateInfoJsonV510),
created_by_user = resourceUserJSON,
enabled = true,
created = DateWithDayExampleObject,
logo_url = Some(logoURLExample.value),
active_rate_limits = activeRateLimitsJsonV600,
call_counters = redisCallCountersJsonV600
)

lazy val consumerJsonOnlyForPostResponseV510: ConsumerJsonOnlyForPostResponseV510 = ConsumerJsonOnlyForPostResponseV510(
consumer_id = consumerIdExample.value,
consumer_key = consumerKeyExample.value,
Expand Down Expand Up @@ -3068,6 +3088,27 @@ object SwaggerDefinitionsJSON {
lazy val metricsJsonV510 = MetricsJsonV510(
metrics = List(metricJson510)
)
lazy val metricJsonV600 = MetricJsonV600(
user_id = ExampleValue.userIdExample.value,
url = "www.openbankproject.com",
date = DateWithDayExampleObject,
user_name = "OBP",
app_name = "SOFI",
developer_email = ExampleValue.emailExample.value,
implemented_by_partial_function = "getBanks",
implemented_in_version = "v210",
consumer_id = "123",
verb = "get",
correlation_id = "v8ho6h5ivel3uq7a5zcnv0w1",
duration = 39,
source_ip = "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b",
target_ip = "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b",
response_body = json.parse("""{"code":401,"message":"OBP-20001: User not logged in. Authentication is required!"}"""),
operation_id = "OBPv4.0.0-getBanks"
)
lazy val metricsJsonV600 = MetricsJsonV600(
metrics = List(metricJsonV600)
)

lazy val branchJsonPut = BranchJsonPutV210("gh.29.fi", "OBP",
addressJsonV140,
Expand Down Expand Up @@ -5182,6 +5223,44 @@ object SwaggerDefinitionsJSON {
lazy val featuredApiCollectionJsonV600 = FeaturedApiCollectionJsonV600(featuredApiCollectionIdExample.value, apiCollectionIdExample.value, 1)
lazy val featuredApiCollectionsJsonV600 = FeaturedApiCollectionsJsonV600(List(featuredApiCollectionJsonV600))

// Api Product (v6.0.0)
lazy val apiProductAttributeResponseJsonV600 = ApiProductAttributeResponseJsonV600(
bank_id = bankIdExample.value,
api_product_code = productCodeExample.value,
api_product_attribute_id = "api-product-attribute-id-123",
name = "OVERDRAFT_LIMIT",
`type` = "STRING",
value = "10000",
is_active = Some(true)
)
lazy val apiProductAttributeJsonV600 = ApiProductAttributeJsonV600(
name = "OVERDRAFT_LIMIT",
`type` = "STRING",
value = "10000",
is_active = Some(true)
)
lazy val postPutApiProductJsonV600 = PostPutApiProductJsonV600(
parent_api_product_code = Some(""),
name = "ApiProduct1",
category = Some("category1"),
more_info_url = Some("https://example.com/more-info"),
terms_and_conditions_url = Some("https://example.com/terms"),
description = Some("Description of the product")
)
lazy val apiProductJsonV600 = ApiProductJsonV600(
api_product_id = "api-product-id-123",
bank_id = bankIdExample.value,
api_product_code = productCodeExample.value,
parent_api_product_code = "",
name = "ApiProduct1",
category = "category1",
more_info_url = "https://example.com/more-info",
terms_and_conditions_url = "https://example.com/terms",
description = "Description of the product",
attributes = Some(List(apiProductAttributeResponseJsonV600))
)
lazy val apiProductsJsonV600 = ApiProductsJsonV600(List(apiProductJsonV600))

lazy val jsonScalaConnectorMethod = JsonConnectorMethod(Some(connectorMethodIdExample.value),"getBank", connectorMethodBodyScalaExample.value, "Scala")
lazy val jsonScalaConnectorMethodMethodBody = JsonConnectorMethodMethodBody(connectorMethodBodyScalaExample.value, "Scala")

Expand Down
3 changes: 3 additions & 0 deletions obp-api/src/main/scala/code/api/cache/Redis.scala
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ object Redis extends MdcLoggable {
jedisConnection.head.del(key).toString
}else if (method ==JedisMethod.GET) {
jedisConnection.head.get(key)
} else if (method == JedisMethod.SCAN) {
import scala.collection.JavaConverters._
jedisConnection.head.keys(key).asScala.mkString(",")
} else if(method ==JedisMethod.SET && value.isDefined){
if (ttlSeconds.isDefined) {//if set ttl, call `setex` method to set the expired seconds.
jedisConnection.head.setex(key, ttlSeconds.get, value.get).toString
Expand Down
10 changes: 9 additions & 1 deletion obp-api/src/main/scala/code/api/constant/constant.scala
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ object Constant extends MdcLoggable {
final val METRICS_STABLE_NAMESPACE = "metrics_stable"
final val METRICS_RECENT_NAMESPACE = "metrics_recent"
final val ABAC_RULE_NAMESPACE = "abac_rule"
final val CONNECTOR_OUTBOUND_NAMESPACE = "connector_outbound"
final val CONNECTOR_INBOUND_NAMESPACE = "connector_inbound"

// List of all versioned cache namespaces
final val ALL_CACHE_NAMESPACES = List(
Expand All @@ -234,7 +236,9 @@ object Constant extends MdcLoggable {
CONNECTOR_NAMESPACE,
METRICS_STABLE_NAMESPACE,
METRICS_RECENT_NAMESPACE,
ABAC_RULE_NAMESPACE
ABAC_RULE_NAMESPACE,
CONNECTOR_OUTBOUND_NAMESPACE,
CONNECTOR_INBOUND_NAMESPACE
)

// Cache key prefixes with global namespace and versioning for easy invalidation
Expand Down Expand Up @@ -266,6 +270,10 @@ object Constant extends MdcLoggable {
// ABAC Cache Prefixes (with global namespace and versioning)
def ABAC_RULE_PREFIX: String = getVersionedCachePrefix(ABAC_RULE_NAMESPACE)

// Connector Metrics Redis Counter Prefixes (with global namespace and versioning)
def CONNECTOR_OUTBOUND_PREFIX: String = getVersionedCachePrefix(CONNECTOR_OUTBOUND_NAMESPACE)
def CONNECTOR_INBOUND_PREFIX: String = getVersionedCachePrefix(CONNECTOR_INBOUND_NAMESPACE)

// ABAC Policy Constants
final val ABAC_POLICY_ACCOUNT_ACCESS = "account-access"

Expand Down
Loading
Loading