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.ErrorCode;
38  import org.waarp.openr66.context.R66Result;
39  import org.waarp.openr66.context.R66Session;
40  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNoCorrectAuthenticationException;
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.json.BusinessRequestJsonPacket;
47  import org.waarp.openr66.protocol.localhandler.packet.json.JsonPacket;
48  import org.waarp.openr66.protocol.utils.R66Future;
49  
50  import static org.waarp.openr66.context.R66FiniteDualStates.*;
51  
52  /**
53   * Business Http REST interface: http://host/business?... +
54   * BusinessRequestJsonPacket as GET
55   */
56  public class HttpRestBusinessR66Handler extends HttpRestAbstractR66Handler {
57  
58    public static final String BASEURI = "business";
59    /**
60     * Internal Logger
61     */
62    private static final WaarpLogger logger =
63        WaarpLoggerFactory.getLogger(HttpRestBusinessR66Handler.class);
64  
65    public HttpRestBusinessR66Handler(final RestConfiguration config,
66                                      final METHOD... methods) {
67      super(BASEURI, config, METHOD.OPTIONS);
68      setIntersectionMethods(methods, METHOD.GET);
69    }
70  
71    @Override
72    public final void endParsingRequest(final HttpRestHandler handler,
73                                        final RestArgument arguments,
74                                        final RestArgument result,
75                                        final Object body)
76        throws HttpIncorrectRequestException, HttpInvalidAuthenticationException {
77      try {
78        HttpRestV1Utils.checkSanity(arguments);
79      } catch (final InvalidArgumentException e) {
80        throw new HttpIncorrectRequestException("Issue on values", e);
81      }
82      logger.debug("debug: {} ### {}", arguments, result);
83      if (body != null) {
84        logger.debug("Obj: {}", body);
85      }
86      handler.setWillClose(false);
87      final ServerActions serverHandler =
88          ((HttpRestR66Handler) handler).getServerHandler();
89      final R66Session session = serverHandler.getSession();
90      // now action according to body
91      final JsonPacket json = (JsonPacket) body;
92      if (json == null) {
93        result.setDetail("not enough information");
94        setError(handler, result, HttpResponseStatus.BAD_REQUEST);
95        return;
96      }
97      result.getAnswer()
98            .put(AbstractDbData.JSON_MODEL, RESTHANDLERS.Business.name());
99      try {
100       if (json instanceof BusinessRequestJsonPacket) {//
101         result.setCommand(ACTIONS_TYPE.ExecuteBusiness.name());
102         final BusinessRequestJsonPacket node = (BusinessRequestJsonPacket) json;
103         final R66Future future =
104             serverHandler.businessRequest(node.isToApplied(),
105                                           node.getClassName(),
106                                           node.getArguments(),
107                                           node.getExtraArguments(),
108                                           node.getDelay());
109         if (future != null && !future.isSuccess()) {
110           R66Result r66result = future.getResult();
111           if (r66result == null) {
112             r66result =
113                 new R66Result(session, false, ErrorCode.ExternalOp, null);
114           }
115           wrongResult(handler, result, session, node, r66result);
116         } else if (future == null) {
117           final R66Result r66result =
118               new R66Result(session, false, ErrorCode.ExternalOp, null);
119           wrongResult(handler, result, session, node, r66result);
120         } else {
121           final R66Result r66result = future.getResult();
122           if (r66result != null && r66result.getOther() != null) {
123             result.setDetail(r66result.getOther().toString());
124             node.setArguments(r66result.getOther().toString());
125           }
126           setOk(handler, result, json, HttpResponseStatus.OK);
127         }
128       } else {
129         logger.info("Validation is ignored: {}", json);
130         result.setDetail("Unknown command");
131         setError(handler, result, json, HttpResponseStatus.PRECONDITION_FAILED);
132       }
133     } catch (final OpenR66ProtocolNotAuthenticatedException e) {
134       throw new HttpInvalidAuthenticationException(e);
135     } catch (final OpenR66ProtocolNoCorrectAuthenticationException e) {
136       throw new HttpInvalidAuthenticationException(e);
137     }
138   }
139 
140   private void wrongResult(final HttpRestHandler handler,
141                            final RestArgument result, final R66Session session,
142                            final BusinessRequestJsonPacket node,
143                            final R66Result r66result) {
144     logger.info("Task in Error: {} {}", node.getClassName(), r66result);
145     if (!r66result.isAnswered()) {
146       node.setValidated(false);
147       session.newState(ERROR);
148     }
149     result.setDetail("Task in Error:" + node.getClassName() + ' ' + r66result);
150     setError(handler, result, HttpResponseStatus.NOT_ACCEPTABLE);
151   }
152 
153   @Override
154   protected final ArrayNode getDetailedAllow() {
155     final ArrayNode node = JsonHandler.createArrayNode();
156 
157     if (methods.contains(METHOD.GET)) {
158       final BusinessRequestJsonPacket node3 = new BusinessRequestJsonPacket();
159       node3.setRequestUserPacket();
160       node3.setComment("Business execution request (GET)");
161       node3.setClassName("Class name to execute");
162       node3.setArguments("Arguments of the execution");
163       node3.setExtraArguments("Extra arguments");
164       final ObjectNode node2;
165       final ArrayNode node1 = JsonHandler.createArrayNode();
166       try {
167         node1.add(node3.createObjectNode());
168         node2 = RestArgument.fillDetailedAllow(METHOD.GET, path,
169                                                ACTIONS_TYPE.ExecuteBusiness.name(),
170                                                node3.createObjectNode(), node1);
171         node.add(node2);
172       } catch (final OpenR66ProtocolPacketException ignored) {
173         // ignore
174       }
175     }
176     final ObjectNode node2 =
177         RestArgument.fillDetailedAllow(METHOD.OPTIONS, path,
178                                        COMMAND_TYPE.OPTIONS.name(), null, null);
179     node.add(node2);
180 
181     return node;
182   }
183 }