001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.microservice.resources;
014
015import static javax.servlet.http.HttpServletResponse.*;
016import static org.apache.juneau.dto.html5.HtmlBuilder.*;
017import static org.apache.juneau.http.HttpMethodName.*;
018
019import java.io.*;
020import java.util.Map;
021
022import org.apache.juneau.*;
023import org.apache.juneau.dto.html5.*;
024import org.apache.juneau.rest.*;
025import org.apache.juneau.rest.annotation.*;
026import org.apache.juneau.rest.annotation.Body;
027
028/**
029 * Shows contents of the microservice configuration file.
030 */
031@RestResource(
032   path="/config",
033   title="Configuration",
034   description="Contents of configuration file.",
035   htmldoc=@HtmlDoc(
036      navlinks={
037         "up: request:/..",
038         "options: servlet:/?method=OPTIONS",
039         "edit: servlet:/edit"
040      }
041   )
042)
043public class ConfigResource extends BasicRestServlet {
044   private static final long serialVersionUID = 1L;
045
046   /**
047    * [GET /] - Show contents of config file.
048    * 
049    * @return The config file.
050    * @throws Exception
051    */
052   @RestMethod(name=GET, path="/", description="Show contents of config file.")
053   public ObjectMap getConfig() throws Exception {
054      return getServletConfig().getConfig().asMap();
055   }
056
057   /**
058    * [GET /edit] - Show config file edit page.
059    * 
060    * @param req The HTTP request.
061    * @return The config file as a reader resource.
062    * @throws Exception
063    */
064   @RestMethod(name=GET, path="/edit", description="Edit config file.")
065   public Form getConfigEditForm(RestRequest req) throws Exception {
066      return form().id("form").action("servlet:/").method("POST").enctype("application/x-www-form-urlencoded").children(
067         div()._class("data").children(
068            table(
069               tr(td().style("text-align:right").children(button("submit","Submit"),button("reset","Reset"))),
070               tr(th().child("Contents")),
071               tr(th().child(
072                  textarea().name("contents").rows(40).cols(120).style("white-space:pre;word-wrap:normal;overflow-x:scroll;font-family:monospace;")
073                     .text(getServletConfig().getConfig().toString()))
074               )
075            )
076         )
077      );
078   }
079
080   /**
081    * [GET /{section}] - Show config file section.
082    * 
083    * @param section The section name.
084    * @return The config file section.
085    * @throws Exception
086    */
087   @RestMethod(name=GET, path="/{section}",
088      description="Show config file section.",
089      swagger={
090         "parameters:[",
091            "{name:'section',in:'path',description:'Section name.'}",
092         "]"
093      }
094   )
095   public ObjectMap getConfigSection(@Path("section") String section) throws Exception {
096      return getSection(section);
097   }
098
099   /**
100    * [GET /{section}/{key}] - Show config file entry.
101    * 
102    * @param section The section name.
103    * @param key The section key.
104    * @return The value of the config file entry.
105    * @throws Exception
106    */
107   @RestMethod(name=GET, path="/{section}/{key}",
108      description="Show config file entry.",
109      swagger={
110         "parameters:[",
111            "{name:'section',in:'path',description:'Section name.'},",
112            "{name:'key',in:'path',description:'Entry name.'}",
113         "]"
114      }
115   )
116   public String getConfigEntry(@Path("section") String section, @Path("key") String key) throws Exception {
117      return getSection(section).getString(key);
118   }
119
120   /**
121    * [POST /] - Sets contents of config file from a FORM post.
122    * 
123    * @param contents The new contents of the config file.
124    * @return The new config file contents.
125    * @throws Exception
126    */
127   @RestMethod(name=POST, path="/",
128      description="Sets contents of config file from a FORM post.",
129      swagger={
130         "parameters:[",
131            "{name:'contents',in:'formData',description:'New contents in INI file format.'}",
132         "]"
133      }
134   )
135   public ObjectMap setConfigContentsFormPost(@FormData("contents") String contents) throws Exception {
136      return setConfigContents(new StringReader(contents));
137   }
138
139   /**
140    * [PUT /] - Sets contents of config file.
141    * 
142    * @param contents The new contents of the config file.
143    * @return The new config file contents.
144    * @throws Exception
145    */
146   @RestMethod(name=PUT, path="/",
147      description="Sets contents of config file.",
148      swagger={
149         "parameters:[",
150            "{in:'body',description:'New contents in INI file format.'}",
151         "]"
152      }
153   )
154   public ObjectMap setConfigContents(@Body Reader contents) throws Exception {
155      return getServletConfig().getConfig().load(contents, true).asMap();
156   }
157
158   /**
159    * [PUT /{section}] - Add or overwrite a config file section.
160    * 
161    * @param section The section name.
162    * @param contents The new contents of the config file section.
163    * @return The new section.
164    * @throws Exception
165    */
166   @RestMethod(name=PUT, path="/{section}",
167      description="Add or overwrite a config file section.",
168      swagger={
169         "parameters:[",
170            "{name:'section',in:'path',description:'Section name.'}",
171            "{in:'body',description:'New contents for section as a simple map with string keys and values.'}",
172         "]"
173      }
174   )
175   public ObjectMap setConfigSection(@Path("section") String section, @Body Map<String,Object> contents) throws Exception {
176      getServletConfig().getConfig().setSection(section, null, contents);
177      return getSection(section);
178   }
179
180   /**
181    * [PUT /{section}/{key}] - Add or overwrite a config file entry.
182    * 
183    * @param section The section name.
184    * @param key The section key.
185    * @param value The new value.
186    * @return The new value.
187    * @throws Exception
188    */
189   @RestMethod(name=PUT, path="/{section}/{key}",
190      description="Add or overwrite a config file entry.",
191      swagger={
192         "parameters:[",
193            "{name:'section',in:'path',description:'Section name.'}",
194            "{name:'key',in:'path',description:'Entry name.'}",
195            "{in:'body',description:'New value as a string.'}",
196         "]"
197      }
198   )
199   public String setConfigSection(@Path("section") String section, @Path("key") String key, @Body String value) throws Exception {
200      getServletConfig().getConfig().set(section + '/' + key, value);
201      return getSection(section).getString(key);
202   }
203
204   private ObjectMap getSection(String name) throws Exception {
205      ObjectMap m = getServletConfig().getConfig().getSectionAsMap(name);
206      if (m == null)
207         throw new RestException(SC_NOT_FOUND, "Section not found.");
208      return m;
209   }
210}