Skip to content

Commit 8d52ae2

Browse files
shawkinsmanusa
authored andcommitted
fix #4638 using patch instead of update
1 parent 4c263a5 commit 8d52ae2

File tree

6 files changed

+59
-44
lines changed

6 files changed

+59
-44
lines changed

kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extended/leaderelection/LeaderElector.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ private void release(LeaderElectionRecord current) {
139139
try {
140140
ZonedDateTime now = now();
141141
final LeaderElectionRecord newLeaderElectionRecord = new LeaderElectionRecord(
142-
null,
142+
"",
143143
Duration.ofSeconds(1),
144144
now,
145145
now,

kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extended/leaderelection/resourcelock/ConfigMapLock.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,12 @@ protected LeaderElectionRecord toRecord(ConfigMap resource) {
5050
return null;
5151
}
5252
})
53-
.map(record -> {
54-
record.setVersion(resource.getMetadata().getResourceVersion());
55-
return record;
56-
})
5753
.orElse(null);
5854
}
5955

6056
@Override
61-
protected ConfigMap toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta meta, ConfigMap current) {
62-
ConfigMapBuilder builder = Optional.ofNullable(current).map(ConfigMapBuilder::new).orElse(new ConfigMapBuilder());
63-
return builder.withMetadata(meta).editMetadata()
57+
protected ConfigMap toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta meta) {
58+
return new ConfigMapBuilder().withMetadata(meta).editMetadata()
6459
.addToAnnotations(LEADER_ELECTION_RECORD_ANNOTATION_KEY, Serialization.asJson(leaderElectionRecord))
6560
.endMetadata()
6661
.build();

kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extended/leaderelection/resourcelock/LeaseLock.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ protected Class<Lease> getKind() {
3535
}
3636

3737
@Override
38-
protected Lease toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta meta, Lease current) {
39-
LeaseBuilder builder = Optional.ofNullable(current).map(LeaseBuilder::new).orElse(new LeaseBuilder());
40-
return builder.withMetadata(meta)
38+
protected Lease toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta meta) {
39+
return new LeaseBuilder().withMetadata(meta)
4140
.withNewSpec()
4241
.withHolderIdentity(leaderElectionRecord.getHolderIdentity())
4342
.withLeaseDurationSeconds((int) leaderElectionRecord.getLeaseDuration().get(ChronoUnit.SECONDS))
@@ -50,16 +49,12 @@ protected Lease toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta
5049

5150
@Override
5251
protected LeaderElectionRecord toRecord(Lease resource) {
53-
return Optional.ofNullable(resource.getSpec()).map(spec -> {
54-
final LeaderElectionRecord ret = new LeaderElectionRecord(
55-
spec.getHolderIdentity(),
56-
Duration.ofSeconds(spec.getLeaseDurationSeconds()),
57-
spec.getAcquireTime(),
58-
spec.getRenewTime(),
59-
Optional.ofNullable(spec.getLeaseTransitions()).orElse(0));
60-
ret.setVersion(resource.getMetadata().getResourceVersion());
61-
return ret;
62-
}).orElse(null);
52+
return Optional.ofNullable(resource.getSpec()).map(spec -> new LeaderElectionRecord(
53+
spec.getHolderIdentity(),
54+
Duration.ofSeconds(spec.getLeaseDurationSeconds()),
55+
spec.getAcquireTime(),
56+
spec.getRenewTime(),
57+
Optional.ofNullable(spec.getLeaseTransitions()).orElse(0))).orElse(null);
6358
}
6459

6560
}

kubernetes-client-api/src/main/java/io/fabric8/kubernetes/client/extended/leaderelection/resourcelock/ResourceLock.java

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@
2020
import io.fabric8.kubernetes.api.model.ObjectMeta;
2121
import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
2222
import io.fabric8.kubernetes.client.KubernetesClient;
23+
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
24+
import io.fabric8.kubernetes.client.dsl.base.PatchType;
2325

26+
import java.io.Serializable;
2427
import java.util.Objects;
2528
import java.util.Optional;
2629

