View Javadoc
1   /*
2    * This file is part of Waarp Project (named also Waarp or GG).
3    *
4    *  Copyright (c) 2019, Waarp SAS, and individual contributors by the @author
5    *  tags. See the COPYRIGHT.txt in the distribution for a full listing of
6    * individual contributors.
7    *
8    *  All Waarp Project is free software: you can redistribute it and/or
9    * modify it under the terms of the GNU General Public License as published by
10   * the Free Software Foundation, either version 3 of the License, or (at your
11   * option) any later version.
12   *
13   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY
14   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
15   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16   *
17   *  You should have received a copy of the GNU General Public License along with
18   * Waarp . If not, see <http://www.gnu.org/licenses/>.
19   */
20  package org.waarp.openr66.protocol.http.rest.handler;
21  
22  import com.fasterxml.jackson.databind.node.ArrayNode;
23  import com.fasterxml.jackson.databind.node.ObjectNode;
24  import io.netty.handler.codec.http.HttpResponseStatus;
25  import org.waarp.common.database.data.AbstractDbData;
26  import org.waarp.common.exception.InvalidArgumentException;
27  import org.waarp.common.json.JsonHandler;
28  import org.waarp.common.logging.WaarpLogger;
29  import org.waarp.common.logging.WaarpLoggerFactory;
30  import org.waarp.gateway.kernel.exception.HttpIncorrectRequestException;
31  import org.waarp.gateway.kernel.exception.HttpInvalidAuthenticationException;
32  import org.waarp.gateway.kernel.rest.DataModelRestMethodHandler.COMMAND_TYPE;
33  import org.waarp.gateway.kernel.rest.HttpRestHandler;
34  import org.waarp.gateway.kernel.rest.HttpRestHandler.METHOD;
35  import org.waarp.gateway.kernel.rest.RestArgument;
36  import org.waarp.gateway.kernel.rest.RestConfiguration;
37  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoCorrectAuthenticationException;
38  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
39  import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
40  import org.waarp.openr66.protocol.exception.OpenR66ProtocolSystemException;
41  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler;
42  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler.RESTHANDLERS;
43  import org.waarp.openr66.protocol.localhandler.ServerActions;
44  import org.waarp.openr66.protocol.localhandler.packet.json.ConfigExportJsonPacket;
45  import org.waarp.openr66.protocol.localhandler.packet.json.ConfigExportResponseJsonPacket;
46  import org.waarp.openr66.protocol.localhandler.packet.json.ConfigImportJsonPacket;
47  import org.waarp.openr66.protocol.localhandler.packet.json.ConfigImportResponseJsonPacket;
48  import org.waarp.openr66.protocol.localhandler.packet.json.JsonPacket;
49  
50  /**
51   * Configuration Http REST interface: http://host/config?... +
52   * ConfigExportJsonPacket or
53   * ConfigImportJsonPacket as GET or PUT
54   */
55  public class HttpRestConfigR66Handler extends HttpRestAbstractR66Handler {
56  
57    public static final String BASEURI = "config";
58    /**
59     * Internal Logger
60     */
61    private static final WaarpLogger logger =
62        WaarpLoggerFactory.getLogger(HttpRestConfigR66Handler.class);
63  
64    public HttpRestConfigR66Handler(final RestConfiguration config,
65                                    final METHOD... methods) {
66      super(BASEURI, config, METHOD.OPTIONS);
67      setIntersectionMethods(methods, METHOD.GET, METHOD.PUT);
68    }
69  
70    @Override
71    public final void endParsingRequest(final HttpRestHandler handler,
72                                        final RestArgument arguments,
73                                        final RestArgument result,
74                                        final Object body)
75        throws HttpIncorrectRequestException, HttpInvalidAuthenticationException {
76      try {
77        HttpRestV1Utils.checkSanity(arguments);
78      } catch (final InvalidArgumentException e) {
79        throw new HttpIncorrectRequestException("Issue on values", e);
80      }
81      logger.debug("debug: {} ### {}", arguments, result);
82      if (body != null) {
83        logger.debug("Obj: {}", body);
84      }
85      handler.setWillClose(false);
86      final ServerActions serverHandler =
87          ((HttpRestR66Handler) handler).getServerHandler();
88      // now action according to body
89      final JsonPacket json = (JsonPacket) body;
90      if (json == null) {
91        result.setDetail("not enough information");
92        setError(handler, result, HttpResponseStatus.BAD_REQUEST);
93        return;
94      }
95      result.getAnswer()
96            .put(AbstractDbData.JSON_MODEL, RESTHANDLERS.Config.name());
97      try {
98        if (json instanceof ConfigExportJsonPacket &&
99            arguments.getMethod() == METHOD.GET) {//
100         result.setCommand(ACTIONS_TYPE.ExportConfig.name());
101         // host, rule, business, alias, roles
102         final ConfigExportJsonPacket node = (ConfigExportJsonPacket) json;
103         final boolean bhost = node.isHost();
104         final boolean brule = node.isRule();
105         final boolean bbusiness = node.isBusiness();
106         final boolean balias = node.isAlias();
107         final boolean broles = node.isRoles();
108         final String[] sresult =
109             serverHandler.configExport(bhost, brule, bbusiness, balias, broles);
110         // Now answer
111         final ConfigExportResponseJsonPacket resp =
112             new ConfigExportResponseJsonPacket();
113         resp.fromJson(node);
114         resp.setFilehost(sresult[0]);
115         resp.setFilerule(sresult[1]);
116         resp.setFilebusiness(sresult[2]);
117         resp.setFilealias(sresult[3]);
118         resp.setFileroles(sresult[4]);
119         if (resp.getFilerule() != null || resp.getFilehost() != null ||
120             resp.getFilebusiness() != null || resp.getFilealias() != null ||
121             resp.getFileroles() != null) {
122           setOk(handler, result, resp, HttpResponseStatus.OK);
123         } else {
124           result.setDetail("Export configuration in error");
125           setError(handler, result, resp, HttpResponseStatus.NOT_ACCEPTABLE);
126         }
127       } else if (json instanceof ConfigImportJsonPacket &&
128                  arguments.getMethod() == METHOD.PUT) {//
129         result.setCommand(ACTIONS_TYPE.ImportConfig.name());
130         final ConfigImportResponseJsonPacket resp =
131             serverHandler.configImport((ConfigImportJsonPacket) json);
132         if (resp.isImportedhost() || resp.isImportedrule() ||
133             resp.isImportedbusiness() || resp.isImportedalias() ||
134             resp.isImportedroles()) {
135           setOk(handler, result, resp, HttpResponseStatus.OK);
136         } else {
137           result.setDetail("Import configuration in error");
138           setError(handler, result, resp, HttpResponseStatus.NOT_ACCEPTABLE);
139         }
140       } else {
141         logger.info("Validation is ignored: {}", json);
142         result.setDetail("Unknown command");
143         setError(handler, result, json, HttpResponseStatus.PRECONDITION_FAILED);
144       }
145     } catch (final OpenR66ProtocolNotAuthenticatedException e) {
146       throw new HttpInvalidAuthenticationException(e);
147     } catch (final OpenR66ProtocolSystemException e) {
148       throw new HttpIncorrectRequestException(e);
149     } catch (OpenR66ProtocolNoCorrectAuthenticationException e) {
150       throw new HttpInvalidAuthenticationException(e);
151     }
152   }
153 
154   @Override
155   protected final ArrayNode getDetailedAllow() {
156     final ArrayNode node = JsonHandler.createArrayNode();
157 
158     if (methods.contains(METHOD.GET)) {
159       final ConfigExportJsonPacket node3 = new ConfigExportJsonPacket();
160       node3.setRequestUserPacket();
161       node3.setComment("ConfigExport request (GET)");
162       final ObjectNode node2;
163       final ArrayNode node1 = JsonHandler.createArrayNode();
164       final ConfigExportResponseJsonPacket resp =
165           new ConfigExportResponseJsonPacket();
166       resp.setComment("ConfigExport response");
167       resp.setFilealias("filepath");
168       resp.setFilebusiness("filepath");
169       resp.setFilehost("filepath");
170       resp.setFileroles("filepath");
171       resp.setFilerule("filepath");
172       resp.setRequestUserPacket();
173       try {
174         node1.add(resp.createObjectNode());
175         node2 = RestArgument.fillDetailedAllow(METHOD.GET, path,
176                                                ACTIONS_TYPE.ExportConfig.name(),
177                                                node3.createObjectNode(), node1);
178         node.add(node2);
179       } catch (final OpenR66ProtocolPacketException ignored) {
180         // ignore
181       }
182     }
183     if (methods.contains(METHOD.PUT)) {
184       final ConfigImportJsonPacket node4 = new ConfigImportJsonPacket();
185       node4.setRequestUserPacket();
186       node4.setComment(
187           "ConfigImport request (PUT) where items are either set through transfer Id, either set directly with a filename");
188       node4.setAlias("AliasFilename if not through TransferId");
189       node4.setBusiness("BusinessFilename if not through TransferId");
190       node4.setHost("HostFilename if not through TransferId");
191       node4.setRoles("RolesFilename if not through TransferId");
192       node4.setRule("RuleFilename if not through TransferId");
193       final ConfigImportResponseJsonPacket resp2 =
194           new ConfigImportResponseJsonPacket();
195       resp2.setComment("ConfigImport response");
196       resp2.setAlias("filepath");
197       resp2.setBusiness("filepath");
198       resp2.setHost("filepath");
199       resp2.setRoles("filepath");
200       resp2.setRule("filepath");
201       resp2.setRequestUserPacket();
202       final ArrayNode node1 = JsonHandler.createArrayNode();
203       try {
204         node1.add(resp2.createObjectNode());
205         final ObjectNode node2 =
206             RestArgument.fillDetailedAllow(METHOD.PUT, path,
207                                            ACTIONS_TYPE.ImportConfig.name(),
208                                            node4.createObjectNode(), node1);
209         node.add(node2);
210       } catch (final OpenR66ProtocolPacketException ignored) {
211         // ignore
212       }
213     }
214 
215     final ObjectNode node2 =
216         RestArgument.fillDetailedAllow(METHOD.OPTIONS, path,
217                                        COMMAND_TYPE.OPTIONS.name(), null, null);
218     node.add(node2);
219 
220     return node;
221   }
222 }