Skip to content

Commit 385ff65

Browse files
Sergey Chugunovalamar
authored andcommitted
IGNITE-12111 Cluster ID and tag to identify cluster - Fixes apache#7922.
Signed-off-by: Ilya Kasnacheev <[email protected]>
1 parent 16a7035 commit 385ff65

File tree

13 files changed

+1559
-6
lines changed

13 files changed

+1559
-6
lines changed

modules/core/src/main/java/org/apache/ignite/IgniteCluster.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
* caching nodes, and get other useful information about topology.
4141
*/
4242
public interface IgniteCluster extends ClusterGroup, IgniteAsyncSupport {
43+
/**
44+
* Maximum length of {@link IgniteCluster#tag()} tag.
45+
*/
46+
public static final int MAX_TAG_LENGTH = 280;
47+
4348
/**
4449
* Gets local grid node.
4550
*
@@ -558,9 +563,44 @@ public IgniteFuture<Collection<ClusterStartNodeResult>> startNodesAsync(Collecti
558563
*/
559564
public boolean isWalEnabled(String cacheName);
560565

566+
/**
567+
* Cluster ID is a unique identifier automatically generated when cluster starts up for the very first time.
568+
*
569+
* It is a cluster-wide property so all nodes of the cluster (including client nodes) return the same value.
570+
*
571+
* In in-memory clusters ID is generated again upon each cluster restart.
572+
* In clusters running in persistent mode cluster ID is stored to disk and is used even after full cluster restart.
573+
*
574+
* @return Unique cluster ID.
575+
*/
576+
public UUID id();
577+
578+
/**
579+
* User-defined tag describing the cluster.
580+
*
581+
* @return Current tag value same across all nodes of the cluster.
582+
*/
583+
public String tag();
584+
585+
/**
586+
* Enables user to add a specific label to the cluster e.g. to describe purpose of the cluster
587+
* or any its characteristics.
588+
* Tag is set cluster-wide,
589+
* value set on one node will be distributed across all nodes (including client nodes) in the cluster.
590+
*
591+
* Maximum tag length is limited by {@link #MAX_TAG_LENGTH} value.
592+
*
593+
* @param tag New tag to be set.
594+
*
595+
* @throws IgniteCheckedException In case tag change is requested on inactive cluster
596+
* or concurrent tag change request was completed before the current one.
597+
* Also provided tag is checked for max length.
598+
*/
599+
public void tag(String tag) throws IgniteCheckedException;
600+
561601
/**
562602
* @return Value of manual baseline control or auto adjusting baseline. {@code True} If cluster in auto-adjust.
563-
* {@code False} If cluster in manuale.
603+
* {@code False} If cluster in manual.
564604
*/
565605
public boolean isBaselineAutoAdjustEnabled();
566606

modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterAsyncImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,21 @@ public IgniteClusterAsyncImpl(IgniteClusterImpl cluster) {
363363
return cluster.isWalEnabled(cacheName);
364364
}
365365

366+
/** {@inheritDoc} */
367+
@Override public UUID id() {
368+
return cluster.id();
369+
}
370+
371+
/** {@inheritDoc} */
372+
@Override public String tag() {
373+
return cluster.tag();
374+
}
375+
376+
/** {@inheritDoc} */
377+
@Override public void tag(String tag) throws IgniteCheckedException {
378+
cluster.tag(tag);
379+
}
380+
366381
/** {@inheritDoc} */
367382
@Override public boolean isBaselineAutoAdjustEnabled() {
368383
return cluster.isBaselineAutoAdjustEnabled();

modules/core/src/main/java/org/apache/ignite/internal/cluster/IgniteClusterImpl.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ public class IgniteClusterImpl extends ClusterGroupAdapter implements IgniteClus
101101
/** Minimal IgniteProductVersion supporting BaselineTopology */
102102
private static final IgniteProductVersion MIN_BLT_SUPPORTING_VER = IgniteProductVersion.fromString("2.4.0");
103103

104+
/** Unique ID of cluster. Generated on start, shared by all nodes. */
105+
private volatile UUID id;
106+
107+
/** User-defined human-readable tag. Generated automatically on start, can be changed later. */
108+
private volatile String tag;
109+
104110
/**
105111
* Required by {@link Externalizable}.
106112
*/
@@ -639,6 +645,65 @@ private boolean changeWalMode(String cacheName, boolean enabled) {
639645
}
640646
}
641647

648+
/** {@inheritDoc} */
649+
@Override public UUID id() {
650+
return id;
651+
}
652+
653+
/**
654+
* Not part of public API.
655+
* Enables ClusterProcessor to set ID in the following cases:
656+
* <ol>
657+
* <li>For the first time on node startup.</li>
658+
* <li>Set to null on client disconnect.</li>
659+
* <li>Set to some not-null value on client reconnect.</li>
660+
* </ol>
661+
*
662+
* @param id ID to set.
663+
*/
664+
public void setId(UUID id) {
665+
this.id = id;
666+
}
667+
668+
/** {@inheritDoc} */
669+
@Override public String tag() {
670+
return tag;
671+
}
672+
673+
/** {@inheritDoc} */
674+
@Override public void tag(String tag) throws IgniteCheckedException {
675+
if (tag == null || tag.isEmpty())
676+
throw new IgniteCheckedException("Please provide not-null and not empty string for cluster tag");
677+
678+
if (tag.length() > MAX_TAG_LENGTH) {
679+
throw new IgniteCheckedException("Maximum tag length is exceeded, max length is " +
680+
MAX_TAG_LENGTH +
681+
" symbols, provided value has " +
682+
tag.length() +
683+
" symbols.");
684+
}
685+
686+
if (!ctx.state().publicApiActiveState(true))
687+
throw new IgniteCheckedException("Can not change cluster tag on inactive cluster. To activate the cluster call Ignite.active(true).");
688+
689+
ctx.cluster().updateTag(tag);
690+
}
691+
692+
/**
693+
* Not part of public API.
694+
* Enables ClusterProcessor to set tag in the following cases:
695+
* <ol>
696+
* <li>For the first time on node startup.</li>
697+
* <li>Set to null on client disconnect.</li>
698+
* <li>Set to some not-null value on client reconnect.</li>
699+
* </ol>
700+
*
701+
* @param tag Tag to set.
702+
*/
703+
public void setTag(@Nullable String tag) {
704+
this.tag = tag;
705+
}
706+
642707
/** {@inheritDoc} */
643708
@Override public boolean isBaselineAutoAdjustEnabled() {
644709
return ctx.state().isBaselineAutoAdjustEnabled();

modules/core/src/main/java/org/apache/ignite/internal/managers/discovery/GridDiscoveryManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -767,6 +767,8 @@ else if (customMsg instanceof ChangeGlobalStateMessage) {
767767
ctx.authentication().onLocalJoin();
768768

769769
ctx.encryption().onLocalJoin();
770+
771+
ctx.cluster().onLocalJoin();
770772
}
771773

772774
IgniteInternalFuture<Boolean> transitionWaitFut = ctx.state().onLocalJoin(discoCache);
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
package org.apache.ignite.internal.processors.cluster;
19+
20+
import java.io.Serializable;
21+
import java.util.Objects;
22+
import java.util.UUID;
23+
import org.apache.ignite.internal.util.typedef.internal.S;
24+
25+
/**
26+
* Container class to send cluster ID and tag in disco data and to write them atomically to metastorage.
27+
*/
28+
public class ClusterIdAndTag implements Serializable {
29+
/** */
30+
private static final long serialVersionUID = 0L;
31+
32+
/** */
33+
private final UUID id;
34+
35+
/** */
36+
private final String tag;
37+
38+
/**
39+
* @param id Cluster ID.
40+
* @param tag Cluster tag.
41+
*/
42+
public ClusterIdAndTag(UUID id, String tag) {
43+
this.id = id;
44+
this.tag = tag;
45+
}
46+
47+
/**
48+
* @return Value of cluster id.
49+
*/
50+
public UUID id() {
51+
return id;
52+
}
53+
54+
/**
55+
* @return Value of cluster tag.
56+
*/
57+
public String tag() {
58+
return tag;
59+
}
60+
61+
/** {@inheritDoc} */
62+
@Override public int hashCode() {
63+
return Objects.hash(id, tag);
64+
}
65+
66+
/** {@inheritDoc} */
67+
@Override public boolean equals(Object obj) {
68+
if (!(obj instanceof ClusterIdAndTag))
69+
return false;
70+
71+
ClusterIdAndTag idAndTag = (ClusterIdAndTag)obj;
72+
73+
return id.equals(idAndTag.id) && tag.equals(idAndTag.tag);
74+
}
75+
76+
/** {@inheritDoc} */
77+
@Override public String toString() {
78+
return S.toString(ClusterIdAndTag.class, this);
79+
}
80+
}

0 commit comments

Comments
 (0)