Skip to content

Commit

Permalink
Fix #884: clearing the cache of the push client works only on one node (
Browse files Browse the repository at this point in the history
#885)

* Fix #884: clearing the cache of the push client works only on one node
  • Loading branch information
banterCZ authored Oct 15, 2024
1 parent efef6c6 commit 1d97c3c
Show file tree
Hide file tree
Showing 23 changed files with 536 additions and 448 deletions.
19 changes: 10 additions & 9 deletions docs/Configuration-Properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,16 @@ The Push Server uses the following public configuration properties:

## PowerAuth Push Service Configuration

| Property | Default | Note |
|---|---|---|
| `powerauth.push.service.applicationName` | `powerauth-push` | Technical name of the instance |
| `powerauth.push.service.applicationDisplayName` | `PowerAuth Push Server` | Display name of the instance |
| `powerauth.push.service.applicationEnvironment` | `_empty_` | Environment identifier |
| `powerauth.push.service.message.storage.enabled` | `false` | Whether persistent storing of sent messages is enabled |
| `powerauth.push.service.registration.multipleActivations.enabled` | `false` | Whether push registration supports "associated activations" |
| `powerauth.push.service.registration.retry.backoff` | `100` | Duration in milliseconds before a retry attempt during device registration in case of an insert error |
| `owerauth.push.service.registration.retry.maxAttempts` | `2` | Max number of retry attempts during device registration in case of an insert error |
| Property | Default | Note |
|-------------------------------------------------------------------|-------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `powerauth.push.service.applicationName` | `powerauth-push` | Technical name of the instance |
| `powerauth.push.service.applicationDisplayName` | `PowerAuth Push Server` | Display name of the instance |
| `powerauth.push.service.applicationEnvironment` | `_empty_` | Environment identifier |
| `powerauth.push.service.message.storage.enabled` | `false` | Whether persistent storing of sent messages is enabled |
| `powerauth.push.service.registration.multipleActivations.enabled` | `false` | Whether push registration supports "associated activations" |
| `powerauth.push.service.registration.retry.backoff` | `100` | Duration in milliseconds before a retry attempt during device registration in case of an insert error |
| `powerauth.push.service.registration.retry.maxAttempts` | `2` | Max number of retry attempts during device registration in case of an insert error |
| `powerauth.push.service.clients.cache.refreshAfterWrite` | `5m` | APNS, FCM and HMS client configuration is cached. It is evicted if updated via administration on a single node. This is a smart fallback for the clustered environment. |

## PowerAuth Push Campaign Setup

Expand Down
15 changes: 14 additions & 1 deletion docs/PowerAuth-Push-Server-1.9.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,17 @@

This guide contains instructions for migration from PowerAuth Push Server version `1.8.x` to version `1.9.x`.

No migration steps nor database changes are required.
## Database Changes

For convenience, you can use liquibase for your database migration.

If you prefer to make manual DB schema changes, please use the following SQL scripts:

- [PostgreSQL script](./sql/postgresql/migration_1.8.0_1.9.0.sql)
- [Oracle script](./sql/oracle/migration_1.8.0_1.9.0.sql)
- [MSSQL script](./sql/mssql/migration_1.8.0_1.9.0.sql)


### App Credentials Timestamp

To improve caching, the columns `timestamp_created`, and `timestamp_last_updated` have been added into the table `push_app_credentials`.
28 changes: 16 additions & 12 deletions docs/Push-Server-Database.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,29 @@ CREATE TABLE push_app_credentials (
ios_bundle VARCHAR(255),
ios_environment VARCHAR(32),
android_private_key BYTEA,
android_project_id VARCHAR(255)
android_project_id VARCHAR(255),
timestamp_created TIMESTAMP(6) DEFAULT NOW() NOT NULL,
timestamp_last_updated TIMESTAMP(6)
);

