Skip to content

Commit 4f5c588

Browse files
Etag support for users and channels (#328)
* Etag support for users and channels A new optional parameter `ifMatchesEtag` is added to `setUUIDMetadata` and `setChannelMetadata`. When provided, the server checks the argument value with the ETag on the server and if they don't match a HTTP 412 error is returned. * PubNub SDK v10.4.0 release. --------- Co-authored-by: PubNub Release Bot <[email protected]>
1 parent 11f1678 commit 4f5c588

File tree

30 files changed

+248
-45
lines changed

30 files changed

+248
-45
lines changed

.github/workflows/commands-handler.yml

+3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ jobs:
3535
ref: v1
3636
token: ${{ secrets.GH_TOKEN }}
3737
path: .github/.release/actions
38+
- name: Update CocoaPods trunk
39+
run: |
40+
pod repo update
3841
- name: Process changelog entries
3942
if: steps.user-check.outputs.expected-user == 'true'
4043
uses: ./.github/.release/actions/actions/commands

.github/workflows/release.yml

+3
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ jobs:
5555
ref: v1
5656
token: ${{ secrets.GH_TOKEN }}
5757
path: .github/.release/actions
58+
- name: Update CocoaPods trunk
59+
run: |
60+
pod repo update
5861
- name: Publish to Maven
5962
uses: ./.github/.release/actions/actions/services/maven
6063
with:

.github/workflows/run-tests.yml

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jobs:
3333
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
3434
restore-keys: |
3535
${{ runner.os }}-gradle-
36+
- name: Update CocoaPods trunk
37+
run: |
38+
pod repo update
3639
- name: Build and run tests
3740
run: |
3841
./gradlew check

.github/workflows/run-validations.yml

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ jobs:
5353
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
5454
restore-keys: |
5555
${{ runner.os }}-gradle-
56+
- name: Update CocoaPods trunk
57+
run: |
58+
pod repo update
5659
- name: Validate clean build
5760
run: ./gradlew ktlintFormat publishAllPublicationsToRepoRepository -PRELEASE_SIGNING_ENABLED=false
5861
- name: Cancel workflow runs for commit on error

.pubnub.yml

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
name: kotlin
2-
version: 10.3.4
2+
version: 10.4.0
33
schema: 1
44
scm: github.com/pubnub/kotlin
55
files:
6-
- build/libs/pubnub-kotlin-10.3.4-all.jar
6+
- build/libs/pubnub-kotlin-10.4.0-all.jar
77
sdks:
88
-
99
type: library
@@ -23,8 +23,8 @@ sdks:
2323
-
2424
distribution-type: library
2525
distribution-repository: maven
26-
package-name: pubnub-kotlin-10.3.4
27-
location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-kotlin/10.3.4/pubnub-kotlin-10.3.4.jar
26+
package-name: pubnub-kotlin-10.4.0
27+
location: https://repo.maven.apache.org/maven2/com/pubnub/pubnub-kotlin/10.4.0/pubnub-kotlin-10.4.0.jar
2828
supported-platforms:
2929
supported-operating-systems:
3030
Android:
@@ -121,6 +121,11 @@ sdks:
121121
license-url: https://www.apache.org/licenses/LICENSE-2.0.txt
122122
is-required: Required
123123
changelog:
124+
- date: 2025-01-21
125+
version: v10.4.0
126+
changes:
127+
- type: feature
128+
text: "A new optional parameter `ifMatchesEtag` is added to `setUUIDMetadata` and `setChannelMetadata`. When provided, the server compares the argument value with the ETag on the server and if they don't match a HTTP 412 error is returned."
124129
- date: 2025-01-13
125130
version: v10.3.4
126131
changes:

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## v10.4.0
2+
January 21 2025
3+
4+
#### Added
5+
- A new optional parameter `ifMatchesEtag` is added to `setUUIDMetadata` and `setChannelMetadata`. When provided, the server compares the argument value with the ETag on the server and if they don't match a HTTP 412 error is returned.
6+
17
## v10.3.4
28
January 13 2025
39

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ You will need the publish and subscribe keys to authenticate your app. Get your
2020
<dependency>
2121
<groupId>com.pubnub</groupId>
2222
<artifactId>pubnub-kotlin</artifactId>
23-
<version>10.3.4</version>
23+
<version>10.4.0</version>
2424
</dependency>
2525
```
2626

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ RELEASE_SIGNING_ENABLED=true
1818
SONATYPE_HOST=DEFAULT
1919
SONATYPE_AUTOMATIC_RELEASE=false
2020
GROUP=com.pubnub
21-
VERSION_NAME=10.3.4
21+
VERSION_NAME=10.4.0
2222
POM_PACKAGING=jar
2323

2424
POM_NAME=PubNub SDK

gradle/libs.versions.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ ktlint = "12.1.0"
1212
dokka = "1.9.20"
1313
kotlinx_datetime = "0.6.1"
1414
kotlinx_coroutines = "1.9.0"
15-
pubnub_js = "8.4.1"
16-
pubnub_swift = "8.2.4"
15+
pubnub_js = "8.6.0"
16+
pubnub_swift = "8.3.0"
1717

1818
[libraries]
1919
retrofit2 = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit2" }

kotlin-js-store/yarn.lock

+20-4
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,26 @@ proxy-from-env@^1.1.0:
659659
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
660660
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
661661

662-
663-
version "8.4.0"
664-
resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-8.4.0.tgz#8a5fdd3af9783abb1de44ea4145107e296c8394d"
665-
integrity sha512-HvkFhn4XcfR1wdJv4paX94I0TT4UBHW/vIuYnS+6XuoSx0AunJMCk5wbKnSesmdbzYUZa8Ag3H1mJQZKuyRy8Q==
662+
663+
version "8.4.1"
664+
resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-8.4.1.tgz#5f6f19e84d3187dc8aee0a458bd6b05e90d43e6a"
665+
integrity sha512-mPlwVoHJDWPasZx52UfSMiPX5TATm5A+ficSogyqDqTQ4w5EQnwxH+PJdsWc0mPnlT051jM1vIISMeM0fQ30CQ==
666+
dependencies:
667+
agentkeepalive "^3.5.2"
668+
buffer "^6.0.3"
669+
cbor-js "^0.1.0"
670+
cbor-sync "^1.0.4"
671+
form-data "^4.0.0"
672+
lil-uuid "^0.1.1"
673+
node-fetch "^2.7.0"
674+
proxy-agent "^6.3.0"
675+
react-native-url-polyfill "^2.0.0"
676+
text-encoding "^0.7.0"
677+
678+
679+
version "8.6.0"
680+
resolved "https://registry.yarnpkg.com/pubnub/-/pubnub-8.6.0.tgz#75524e7ed3653090652d160ce83ac089362a0379"
681+
integrity sha512-LBCglooxiLkNT3ArUOvSJnLKK6/QdeshWY60IWlSQ+SkXlzEjt74wAnX5XriEXKsmza2yw9mFGG6+B5SlczRzA==
666682
dependencies:
667683
agentkeepalive "^3.5.2"
668684
buffer "^6.0.3"

pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/objects_api/channel/SetChannelMetadata.java

+9
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.pubnub.api.java.endpoints.BuilderSteps;
44
import com.pubnub.api.java.endpoints.Endpoint;
55
import com.pubnub.api.java.models.consumer.objects_api.channel.PNSetChannelMetadataResult;
6+
import org.jetbrains.annotations.Nullable;
67

78
import java.util.Map;
89

@@ -19,6 +20,14 @@ public interface SetChannelMetadata extends Endpoint<PNSetChannelMetadataResult>
1920

2021
SetChannelMetadata includeCustom(boolean includeCustom);
2122

23+
/**
24+
* Optional entity tag from a previously received `PNChannelMetadata`. The request
25+
* will fail if this parameter is specified and the ETag value on the server doesn't match.
26+
* @param etag from PNChannelMetadata
27+
* @return this builder
28+
*/
29+
SetChannelMetadata ifMatchesEtag(@Nullable String etag);
30+
2231
interface Builder extends BuilderSteps.ChannelStep<SetChannelMetadata> {
2332
@Override
2433
SetChannelMetadata channel(String channel);

pubnub-gson/pubnub-gson-api/src/main/java/com/pubnub/api/java/endpoints/objects_api/uuid/SetUUIDMetadata.java

+9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.pubnub.api.java.endpoints.Endpoint;
44
import com.pubnub.api.java.models.consumer.objects_api.uuid.PNSetUUIDMetadataResult;
5+
import org.jetbrains.annotations.Nullable;
56

67
import java.util.Map;
78

@@ -23,4 +24,12 @@ public interface SetUUIDMetadata extends Endpoint<PNSetUUIDMetadataResult> {
2324
SetUUIDMetadata type(String type);
2425

2526
SetUUIDMetadata status(String status);
27+
28+
/**
29+
* Optional entity tag from a previously received `PNUUIDMetadata`. The request
30+
* will fail if this parameter is specified and the ETag value on the server doesn't match.
31+
* @param etag from PNUUIDMetadata
32+
* @return this builder
33+
*/
34+
SetUUIDMetadata ifMatchesEtag(@Nullable String etag);
2635
}

pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/objects_api/channel/SetChannelMetadataImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import lombok.Setter;
1313
import lombok.experimental.Accessors;
1414
import org.jetbrains.annotations.NotNull;
15+
import org.jetbrains.annotations.Nullable;
1516

1617
import java.util.HashMap;
1718
import java.util.Map;
@@ -46,7 +47,8 @@ protected Endpoint<PNChannelMetadataResult> createRemoteAction() {
4647
custom,
4748
includeCustom,
4849
type,
49-
status
50+
status,
51+
ifMatchesEtag
5052
);
5153
}
5254

@@ -69,6 +71,10 @@ protected Endpoint<PNChannelMetadataResult> createRemoteAction() {
6971
@Setter
7072
private boolean includeCustom;
7173

74+
@Setter
75+
@Nullable
76+
private String ifMatchesEtag;
77+
7278
@Override
7379
public SetChannelMetadata custom(Map<String, Object> custom) {
7480
final HashMap<String, Object> customHashMap = new HashMap<>();

pubnub-gson/pubnub-gson-impl/src/main/java/com/pubnub/internal/java/endpoints/objects_api/uuid/SetUUIDMetadataImpl.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import lombok.Setter;
1313
import lombok.experimental.Accessors;
1414
import org.jetbrains.annotations.NotNull;
15+
import org.jetbrains.annotations.Nullable;
1516

1617
import java.util.HashMap;
1718
import java.util.Map;
@@ -37,6 +38,10 @@ public class SetUUIDMetadataImpl extends DelegatingEndpoint<PNUUIDMetadataResult
3738
@Setter
3839
private String status;
3940

41+
@Setter
42+
@Nullable
43+
private String ifMatchesEtag;
44+
4045
public SetUUIDMetadataImpl(final PubNub pubnub) {
4146
super(pubnub);
4247
}
@@ -63,7 +68,8 @@ protected Endpoint<PNUUIDMetadataResult> createRemoteAction() {
6368
custom,
6469
includeCustom,
6570
type,
66-
status
71+
status,
72+
ifMatchesEtag
6773
);
6874
}
6975

pubnub-kotlin/pubnub-kotlin-api/config/ktlint/baseline.xml

+14-20
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66
<file name="src/commonMain/kotlin/com/pubnub/api/models/consumer/objects/membership/MembershipInclude.kt">
77
<error line="20" column="5" source="standard:function-naming" />
88
</file>
9-
<file name="src/commonTest/kotlin/com/pubnub/test/integration/MembersTest.kt">
10-
<error line="18" column="1" source="standard:blank-line-before-declaration" />
11-
</file>
129
<file name="src/jsMain/kotlin/Pubnub.d.kt">
1310
<error line="156" column="40" source="standard:comment-wrapping" />
1411
<error line="411" column="15" source="standard:class-naming" />
@@ -22,19 +19,17 @@
2219
<error line="849" column="13" source="standard:property-naming" />
2320
<error line="1034" column="15" source="standard:class-naming" />
2421
<error line="1040" column="15" source="standard:class-naming" />
25-
<error line="1161" column="13" source="standard:property-naming" />
26-
<error line="1169" column="13" source="standard:property-naming" />
22+
<error line="1163" column="13" source="standard:property-naming" />
2723
<error line="1171" column="13" source="standard:property-naming" />
28-
<error line="1234" column="39" source="standard:comment-wrapping" />
29-
<error line="1319" column="15" source="standard:class-naming" />
30-
<error line="1347" column="42" source="standard:comment-wrapping" />
31-
<error line="1397" column="37" source="standard:comment-wrapping" />
32-
<error line="1418" column="13" source="standard:property-naming" />
33-
<error line="1419" column="13" source="standard:property-naming" />
34-
<error line="1423" column="13" source="standard:property-naming" />
35-
<error line="1424" column="13" source="standard:property-naming" />
36-
<error line="1443" column="9" source="standard:property-naming" />
37-
<error line="1444" column="9" source="standard:property-naming" />
24+
<error line="1173" column="13" source="standard:property-naming" />
25+
<error line="1236" column="39" source="standard:comment-wrapping" />
26+
<error line="1321" column="15" source="standard:class-naming" />
27+
<error line="1349" column="42" source="standard:comment-wrapping" />
28+
<error line="1399" column="37" source="standard:comment-wrapping" />
29+
<error line="1420" column="13" source="standard:property-naming" />
30+
<error line="1421" column="13" source="standard:property-naming" />
31+
<error line="1425" column="13" source="standard:property-naming" />
32+
<error line="1426" column="13" source="standard:property-naming" />
3833
<error line="1445" column="9" source="standard:property-naming" />
3934
<error line="1446" column="9" source="standard:property-naming" />
4035
<error line="1447" column="9" source="standard:property-naming" />
@@ -46,8 +41,8 @@
4641
<error line="1453" column="9" source="standard:property-naming" />
4742
<error line="1454" column="9" source="standard:property-naming" />
4843
<error line="1455" column="9" source="standard:property-naming" />
49-
<error line="1459" column="9" source="standard:property-naming" />
50-
<error line="1460" column="9" source="standard:property-naming" />
44+
<error line="1456" column="9" source="standard:property-naming" />
45+
<error line="1457" column="9" source="standard:property-naming" />
5146
<error line="1461" column="9" source="standard:property-naming" />
5247
<error line="1462" column="9" source="standard:property-naming" />
5348
<error line="1463" column="9" source="standard:property-naming" />
@@ -82,8 +77,7 @@
8277
<error line="1492" column="9" source="standard:property-naming" />
8378
<error line="1493" column="9" source="standard:property-naming" />
8479
<error line="1494" column="9" source="standard:property-naming" />
85-
</file>
86-
<file name="src/jsMain/kotlin/com/pubnub/api/PubNubImpl.kt">
87-
<error line="1446" column="12" source="standard:no-multi-spaces" />
80+
<error line="1495" column="9" source="standard:property-naming" />
81+
<error line="1496" column="9" source="standard:property-naming" />
8882
</file>
8983
</baseline>

pubnub-kotlin/pubnub-kotlin-api/src/appleMain/kotlin/com/pubnub/api/PubNubImpl.kt

+8-4
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,8 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub {
513513
custom: CustomObject?,
514514
includeCustom: Boolean,
515515
type: String?,
516-
status: String?
516+
status: String?,
517+
ifMatchesEtag: String?,
517518
): SetChannelMetadata {
518519
return SetChannelMetadataImpl(
519520
pubnub = pubNubObjC,
@@ -523,7 +524,8 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub {
523524
custom = custom,
524525
includeCustom = includeCustom,
525526
type = type,
526-
status = status
527+
status = status,
528+
ifMatchesEtag = ifMatchesEtag,
527529
)
528530
}
529531

@@ -570,7 +572,8 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub {
570572
custom: CustomObject?,
571573
includeCustom: Boolean,
572574
type: String?,
573-
status: String?
575+
status: String?,
576+
ifMatchesEtag: String?,
574577
): SetUUIDMetadata {
575578
return SetUUIDMetadataImpl(
576579
pubnub = pubNubObjC,
@@ -582,7 +585,8 @@ class PubNubImpl(private val pubNubObjC: KMPPubNub) : PubNub {
582585
custom = custom,
583586
includeCustom = includeCustom,
584587
type = type,
585-
status = status
588+
status = status,
589+
ifMatchesEtag = ifMatchesEtag,
586590
)
587591
}
588592

pubnub-kotlin/pubnub-kotlin-api/src/appleMain/kotlin/com/pubnub/api/endpoints/objects/channel/SetChannelMetadata.ios.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class SetChannelMetadataImpl(
2828
private val custom: CustomObject?,
2929
private val includeCustom: Boolean,
3030
private val type: String?,
31-
private val status: String?
31+
private val status: String?,
32+
private val ifMatchesEtag: String? = null,
3233
) : SetChannelMetadata {
3334
override fun async(callback: Consumer<Result<PNChannelMetadataResult>>) {
3435
pubnub.setChannelMetadataWithMetadataId(
@@ -43,6 +44,7 @@ class SetChannelMetadataImpl(
4344
),
4445
type = type,
4546
status = status,
47+
ifMatchesEtag = ifMatchesEtag,
4648
onSuccess = callback.onSuccessHandler {
4749
PNChannelMetadataResult(
4850
status = 200,

pubnub-kotlin/pubnub-kotlin-api/src/appleMain/kotlin/com/pubnub/api/endpoints/objects/uuid/SetUUIDMetadata.ios.kt

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class SetUUIDMetadataImpl(
3030
private val custom: CustomObject?,
3131
private val includeCustom: Boolean,
3232
private val type: String?,
33-
private val status: String?
33+
private val status: String?,
34+
private val ifMatchesEtag: String? = null,
3435
) : SetUUIDMetadata {
3536
override fun async(callback: Consumer<Result<PNUUIDMetadataResult>>) {
3637
pubnub.setUserMetadataWithMetadataId(
@@ -47,6 +48,7 @@ class SetUUIDMetadataImpl(
4748
),
4849
type = type,
4950
status = status,
51+
ifMatchesEtag = ifMatchesEtag,
5052
onSuccess = callback.onSuccessHandler {
5153
PNUUIDMetadataResult(
5254
status = 200,

0 commit comments

Comments
 (0)