Skip to content

Commit 351ffa1

Browse files
authored
Merge pull request #1345 from yue9944882/lease-lock
Feat: Adding lease lock implementation
2 parents 67ac475 + 7284b8f commit 351ffa1

File tree

1 file changed

+137
-0
lines changed
  • extended/src/main/java/io/kubernetes/client/extended/leaderelection/resourcelock

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
http://www.apache.org/licenses/LICENSE-2.0
7+
Unless required by applicable law or agreed to in writing, software
8+
distributed under the License is distributed on an "AS IS" BASIS,
9+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10+
See the License for the specific language governing permissions and
11+
limitations under the License.
12+
*/
13+
package io.kubernetes.client.extended.leaderelection.resourcelock;
14+
15+
import io.kubernetes.client.extended.leaderelection.LeaderElectionRecord;
16+
import io.kubernetes.client.extended.leaderelection.Lock;
17+
import io.kubernetes.client.openapi.ApiClient;
18+
import io.kubernetes.client.openapi.ApiException;
19+
import io.kubernetes.client.openapi.Configuration;
20+
import io.kubernetes.client.openapi.apis.CoordinationV1Api;
21+
import io.kubernetes.client.openapi.models.V1Lease;
22+
import io.kubernetes.client.openapi.models.V1LeaseSpec;
23+
import io.kubernetes.client.openapi.models.V1ObjectMeta;
24+
import java.net.HttpURLConnection;
25+
import java.util.concurrent.atomic.AtomicReference;
26+
import org.joda.time.DateTime;
27+
import org.slf4j.Logger;
28+
import org.slf4j.LoggerFactory;
29+
30+
public class LeaseLock implements Lock {
31+
32+
private static final Logger log = LoggerFactory.getLogger(LeaseLock.class);
33+
34+
// Namespace and name describes the endpoint object
35+
// that the LeaderElector will attempt to lead.
36+
private final String namespace;
37+
private final String name;
38+
private final String identity;
39+
40+
private CoordinationV1Api coordinationV1Api;
41+
42+
private AtomicReference<V1Lease> leaseRefer = new AtomicReference<>(null);
43+
44+
public LeaseLock(String namespace, String name, String identity) {
45+
this(namespace, name, identity, Configuration.getDefaultApiClient());
46+
}
47+
48+
public LeaseLock(String namespace, String name, String identity, ApiClient apiClient) {
49+
this.namespace = namespace;
50+
this.name = name;
51+
this.identity = identity;
52+
this.coordinationV1Api = new CoordinationV1Api(apiClient);
53+
}
54+
55+
@Override
56+
public LeaderElectionRecord get() throws ApiException {
57+
V1Lease lease = coordinationV1Api.readNamespacedLease(name, namespace, null, null, null);
58+
leaseRefer.set(lease);
59+
return getRecordFromLease(lease.getSpec());
60+
}
61+
62+
@Override
63+
public boolean create(LeaderElectionRecord record) {
64+
try {
65+
V1Lease createdLease =
66+
coordinationV1Api.createNamespacedLease(
67+
namespace,
68+
new V1Lease()
69+
.metadata(new V1ObjectMeta().namespace(namespace).name(name))
70+
.spec(getLeaseFromRecord(record)),
71+
null,
72+
null,
73+
null);
74+
leaseRefer.set(createdLease);
75+
return true;
76+
} catch (ApiException e) {
77+
if (e.getCode() == HttpURLConnection.HTTP_CONFLICT) {
78+
log.debug("received {} when creating configmap lock", e.getCode(), e);
79+
} else {
80+
log.error("received {} when creating configmap lock", e.getCode(), e);
81+
}
82+
return false;
83+
}
84+
}
85+
86+
@Override
87+
public boolean update(LeaderElectionRecord record) {
88+
try {
89+
V1Lease latest = leaseRefer.get();
90+
latest.setSpec(getLeaseFromRecord(record));
91+
V1Lease updatedLease =
92+
coordinationV1Api.replaceNamespacedLease(name, namespace, latest, null, null, null);
93+
leaseRefer.set(updatedLease);
94+
return true;
95+
} catch (ApiException e) {
96+
if (e.getCode() == HttpURLConnection.HTTP_CONFLICT) {
97+
log.debug("received {} when creating configmap lock", e.getCode(), e);
98+
} else {
99+
log.error("received {} when creating configmap lock", e.getCode(), e);
100+
}
101+
return false;
102+
}
103+
}
104+
105+
@Override
106+
public String identity() {
107+
return identity;
108+
}
109+
110+
@Override
111+
public String describe() {
112+
return namespace + "/" + name;
113+
}
114+
115+
private LeaderElectionRecord getRecordFromLease(V1LeaseSpec lease) {
116+
LeaderElectionRecord record = new LeaderElectionRecord();
117+
if (lease.getAcquireTime() != null) {
118+
record.setAcquireTime(lease.getAcquireTime().toDate());
119+
}
120+
if (lease.getRenewTime() != null) {
121+
record.setRenewTime(lease.getRenewTime().toDate());
122+
}
123+
record.setHolderIdentity(lease.getHolderIdentity());
124+
record.setLeaderTransitions(lease.getLeaseTransitions());
125+
record.setLeaseDurationSeconds(lease.getLeaseDurationSeconds());
126+
return record;
127+
}
128+
129+
private V1LeaseSpec getLeaseFromRecord(LeaderElectionRecord record) {
130+
return new V1LeaseSpec()
131+
.acquireTime(new DateTime(record.getAcquireTime()))
132+
.renewTime(new DateTime(record.getRenewTime()))
133+
.holderIdentity(record.getHolderIdentity())
134+
.leaseDurationSeconds(record.getLeaseDurationSeconds())
135+
.leaseTransitions(record.getLeaderTransitions());
136+
}
137+
}

0 commit comments

Comments
 (0)