11
11
12
12
import org .elasticsearch .ResourceNotFoundException ;
13
13
import org .elasticsearch .action .ActionListener ;
14
+ import org .elasticsearch .action .FailedNodeException ;
14
15
import org .elasticsearch .action .support .ActionFilters ;
15
- import org .elasticsearch .action .support .master .TransportMasterNodeAction ;
16
- import org .elasticsearch .cluster .ClusterState ;
17
- import org .elasticsearch .cluster .block .ClusterBlockException ;
18
- import org .elasticsearch .cluster .block .ClusterBlockLevel ;
19
- import org .elasticsearch .cluster .metadata .IndexNameExpressionResolver ;
16
+ import org .elasticsearch .action .support .nodes .TransportNodesAction ;
17
+ import org .elasticsearch .cluster .node .DiscoveryNode ;
20
18
import org .elasticsearch .cluster .service .ClusterService ;
19
+ import org .elasticsearch .common .io .stream .StreamInput ;
21
20
import org .elasticsearch .common .regex .Regex ;
22
- import org .elasticsearch .common . util . concurrent . EsExecutors ;
21
+ import org .elasticsearch .features . FeatureService ;
23
22
import org .elasticsearch .ingest .geoip .IngestGeoIpMetadata ;
24
23
import org .elasticsearch .injection .guice .Inject ;
25
24
import org .elasticsearch .tasks .Task ;
26
25
import org .elasticsearch .threadpool .ThreadPool ;
27
26
import org .elasticsearch .transport .TransportService ;
28
27
28
+ import java .io .IOException ;
29
29
import java .util .ArrayList ;
30
30
import java .util .Arrays ;
31
31
import java .util .LinkedHashSet ;
32
32
import java .util .List ;
33
33
import java .util .Map ;
34
34
import java .util .Set ;
35
35
36
- public class TransportGetDatabaseConfigurationAction extends TransportMasterNodeAction <
36
+ import static org .elasticsearch .ingest .IngestGeoIpFeatures .GET_DATABASE_CONFIGURATION_ACTION_MULTI_NODE ;
37
+
38
+ public class TransportGetDatabaseConfigurationAction extends TransportNodesAction <
37
39
GetDatabaseConfigurationAction .Request ,
38
- GetDatabaseConfigurationAction .Response > {
40
+ GetDatabaseConfigurationAction .Response ,
41
+ GetDatabaseConfigurationAction .NodeRequest ,
42
+ GetDatabaseConfigurationAction .NodeResponse ,
43
+ List <DatabaseConfigurationMetadata >> {
44
+
45
+ private final FeatureService featureService ;
39
46
40
47
@ Inject
41
48
public TransportGetDatabaseConfigurationAction (
42
49
TransportService transportService ,
43
50
ClusterService clusterService ,
44
51
ThreadPool threadPool ,
45
52
ActionFilters actionFilters ,
46
- IndexNameExpressionResolver indexNameExpressionResolver
53
+ FeatureService featureService
47
54
) {
48
55
super (
49
56
GetDatabaseConfigurationAction .NAME ,
50
- transportService ,
51
57
clusterService ,
52
- threadPool ,
58
+ transportService ,
53
59
actionFilters ,
54
- GetDatabaseConfigurationAction .Request ::new ,
55
- indexNameExpressionResolver ,
56
- GetDatabaseConfigurationAction .Response ::new ,
57
- EsExecutors .DIRECT_EXECUTOR_SERVICE
60
+ GetDatabaseConfigurationAction .NodeRequest ::new ,
61
+ threadPool .executor (ThreadPool .Names .MANAGEMENT )
58
62
);
63
+ this .featureService = featureService ;
59
64
}
60
65
61
66
@ Override
62
- protected void masterOperation (
63
- final Task task ,
64
- final GetDatabaseConfigurationAction .Request request ,
65
- final ClusterState state ,
66
- final ActionListener <GetDatabaseConfigurationAction .Response > listener
67
+ protected void doExecute (
68
+ Task task ,
69
+ GetDatabaseConfigurationAction .Request request ,
70
+ ActionListener <GetDatabaseConfigurationAction .Response > listener
67
71
) {
72
+ if (featureService .clusterHasFeature (clusterService .state (), GET_DATABASE_CONFIGURATION_ACTION_MULTI_NODE ) == false ) {
73
+ /*
74
+ * TransportGetDatabaseConfigurationAction used to be a TransportMasterNodeAction, and not all nodes in the cluster have been
75
+ * updated. So we don't want to send node requests to the other nodes because they will blow up. Instead, we just return
76
+ * the information that we used to return from the master node (it doesn't make any difference that this might not be the master
77
+ * node, because we're only reading the clsuter state).
78
+ */
79
+ newResponseAsync (task , request , createActionContext (task , request ), List .of (), List .of (), listener );
80
+ } else {
81
+ super .doExecute (task , request , listener );
82
+ }
83
+ }
84
+
85
+ protected List <DatabaseConfigurationMetadata > createActionContext (Task task , GetDatabaseConfigurationAction .Request request ) {
68
86
final Set <String > ids ;
69
87
if (request .getDatabaseIds ().length == 0 ) {
70
88
// if we did not ask for a specific name, then return all databases
@@ -79,7 +97,7 @@ protected void masterOperation(
79
97
);
80
98
}
81
99
82
- final IngestGeoIpMetadata geoIpMeta = state .metadata ().custom (IngestGeoIpMetadata .TYPE , IngestGeoIpMetadata .EMPTY );
100
+ final IngestGeoIpMetadata geoIpMeta = clusterService . state () .metadata ().custom (IngestGeoIpMetadata .TYPE , IngestGeoIpMetadata .EMPTY );
83
101
List <DatabaseConfigurationMetadata > results = new ArrayList <>();
84
102
85
103
for (String id : ids ) {
@@ -92,19 +110,54 @@ protected void masterOperation(
92
110
} else {
93
111
DatabaseConfigurationMetadata meta = geoIpMeta .getDatabases ().get (id );
94
112
if (meta == null ) {
95
- listener .onFailure (new ResourceNotFoundException ("database configuration not found: {}" , id ));
96
- return ;
113
+ throw new ResourceNotFoundException ("database configuration not found: {}" , id );
97
114
} else {
98
115
results .add (meta );
99
116
}
100
117
}
101
118
}
119
+ return results ;
120
+ }
121
+
122
+ protected void newResponseAsync (
123
+ Task task ,
124
+ GetDatabaseConfigurationAction .Request request ,
125
+ List <DatabaseConfigurationMetadata > results ,
126
+ List <GetDatabaseConfigurationAction .NodeResponse > responses ,
127
+ List <FailedNodeException > failures ,
128
+ ActionListener <GetDatabaseConfigurationAction .Response > listener
129
+ ) {
130
+ ActionListener .run (
131
+ listener ,
132
+ l -> ActionListener .respondAndRelease (
133
+ l ,
134
+ new GetDatabaseConfigurationAction .Response (results , clusterService .getClusterName (), responses , failures )
135
+ )
136
+ );
137
+ }
102
138
103
- listener .onResponse (new GetDatabaseConfigurationAction .Response (results ));
139
+ @ Override
140
+ protected GetDatabaseConfigurationAction .Response newResponse (
141
+ GetDatabaseConfigurationAction .Request request ,
142
+ List <GetDatabaseConfigurationAction .NodeResponse > nodeResponses ,
143
+ List <FailedNodeException > failures
144
+ ) {
145
+ throw new UnsupportedOperationException ("Use newResponseAsync instead" );
104
146
}
105
147
106
148
@ Override
107
- protected ClusterBlockException checkBlock (GetDatabaseConfigurationAction .Request request , ClusterState state ) {
108
- return state . blocks (). globalBlockedException ( ClusterBlockLevel . METADATA_READ );
149
+ protected GetDatabaseConfigurationAction . NodeRequest newNodeRequest (GetDatabaseConfigurationAction .Request request ) {
150
+ return new GetDatabaseConfigurationAction . NodeRequest ( request . getDatabaseIds () );
109
151
}
152
+
153
+ @ Override
154
+ protected GetDatabaseConfigurationAction .NodeResponse newNodeResponse (StreamInput in , DiscoveryNode node ) throws IOException {
155
+ return new GetDatabaseConfigurationAction .NodeResponse (in );
156
+ }
157
+
158
+ @ Override
159
+ protected GetDatabaseConfigurationAction .NodeResponse nodeOperation (GetDatabaseConfigurationAction .NodeRequest request , Task task ) {
160
+ return new GetDatabaseConfigurationAction .NodeResponse (transportService .getLocalNode (), List .of ());
161
+ }
162
+
110
163
}
0 commit comments