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.context.R66Result;
38  import org.waarp.openr66.database.data.DbTaskRunner;
39  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoCorrectAuthenticationException;
40  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoDataException;
41  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNotAuthenticatedException;
42  import org.waarp.openr66.protocol.exception.OpenR66ProtocolPacketException;
43  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler;
44  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler.RESTHANDLERS;
45  import org.waarp.openr66.protocol.localhandler.ServerActions;
46  import org.waarp.openr66.protocol.localhandler.packet.ValidPacket;
47  import org.waarp.openr66.protocol.localhandler.packet.json.InformationJsonPacket;
48  import org.waarp.openr66.protocol.localhandler.packet.json.JsonPacket;
49  import org.waarp.openr66.protocol.localhandler.packet.json.RestartTransferJsonPacket;
50  import org.waarp.openr66.protocol.localhandler.packet.json.StopOrCancelJsonPacket;
51  import org.waarp.openr66.protocol.localhandler.packet.json.TransferRequestJsonPacket;
52  
53  import java.util.Date;
54  
55  import static org.waarp.common.database.DbConstant.*;
56  
57  /**
58   * Transfer Http REST interface: http://host/control?... + InformationJsonPacket
59   * (should be on Transfer only)
60   * RestartTransferJsonPacket StopOrCancelJsonPacket TransferRequestJsonPacket as
61   * GET PUT PUT POST
62   */
63  public class HttpRestControlR66Handler extends HttpRestAbstractR66Handler {
64  
65    public static final String BASEURI = "control";
66    /**
67     * Internal Logger
68     */
69    private static final WaarpLogger logger =
70        WaarpLoggerFactory.getLogger(HttpRestControlR66Handler.class);
71  
72    public HttpRestControlR66Handler(final RestConfiguration config,
73                                     final METHOD... methods) {
74      super(BASEURI, config, METHOD.OPTIONS);
75      setIntersectionMethods(methods, METHOD.GET, METHOD.PUT, METHOD.POST);
76    }
77  
78    @Override
79    public final void endParsingRequest(final HttpRestHandler handler,
80                                        final RestArgument arguments,
81                                        final RestArgument result,
82                                        final Object body)
83        throws HttpIncorrectRequestException, HttpInvalidAuthenticationException {
84      try {
85        HttpRestV1Utils.checkSanity(arguments);
86      } catch (final InvalidArgumentException e) {
87        throw new HttpIncorrectRequestException("Issue on values", e);
88      }
89      logger.debug("debug: {} ### {}", arguments, result);
90      if (body != null) {
91        logger.debug("Obj: {}", body);
92      }
93      handler.setWillClose(false);
94      final ServerActions serverHandler =
95          ((HttpRestR66Handler) handler).getServerHandler();
96      // now action according to body
97      final JsonPacket json = (JsonPacket) body;
98      if (json == null) {
99        result.setDetail("not enough information");
100       setError(handler, result, HttpResponseStatus.BAD_REQUEST);
101       return;
102     }
103     result.getAnswer()
104           .put(AbstractDbData.JSON_MODEL, RESTHANDLERS.Control.name());
105     final METHOD method = arguments.getMethod();
106     try {
107       if (json instanceof InformationJsonPacket && method == METHOD.GET) {//
108         final InformationJsonPacket node = (InformationJsonPacket) json;
109         if (node.isIdRequest()) {
110           result.setCommand(ACTIONS_TYPE.GetTransferInformation.name());
111           final ValidPacket validPacket;
112           if (node.isIdRequest()) {
113             validPacket =
114                 serverHandler.informationRequest(node.getId(), node.isTo(),
115                                                  node.getRulename(), true);
116           } else {
117             validPacket = serverHandler.informationFile(node.getRequest(),
118                                                         node.getRulename(),
119                                                         node.getFilename(),
120                                                         true);
121           }
122           if (validPacket != null) {
123             final ObjectNode resp =
124                 JsonHandler.getFromString(validPacket.getSheader());
125             handler.setStatus(HttpResponseStatus.OK);
126             result.setResult(HttpResponseStatus.OK);
127             result.getResults().add(resp);
128           } else {
129             result.setDetail("Error during information request");
130             setError(handler, result, HttpResponseStatus.NOT_ACCEPTABLE);
131           }
132         } else {
133           result.setCommand(ACTIONS_TYPE.GetInformation.name());
134           result.setDetail(
135               "Error: FileInformation is not applicable with URI " + BASEURI);
136           setError(handler, result, HttpResponseStatus.NOT_ACCEPTABLE);
137         }
138       } else if (json instanceof RestartTransferJsonPacket &&
139                  method == METHOD.PUT) {//
140         result.setCommand(ACTIONS_TYPE.RestartTransfer.name());
141         final RestartTransferJsonPacket node = (RestartTransferJsonPacket) json;
142         final R66Result r66result =
143             serverHandler.requestRestart(node.getRequested(),
144                                          node.getRequester(),
145                                          node.getSpecialid(),
146                                          node.getRestarttime());
147         if (serverHandler.isCodeValid(r66result.getCode())) {
148           result.setDetail("Restart Transfer done");
149           setOk(handler, result, node, HttpResponseStatus.OK);
150         } else {
151           result.setDetail("Restart Transfer in error");
152           setError(handler, result, node, HttpResponseStatus.NOT_ACCEPTABLE);
153         }
154       } else if (json instanceof StopOrCancelJsonPacket &&
155                  method == METHOD.PUT) {//
156         result.setCommand(ACTIONS_TYPE.StopOrCancelTransfer.name());
157         final StopOrCancelJsonPacket node = (StopOrCancelJsonPacket) json;
158         final R66Result resulttest;
159         if (node.getRequested() == null || node.getRequester() == null ||
160             node.getSpecialid() == ILLEGALVALUE) {
161           result.setDetail("Not enough argument passed to identify a transfer");
162           setError(handler, result, node, HttpResponseStatus.NOT_FOUND);
163         } else {
164           final String reqd = node.getRequested();
165           final String reqr = node.getRequester();
166           final long id = node.getSpecialid();
167           resulttest =
168               serverHandler.stopOrCancel(node.getRequestUserPacket(), reqd,
169                                          reqr, id);
170           result.setDetail(resulttest.getCode().getMesg());
171           setOk(handler, result, node, HttpResponseStatus.OK);
172         }
173       } else if (json instanceof TransferRequestJsonPacket &&
174                  method == METHOD.POST) {
175         result.setCommand(ACTIONS_TYPE.CreateTransfer.name());
176         final TransferRequestJsonPacket node = (TransferRequestJsonPacket) json;
177         final R66Result r66result = serverHandler.transferRequest(node);
178         if (serverHandler.isCodeValid(r66result.getCode())) {
179           result.setDetail("New Transfer registered");
180           setOk(handler, result, node, HttpResponseStatus.OK);
181         } else {
182           result.setDetail("New Transfer cannot be registered");
183           setError(handler, result, HttpResponseStatus.NOT_ACCEPTABLE);
184         }
185       } else {
186         logger.info("Validation is ignored: {}", json);
187         result.setDetail("Unknown command");
188         setError(handler, result, json, HttpResponseStatus.PRECONDITION_FAILED);
189       }
190     } catch (final OpenR66ProtocolNotAuthenticatedException e) {
191       throw new HttpInvalidAuthenticationException(e);
192     } catch (final OpenR66ProtocolNoDataException e) {
193       throw new HttpIncorrectRequestException(e);
194     } catch (OpenR66ProtocolNoCorrectAuthenticationException e) {
195       throw new HttpInvalidAuthenticationException(e);
196     }
197   }
198 
199   @Override
200   protected final ArrayNode getDetailedAllow() {
201     final ArrayNode node = JsonHandler.createArrayNode();
202 
203     if (methods.contains(METHOD.GET)) {
204       final InformationJsonPacket node3 =
205           new InformationJsonPacket(Long.MIN_VALUE, false, "remoteHost");
206       node3.setComment("Information on Transfer request (GET)");
207       final ArrayNode node1 = JsonHandler.createArrayNode();
208       final ObjectNode node1b = JsonHandler.createObjectNode();
209       node1b.put(AbstractDbData.JSON_MODEL, DbTaskRunner.class.getSimpleName());
210       for (final DbTaskRunner.Columns column : DbTaskRunner.Columns.values()) {
211         node1b.put(column.name(), DbTaskRunner.dbTypes[column.ordinal()]);
212       }
213       node1.add(node1b);
214       final ObjectNode node2;
215       try {
216         node2 = RestArgument.fillDetailedAllow(METHOD.GET, path,
217                                                ACTIONS_TYPE.GetTransferInformation.name(),
218                                                node3.createObjectNode(), node1);
219         node.add(node2);
220       } catch (final OpenR66ProtocolPacketException ignored) {
221         // ignore
222       }
223     }
224     if (methods.contains(METHOD.PUT)) {
225       final RestartTransferJsonPacket node4 = new RestartTransferJsonPacket();
226       node4.setRequestUserPacket();
227       node4.setComment("Restart Transfer request (PUT)");
228       node4.setRequested("Requested host");
229       node4.setRequester("Requester host");
230       node4.setRestarttime(new Date());
231       ArrayNode node1 = JsonHandler.createArrayNode();
232       try {
233         node1.add(node4.createObjectNode());
234         final ObjectNode node2 =
235             RestArgument.fillDetailedAllow(METHOD.PUT, path,
236                                            ACTIONS_TYPE.RestartTransfer.name(),
237                                            node4.createObjectNode(), node1);
238         node.add(node2);
239       } catch (final OpenR66ProtocolPacketException ignored) {
240         // ignore
241       }
242       final StopOrCancelJsonPacket node5 = new StopOrCancelJsonPacket();
243       node5.setRequestUserPacket();
244       node5.setComment("Stop Or Cancel request (PUT)");
245       node5.setRequested("Requested host");
246       node5.setRequester("Requester host");
247       node1 = JsonHandler.createArrayNode();
248       try {
249         node1.add(node5.createObjectNode());
250         final ObjectNode node2 =
251             RestArgument.fillDetailedAllow(METHOD.PUT, path,
252                                            ACTIONS_TYPE.StopOrCancelTransfer.name(),
253                                            node5.createObjectNode(), node1);
254         node.add(node2);
255       } catch (final OpenR66ProtocolPacketException ignored) {
256         // ignore
257       }
258     }
259     if (methods.contains(METHOD.POST)) {
260       final TransferRequestJsonPacket node6 = new TransferRequestJsonPacket();
261       node6.setRequestUserPacket();
262       node6.setComment("Transfer Request (POST)");
263       node6.setFilename("Filename");
264       node6.setFileInformation("File information");
265       node6.setRequested("Requested host");
266       node6.setRulename("Rulename");
267       node6.setStart(new Date());
268       final ArrayNode node1 = JsonHandler.createArrayNode();
269       try {
270         node1.add(node6.createObjectNode());
271         final ObjectNode node2 =
272             RestArgument.fillDetailedAllow(METHOD.POST, path,
273                                            ACTIONS_TYPE.CreateTransfer.name(),
274                                            node6.createObjectNode(), node1);
275         node.add(node2);
276       } catch (final OpenR66ProtocolPacketException ignored) {
277         // ignore
278       }
279     }
280 
281     final ObjectNode node2 =
282         RestArgument.fillDetailedAllow(METHOD.OPTIONS, path,
283                                        COMMAND_TYPE.OPTIONS.name(), null, null);
284     node.add(node2);
285 
286     return node;
287   }
288 }