xref: /OpenGrok/opengrok-web/src/main/java/org/opengrok/web/api/v1/controller/ConfigurationController.java (revision 2f93c05f7383b8c5fc9e10bf9d6c390e686694a8)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * See LICENSE.txt included in this distribution for the specific
9  * language governing permissions and limitations under the License.
10  *
11  * When distributing Covered Code, include this CDDL HEADER in each
12  * file and include the License file at LICENSE.txt.
13  * If applicable, add the following below this CDDL HEADER, with the
14  * fields enclosed by brackets "[]" replaced with your own identifying
15  * information: Portions Copyright [yyyy] [name of copyright owner]
16  *
17  * CDDL HEADER END
18  */
19 
20 /*
21  * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
22  * Portions Copyright (c) 2017, 2020, Chris Fraire <cfraire@me.com>.
23  */
24 package org.opengrok.web.api.v1.controller;
25 
26 import jakarta.inject.Inject;
27 import jakarta.servlet.http.HttpServletRequest;
28 import jakarta.ws.rs.Consumes;
29 import jakarta.ws.rs.GET;
30 import jakarta.ws.rs.POST;
31 import jakarta.ws.rs.PUT;
32 import jakarta.ws.rs.Path;
33 import jakarta.ws.rs.PathParam;
34 import jakarta.ws.rs.Produces;
35 import jakarta.ws.rs.QueryParam;
36 import jakarta.ws.rs.WebApplicationException;
37 import jakarta.ws.rs.core.Context;
38 import jakarta.ws.rs.core.MediaType;
39 import jakarta.ws.rs.core.Response;
40 import org.opengrok.indexer.configuration.CommandTimeoutType;
41 import org.opengrok.indexer.configuration.RuntimeEnvironment;
42 import org.opengrok.indexer.util.ClassUtil;
43 import org.opengrok.web.api.ApiTask;
44 import org.opengrok.web.api.ApiTaskManager;
45 import org.opengrok.web.api.v1.suggester.provider.service.SuggesterService;
46 
47 import java.io.IOException;
48 import java.io.InputStream;
49 import java.nio.charset.StandardCharsets;
50 
51 import static org.opengrok.web.api.v1.controller.ConfigurationController.PATH;
52 
53 @Path(PATH)
54 public class ConfigurationController {
55 
56     private final RuntimeEnvironment env = RuntimeEnvironment.getInstance();
57 
58     public static final String PATH = "/configuration";
59 
60     @Inject
61     private SuggesterService suggesterService;
62 
63     @GET
64     @Produces(MediaType.APPLICATION_XML)
get()65     public String get() {
66         return env.getConfigurationXML();
67     }
68 
69     @PUT
70     @Consumes(MediaType.APPLICATION_XML)
set(@ontext HttpServletRequest request, @QueryParam("reindex") final boolean reindex)71     public Response set(@Context HttpServletRequest request,
72                         @QueryParam("reindex") final boolean reindex) throws IOException {
73 
74         String body;
75         try (InputStream inputStream = request.getInputStream()) {
76             body = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);
77         }
78 
79         return ApiTaskManager.getInstance().submitApiTask(PATH,
80                 new ApiTask(request.getRequestURI(), () -> {
81                     env.applyConfig(body, reindex, CommandTimeoutType.RESTFUL);
82                     suggesterService.refresh();
83                     return null;
84                 }));
85     }
86 
87     @GET
88     @Path("/{field}")
89     @Produces(MediaType.APPLICATION_JSON)
getField(@athParam"field") final String field)90     public Object getField(@PathParam("field") final String field) {
91         return getConfigurationValueException(field);
92     }
93 
94     @PUT
95     @Path("/{field}")
setField(@ontext HttpServletRequest request, @PathParam("field") final String field, final String value)96     public Response setField(@Context HttpServletRequest request,
97                              @PathParam("field") final String field, final String value) {
98 
99         setConfigurationValueException(field, value);
100 
101         return ApiTaskManager.getInstance().submitApiTask(PATH,
102                 new ApiTask(request.getRequestURI(), () -> {
103                     // apply the configuration - let the environment reload the configuration if necessary
104                     env.applyConfig(false, CommandTimeoutType.RESTFUL);
105                     suggesterService.refresh();
106                     return null;
107                 }));
108     }
109 
110     @POST
111     @Path("/authorization/reload")
112     public Response reloadAuthorization(@Context HttpServletRequest request) {
113         return ApiTaskManager.getInstance().submitApiTask("authorization",
114                 new ApiTask(request.getRequestURI(),
115                         () -> {
116                             env.getAuthorizationFramework().reload();
117                             return null;
118                         },
119                         Response.Status.NO_CONTENT));
120     }
121 
122     private Object getConfigurationValueException(String fieldName) throws WebApplicationException {
123         final IOException[] capture = new IOException[1];
124         final int IOE_INDEX = 0;
125         Object result = env.syncReadConfiguration(configuration -> {
126             try {
127                 return ClassUtil.getFieldValue(configuration, fieldName);
128             } catch (IOException ex) {
129                 capture[IOE_INDEX] = ex;
130                 return null;
131             }
132         });
133         if (capture[IOE_INDEX] != null) {
134             throw new WebApplicationException(capture[IOE_INDEX], Response.Status.BAD_REQUEST);
135         }
136         return result;
137     }
138 
139     private void setConfigurationValueException(String fieldName, String value)
140             throws WebApplicationException {
141 
142         final IOException[] capture = new IOException[1];
143         final int IOE_INDEX = 0;
144         env.syncWriteConfiguration(value, (configuration, v) -> {
145             try {
146                 ClassUtil.setFieldValue(configuration, fieldName, v);
147             } catch (IOException ex) {
148                 capture[IOE_INDEX] = ex;
149             }
150         });
151         if (capture[IOE_INDEX] != null) {
152             throw new WebApplicationException(capture[IOE_INDEX], Response.Status.BAD_REQUEST);
153         }
154     }
155 }
156