@@ -40,7 +43,7 @@ public ResourceLock(String namespace, String name, String identity) {
4043

4144
@Override
4245
public LeaderElectionRecord get(KubernetesClient client) {
43-
return getResource(client).map(this::toRecord).orElse(null);
46+
return getResource(client).map(this::toRecordInternal).orElse(null);
4447
}
4548

4649
private Optional<T> getResource(KubernetesClient client) {
@@ -49,14 +52,13 @@ private Optional<T> getResource(KubernetesClient client) {
4952

5053
@Override
5154
public void create(KubernetesClient client, LeaderElectionRecord leaderElectionRecord) {
52-
client.resource(toResource(leaderElectionRecord, getObjectMeta(null), null)).create();
55+
client.resource(toResource(leaderElectionRecord, getObjectMeta(leaderElectionRecord.getVersion()))).create();
5356
}
5457

5558
@Override
5659
public void update(KubernetesClient client, LeaderElectionRecord leaderElectionRecord) {
57-
// this should be an edit, but we've disabled the ability for it to have optimistic locking
58-
client.resource(getResource(client).map(r -> toResource(leaderElectionRecord, getObjectMeta(r), r))
59-
.orElseThrow(() -> new NullPointerException())).lockResourceVersion().replace();
60+
client.resource(toResource(leaderElectionRecord, getObjectMeta(leaderElectionRecord.getVersion())))
61+
.patch(PatchContext.of(PatchType.STRATEGIC_MERGE));
6062
}
6163

6264
/**
@@ -67,14 +69,18 @@ public void update(KubernetesClient client, LeaderElectionRecord leaderElectionR
6769
* @param current may be null
6870
* @return
6971
*/
70-
protected abstract T toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta meta, T current);
72+
protected abstract T toResource(LeaderElectionRecord leaderElectionRecord, ObjectMeta meta);
73+
74+
protected LeaderElectionRecord toRecordInternal(T resource) {
75+
LeaderElectionRecord result = toRecord(resource);
76+
result.setVersion(resource.getMetadata().getResourceVersion());
77+
return result;
78+
}
7179

7280
protected abstract LeaderElectionRecord toRecord(T resource);
7381

74-
protected ObjectMeta getObjectMeta(T current) {
75-
ObjectMetaBuilder builder = Optional.ofNullable(current).map(HasMetadata::getMetadata).map(ObjectMetaBuilder::new)
76-
.orElse(new ObjectMetaBuilder());
77-
return builder.withNamespace(namespace).withName(name).build();
82+
protected ObjectMeta getObjectMeta(Serializable version) {
83+
return new ObjectMetaBuilder().withNamespace(namespace).withName(name).withResourceVersion((String) version).build();
7884
}
7985

8086
/**

kubernetes-examples/src/main/java/io/fabric8/kubernetes/examples/LeaderElectionExamples.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ private LeaderElector leader(String id, Function<String, Lock> lockSupplier) {
186186
.withLeaderCallbacks(new LeaderCallbacks(
187187
() -> System.out.printf("\r%1$s: I just became leader!!!%n", id),
188188
() -> {
189-
leaderReference.compareAndSet(id, null);
189+
leaderReference.updateAndGet(s -> id.equals(s)?null:s);
190190
System.out.printf("\r%1$s: I just lost my leadership :(%n", id);
191191
},
192192
leaderReference::set))

kubernetes-tests/src/test/java/io/fabric8/kubernetes/client/mock/LeaderElectionTest.java

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ public class LeaderElectionTest {
5151
@Test
5252
public void singleLeaderConfigMapLockCreateTest() throws Exception {
5353
// Given
54-
server.expect().post().withPath("/api/v1/namespaces/namespace/configmaps")
55-
.andReturn(200, null).once();
54+
server.expect()
55+
.post()
56+
.withPath("/api/v1/namespaces/namespace/configmaps")
57+
.andReturn(200, null)
58+
.once();
5659
// When - Then
5760
testAndAssertSingleLeader("lead-config-map",
5861
new ConfigMapLock("namespace", "name", "lead-config-map"));
@@ -61,7 +64,9 @@ public void singleLeaderConfigMapLockCreateTest() throws Exception {
6164
@Test
6265
public void singleLeaderConfigMapLockUpdateTest() throws Exception {
6366
// Given
64-
server.expect().get().withPath("/api/v1/namespaces/namespace/configmaps/name")
67+
server.expect()
68+
.get()
69+
.withPath("/api/v1/namespaces/namespace/configmaps/name")
6570
.andReturn(200, new ConfigMapBuilder()
6671
.withNewMetadata()
6772
.withResourceVersion("1")
@@ -71,8 +76,11 @@ public void singleLeaderConfigMapLockUpdateTest() throws Exception {
7176
.endMetadata()
7277
.build())
7378
.always();
74-
server.expect().put().withPath("/api/v1/namespaces/namespace/configmaps/name")
75-
.andReturn(200, null).once();
79+
server.expect()
80+
.patch()
81+
.withPath("/api/v1/namespaces/namespace/configmaps/name")
82+
.andReturn(200, null)
83+
.once();
7684
// When - Then
7785
testAndAssertSingleLeader("lead-config-map",
7886
new ConfigMapLock("namespace", "name", "lead-config-map"));
@@ -81,8 +89,11 @@ public void singleLeaderConfigMapLockUpdateTest() throws Exception {
8189
@Test
8290
public void singleLeaderLeaseLockCreateTest() throws Exception {
8391
// Given
84-
server.expect().post().withPath("/apis/coordination.k8s.io/v1/namespaces/namespace/leases")
85-
.andReturn(200, null).once();
92+
server.expect()
93+
.post()
94+
.withPath("/apis/coordination.k8s.io/v1/namespaces/namespace/leases")
95+
.andReturn(200, null)
96+
.once();
8697
// When - Then
8798
testAndAssertSingleLeader("lead-lease",
8899
new LeaseLock("namespace", "name", "lead-lease"));
@@ -91,9 +102,13 @@ public void singleLeaderLeaseLockCreateTest() throws Exception {
91102
@Test
92103
public void singleLeaderLeaseLockUpdateTest() throws Exception {
93104
// Given
94-
server.expect().get().withPath("/apis/coordination.k8s.io/v1/namespaces/namespace/leases/name")
105+
server.expect()
106+
.get()
107+
.withPath("/apis/coordination.k8s.io/v1/namespaces/namespace/leases/name")
95108
.andReturn(200, new LeaseBuilder()
96-
.withNewMetadata().withResourceVersion("1").endMetadata()
109+
.withNewMetadata()
110+
.withResourceVersion("1")
111+
.endMetadata()
97112
.withNewSpec()
98113
.withHolderIdentity("not-lead-lease")
99114
.withLeaseDurationSeconds(1)
@@ -103,8 +118,11 @@ public void singleLeaderLeaseLockUpdateTest() throws Exception {
103118
.endSpec()
104119
.build())
105120
.always();
106-
server.expect().put().withPath("/apis/coordination.k8s.io/v1/namespaces/namespace/leases/name")
107-
.andReturn(200, null).once();
121+
server.expect()
122+
.patch()
123+
.withPath("/apis/coordination.k8s.io/v1/namespaces/namespace/leases/name")
124+
.andReturn(200, null)
125+
.once();
108126
// When - Then
109127
testAndAssertSingleLeader("lead-lease",
110128
new LeaseLock("namespace", "name", "lead-lease"));
@@ -130,7 +148,8 @@ private void testAndAssertSingleLeader(String id, Lock lock) throws Exception {
130148
stoppedLeading::countDown,
131149
newLeaderRecord::set))
132150
.build())
133-
.build().run()));
151+
.build()
152+
.run()));
134153
// Then
135154
assertTrue(leaderLatch.await(10, TimeUnit.SECONDS));
136155
assertEquals(id, newLeaderRecord.get());

0 commit comments

Comments
 (0)