CREATE UNIQUE INDEX push_app_cred_app ON push_app_credentials (app_id);
```

#### Columns

| Name | Type | Info | Note |
|-----------------------|--------------|-----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | INTEGER | primary key, index, autoincrement | Unique credential record ID. |
| `app_id` | VARCHAR(255) | index | Associated application ID. |
| `ios_key_id` | VARCHAR(255) | - | Key ID used for identifying a private key in APNs service. |
| `ios_private_key` | BYTEA | - | Binary representation of P8 file with private key used for Apple's APNs service. |
| `ios_team_id` | VARCHAR(255) | - | Team ID used for sending push notifications. |
| `ios_bundle` | VARCHAR(255) | - | Application bundle ID, used as a APNs "topic". |
| `ios_environment` | VARCHAR(32) | - | Per-application APNs environment setting. `NULL` or unknown value inherits from global server configuration, values `development` or `production` override the settings. |
| `android_private_key` | BYTEA | - | Firebase service account private key used when obtaining access tokens for FCM HTTP v1 API. |
| `android_project_id` | VARCHAR(255) | - | Firebase project ID, used when sending push messages using FCM. |
| Name | Type | Info | Note |
|--------------------------|--------------|--------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | INTEGER | primary key, index, autoincrement | Unique credential record ID. |
| `app_id` | VARCHAR(255) | index | Associated application ID. |
| `ios_key_id` | VARCHAR(255) | - | Key ID used for identifying a private key in APNs service. |
| `ios_private_key` | BYTEA | - | Binary representation of P8 file with private key used for Apple's APNs service. |
| `ios_team_id` | VARCHAR(255) | - | Team ID used for sending push notifications. |
| `ios_bundle` | VARCHAR(255) | - | Application bundle ID, used as a APNs "topic". |
| `ios_environment` | VARCHAR(32) | - | Per-application APNs environment setting. `NULL` or unknown value inherits from global server configuration, values `development` or `production` override the settings. |
| `android_private_key` | BYTEA | - | Firebase service account private key used when obtaining access tokens for FCM HTTP v1 API. |
| `android_project_id` | VARCHAR(255) | - | Firebase project ID, used when sending push messages using FCM. |
| `timestamp_created` | TIMESTAMP | `NOT NULL DEFAULT CURRENT_TIMESTAMP` | Timestamp when the record was created. |
| `timestamp_last_updated` | TIMESTAMP | | Timestamp when the record was last updated. |

#### Keys

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<changeSet id="1" logicalFilePath="powerauth-push-server/1.9.x/20241011-app-credentials-timestamp.xml" author="Lubos Racansky">
<preConditions onFail="MARK_RAN">
<not>
<columnExists tableName="push_app_credentials" columnName="timestamp_created"/>
<columnExists tableName="push_app_credentials" columnName="timestamp_last_updated"/>
</not>
</preConditions>
<comment>Add columns timestamp_last_updated and timestamp_created to push_app_credentials table</comment>
<addColumn tableName="push_app_credentials">
<column name="timestamp_created" type="timestamp" defaultValueDate="${now}">
<constraints nullable="false" />
</column>
<column name="timestamp_last_updated" type="timestamp" />
</addColumn>
</changeSet>

</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<include file="20241011-app-credentials-timestamp.xml" relativeToChangelogFile="true" />

</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.9.xsd">

<property name="now" value="now()" dbms="h2"/>
<property name="now" value="current_timestamp" dbms="postgresql"/>
<property name="now" value="sysdate" dbms="oracle"/>
<property name="now" value="current_timestamp" dbms="mssql"/>

<property name="blob_type" value="bytea" dbms="postgresql"/>
<property name="blob_type" value="blob" dbms="oracle"/>
<property name="blob_type" value="varbinary(max)" dbms="mssql"/>
Expand All @@ -11,5 +16,6 @@
<include file="1.5.x/db.changelog-version.xml" relativeToChangelogFile="true" />
<include file="1.7.x/db.changelog-version.xml" relativeToChangelogFile="true" />
<include file="1.8.x/db.changelog-version.xml" relativeToChangelogFile="true" />
<include file="1.9.x/db.changelog-version.xml" relativeToChangelogFile="true" />

</databaseChangeLog>
7 changes: 7 additions & 0 deletions docs/sql/mssql/migration_1.8.0_1.9.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Changeset powerauth-push-server/1.9.x/20241011-app-credentials-timestamp.xml::1::Lubos Racansky
-- Add columns timestamp_last_updated and timestamp_created to push_app_credentials table
ALTER TABLE push_app_credentials ADD timestamp_created datetime2 CONSTRAINT DF_push_app_credentials_timestamp_created DEFAULT GETDATE() NOT NULL;
GO

ALTER TABLE push_app_credentials ADD timestamp_last_updated datetime2;
GO
5 changes: 5 additions & 0 deletions docs/sql/oracle/migration_1.8.0_1.9.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Changeset powerauth-push-server/1.9.x/20241011-app-credentials-timestamp.xml::1::Lubos Racansky
-- Add columns timestamp_last_updated and timestamp_created to push_app_credentials table
ALTER TABLE push_app_credentials ADD timestamp_created TIMESTAMP DEFAULT sysdate NOT NULL;

ALTER TABLE push_app_credentials ADD timestamp_last_updated TIMESTAMP;
5 changes: 5 additions & 0 deletions docs/sql/postgresql/migration_1.8.0_1.9.0.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Changeset powerauth-push-server/1.9.x/20241011-app-credentials-timestamp.xml::1::Lubos Racansky
-- Add columns timestamp_last_updated and timestamp_created to push_app_credentials table
ALTER TABLE push_app_credentials ADD timestamp_created TIMESTAMP WITHOUT TIME ZONE DEFAULT NOW() NOT NULL;

ALTER TABLE push_app_credentials ADD timestamp_last_updated TIMESTAMP WITHOUT TIME ZONE;
5 changes: 5 additions & 0 deletions powerauth-push-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>

<!-- For run at Apple M1 architecture -->
<dependency>
<groupId>io.netty</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2024 Wultra s.r.o.
*
* Licensed 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 io.getlime.push.configuration;

import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import io.getlime.push.service.AppRelatedPushClient;
import io.getlime.push.service.AppRelatedPushClientCacheLoader;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.time.Duration;


/**
* Cache configuration.
*
* @author Lubos Racansky, [email protected]
*/
@Configuration
@Slf4j
public class CacheConfiguration {

/**
* Configure cache for {@link AppRelatedPushClient}.
*
* @return cache for AppRelatedPushClient
*/
@Bean
public LoadingCache<String, AppRelatedPushClient> appRelatedPushClientCache(
@Value("${powerauth.push.service.clients.cache.refreshAfterWrite}") final Duration refreshAfterWrite,
final AppRelatedPushClientCacheLoader cacheLoader) {

logger.info("Initializing AppRelatedPushClient cache with refreshAfterWrite={}", refreshAfterWrite);
return Caffeine.newBuilder()
.refreshAfterWrite(refreshAfterWrite)
.build(cacheLoader);
}

}

This file was deleted.

Loading

0 comments on commit 1d97c3c

Please sign in to comment.