1111
1212package org .opensearch .security .dlic .rest .api ;
1313
14- import static org .opensearch .security .dlic .rest .api .Responses .badRequestMessage ;
15- import static org .opensearch .security .dlic .rest .api .Responses .ok ;
16- import static org .opensearch .security .dlic .rest .api .Responses .response ;
17- import static org .opensearch .security .dlic .rest .support .Utils .addRoutesPrefix ;
18- import static org .opensearch .security .dlic .rest .support .Utils .withIOException ;
19-
2014import java .io .IOException ;
2115import java .nio .file .Path ;
2216import java .security .AccessController ;
3125import java .util .Set ;
3226import java .util .stream .Collectors ;
3327
28+ import com .google .common .collect .ImmutableList ;
29+ import com .google .common .collect .ImmutableSet ;
30+ import com .fasterxml .jackson .databind .JsonNode ;
31+ import com .fasterxml .jackson .databind .node .ArrayNode ;
32+ import com .fasterxml .jackson .databind .node .JsonNodeFactory ;
33+ import com .fasterxml .jackson .databind .node .ObjectNode ;
3434import org .apache .logging .log4j .LogManager ;
3535import org .apache .logging .log4j .Logger ;
36+
3637import org .opensearch .client .Client ;
3738import org .opensearch .cluster .service .ClusterService ;
3839import org .opensearch .common .collect .Tuple ;
3940import org .opensearch .common .inject .Inject ;
4041import org .opensearch .common .settings .Settings ;
42+ import org .opensearch .common .xcontent .XContentType ;
4143import org .opensearch .core .rest .RestStatus ;
44+ import org .opensearch .rest .BytesRestResponse ;
4245import org .opensearch .rest .RestChannel ;
4346import org .opensearch .rest .RestRequest ;
4447import org .opensearch .rest .RestRequest .Method ;
5356import org .opensearch .security .support .ConfigHelper ;
5457import org .opensearch .threadpool .ThreadPool ;
5558
56- import com .fasterxml .jackson .databind .JsonNode ;
57- import com .fasterxml .jackson .databind .node .ArrayNode ;
58- import com .fasterxml .jackson .databind .node .JsonNodeFactory ;
5959import com .flipkart .zjsonpatch .DiffFlags ;
6060import com .flipkart .zjsonpatch .JsonDiff ;
61- import com .google .common .collect .ImmutableList ;
62- import com .google .common .collect .ImmutableMap ;
63- import com .google .common .collect .ImmutableSet ;
64-
65- import org .opensearch .common .inject .Inject ;
66- import org .opensearch .common .xcontent .XContentType ;
67- import org .opensearch .core .rest .RestStatus ;
68- import org .opensearch .rest .BytesRestResponse ;
69- import org .opensearch .rest .RestChannel ;
70- import org .opensearch .rest .RestRequest ;
71- import org .opensearch .rest .RestRequest .Method ;
72- import org .opensearch .security .configuration .ConfigurationRepository ;
73- import org .opensearch .security .dlic .rest .support .Utils ;
74- import org .opensearch .security .dlic .rest .validation .ValidationResult ;
75- import org .opensearch .security .securityconf .impl .CType ;
76- import org .opensearch .security .support .ConfigHelper ;
77- import org .opensearch .threadpool .ThreadPool ;
78-
79- import com .fasterxml .jackson .databind .JsonNode ;
80- import com .fasterxml .jackson .databind .node .ArrayNode ;
81- import com .fasterxml .jackson .databind .node .JsonNodeFactory ;
82- import com .fasterxml .jackson .databind .node .ObjectNode ;
83- import com .flipkart .zjsonpatch .DiffFlags ;
84- import com .flipkart .zjsonpatch .JsonDiff ;
85- import com .google .common .collect .ImmutableList ;
8661
62+ import static org .opensearch .security .dlic .rest .api .Responses .badRequestMessage ;
63+ import static org .opensearch .security .dlic .rest .api .Responses .ok ;
64+ import static org .opensearch .security .dlic .rest .api .Responses .response ;
65+ import static org .opensearch .security .dlic .rest .support .Utils .addRoutesPrefix ;
66+ import static org .opensearch .security .dlic .rest .support .Utils .withIOException ;
8767
8868public class ConfigUpgradeApiAction extends AbstractApiAction {
8969
9070 private final static Logger LOGGER = LogManager .getLogger (ConfigUpgradeApiAction .class );
9171
9272 private final static Set <CType > SUPPORTED_CTYPES = ImmutableSet .of (CType .ROLES );
9373
94- private static final List <Route > routes = addRoutesPrefix (ImmutableList .of (
95- new Route (Method .GET , "/_upgrade_check" ),
96- new Route (Method .POST , "/_upgrade_perform" )
97- ));
74+ private static final List <Route > routes = addRoutesPrefix (
75+ ImmutableList .of (new Route (Method .GET , "/_upgrade_check" ), new Route (Method .POST , "/_upgrade_perform" ))
76+ );
9877
9978 @ Inject
10079 public ConfigUpgradeApiAction (
@@ -109,64 +88,66 @@ public ConfigUpgradeApiAction(
10988 }
11089
11190 void handleCanUpgrade (final RestChannel channel , final RestRequest request , final Client client ) throws IOException {
112- withIOException (() -> getConfigurations (request )
113- .map (this ::configurationDifferences ))
114- .valid (differencesList -> {
115- final var canUpgrade = differencesList .stream ().anyMatch (entry -> entry .v2 ().size () > 0 );
116-
117- final ObjectNode response = JsonNodeFactory .instance .objectNode ();
118- response .put ("can_upgrade" , canUpgrade );
119-
120- if (canUpgrade ) {
121- final ObjectNode differences = JsonNodeFactory .instance .objectNode ();
122- differencesList .forEach (t -> {
123- differences .set (t .v1 ().toLCString (), t .v2 ());
124- });
125- response .set ("differences" , differences );
126- }
127- channel .sendResponse (new BytesRestResponse (RestStatus .OK , XContentType .JSON .mediaType (), response .toPrettyString ()));
128- })
129- .error ((status , toXContent ) -> response (channel , status , toXContent ));
91+ withIOException (() -> getConfigurations (request ).map (this ::configurationDifferences )).valid (differencesList -> {
92+ final var canUpgrade = differencesList .stream ().anyMatch (entry -> entry .v2 ().size () > 0 );
93+
94+ final ObjectNode response = JsonNodeFactory .instance .objectNode ();
95+ response .put ("can_upgrade" , canUpgrade );
96+
97+ if (canUpgrade ) {
98+ final ObjectNode differences = JsonNodeFactory .instance .objectNode ();
99+ differencesList .forEach (t -> { differences .set (t .v1 ().toLCString (), t .v2 ()); });
100+ response .set ("differences" , differences );
101+ }
102+ channel .sendResponse (new BytesRestResponse (RestStatus .OK , XContentType .JSON .mediaType (), response .toPrettyString ()));
103+ }).error ((status , toXContent ) -> response (channel , status , toXContent ));
130104 }
131105
132106 private void handleUpgrade (final RestChannel channel , final RestRequest request , final Client client ) throws IOException {
133- withIOException (() -> getConfigurations (request )
134- .map (this ::configurationDifferences ))
135- .map (diffs -> applyDifferences (request , diffs ))
107+ withIOException (() -> getConfigurations (request ).map (this ::configurationDifferences )).map (diffs -> applyDifferences (request , diffs ))
136108 .valid (updatedResources -> {
137109 ok (channel , "Applied all differences: " + updatedResources );
138110 })
139111 .error ((status , toXContent ) -> response (channel , status , toXContent ));
140112 }
141113
142- ValidationResult <List <Tuple <CType , Map <String , List <String >>>>> applyDifferences (final RestRequest request , final List <Tuple <CType , JsonNode >> differencesToUpdate ) throws IOException {
114+ ValidationResult <List <Tuple <CType , Map <String , List <String >>>>> applyDifferences (
115+ final RestRequest request ,
116+ final List <Tuple <CType , JsonNode >> differencesToUpdate
117+ ) throws IOException {
143118 final var updatedResources = new ArrayList <ValidationResult <Tuple <CType , Map <String , List <String >>>>>();
144119 for (final Tuple <CType , JsonNode > difference : differencesToUpdate ) {
145- updatedResources .add (loadConfiguration (difference .v1 (), false , false )
146- .map (configuration -> patchEntities (request , difference .v2 (), SecurityConfiguration .of (null , configuration ))
147- .map (patchResults -> {
148- final var items = new HashMap <String , String >();
149- difference .v2 ().forEach (node -> {
150- final var item = pathRoot (node );
151- final var operation = node .get ("op" ).asText ();
152- if (items .containsKey (item ) && !items .get (item ).equals (operation )) {
153- items .put (item , "modified" );
154- } else {
155- items .put (item , operation );
156- }
157- });
158-
159- final var itemsGroupedByOperation = items .entrySet ().stream ().collect (Collectors .groupingBy (Map .Entry ::getValue , Collectors .mapping (Map .Entry ::getKey , Collectors .toList ())));
160-
161- return ValidationResult .success (new Tuple <>(difference .v1 (), itemsGroupedByOperation ));
162- })
120+ updatedResources .add (
121+ loadConfiguration (difference .v1 (), false , false ).map (
122+ configuration -> patchEntities (request , difference .v2 (), SecurityConfiguration .of (null , configuration )).map (
123+ patchResults -> {
124+ final var items = new HashMap <String , String >();
125+ difference .v2 ().forEach (node -> {
126+ final var item = pathRoot (node );
127+ final var operation = node .get ("op" ).asText ();
128+ if (items .containsKey (item ) && !items .get (item ).equals (operation )) {
129+ items .put (item , "modified" );
130+ } else {
131+ items .put (item , operation );
132+ }
133+ });
134+
135+ final var itemsGroupedByOperation = items .entrySet ()
136+ .stream ()
137+ .collect (
138+ Collectors .groupingBy (Map .Entry ::getValue , Collectors .mapping (Map .Entry ::getKey , Collectors .toList ()))
139+ );
140+
141+ return ValidationResult .success (new Tuple <>(difference .v1 (), itemsGroupedByOperation ));
142+ }
143+ )
163144 )
164145 );
165146 }
166147
167148 return ValidationResult .merge (updatedResources );
168149 }
169-
150+
170151 private ValidationResult <List <Tuple <CType , JsonNode >>> configurationDifferences (final Set <CType > configurations ) throws IOException {
171152 final var differences = new ArrayList <ValidationResult <Tuple <CType , JsonNode >>>();
172153 for (final var configuration : configurations ) {
@@ -186,15 +167,16 @@ private ValidationResult<Tuple<CType, JsonNode>> computeDifferenceToUpdate(final
186167
187168 ValidationResult <Set <CType >> getConfigurations (final RestRequest request ) {
188169 final String [] configs = request .paramAsStringArray ("configs" , null );
189-
190- final var configurations = Optional .ofNullable (configs )
191- .map (CType ::fromStringValues )
192- .orElse (SUPPORTED_CTYPES );
170+
171+ final var configurations = Optional .ofNullable (configs ).map (CType ::fromStringValues ).orElse (SUPPORTED_CTYPES );
193172
194173 if (!configurations .stream ().allMatch (SUPPORTED_CTYPES ::contains )) {
195174 // Remove all supported configurations
196175 configurations .removeAll (SUPPORTED_CTYPES );
197- return ValidationResult .error (RestStatus .BAD_REQUEST , badRequestMessage ("Unsupported configurations for upgrade" + configurations ));
176+ return ValidationResult .error (
177+ RestStatus .BAD_REQUEST ,
178+ badRequestMessage ("Unsupported configurations for upgrade" + configurations )
179+ );
198180 }
199181
200182 return ValidationResult .success (configurations );
@@ -305,7 +287,6 @@ public ValidationResult<JsonNode> validate(RestRequest request, JsonNode jsonCon
305287 return super .validate (request , jsonContent );
306288 }
307289
308-
309290 }
310291
311292}
0 commit comments