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.JsonNode;
23  import com.fasterxml.jackson.databind.node.ArrayNode;
24  import com.fasterxml.jackson.databind.node.ObjectNode;
25  import org.joda.time.DateTime;
26  import org.waarp.common.database.DbPreparedStatement;
27  import org.waarp.common.database.data.AbstractDbData;
28  import org.waarp.common.database.exception.WaarpDatabaseException;
29  import org.waarp.common.database.exception.WaarpDatabaseNoConnectionException;
30  import org.waarp.common.database.exception.WaarpDatabaseSqlException;
31  import org.waarp.common.exception.InvalidArgumentException;
32  import org.waarp.common.json.JsonHandler;
33  import org.waarp.common.role.RoleDefault.ROLE;
34  import org.waarp.common.utility.ParametersChecker;
35  import org.waarp.gateway.kernel.exception.HttpForbiddenRequestException;
36  import org.waarp.gateway.kernel.exception.HttpIncorrectRequestException;
37  import org.waarp.gateway.kernel.exception.HttpNotFoundRequestException;
38  import org.waarp.gateway.kernel.rest.DataModelRestMethodHandler;
39  import org.waarp.gateway.kernel.rest.HttpRestHandler;
40  import org.waarp.gateway.kernel.rest.HttpRestHandler.METHOD;
41  import org.waarp.gateway.kernel.rest.RestArgument;
42  import org.waarp.gateway.kernel.rest.RestConfiguration;
43  import org.waarp.openr66.context.R66Session;
44  import org.waarp.openr66.database.data.DbTaskRunner;
45  import org.waarp.openr66.database.data.DbTaskRunner.Columns;
46  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler;
47  
48  import java.sql.Timestamp;
49  
50  /**
51   * DbTaskRunner Rest handler
52   */
53  public class DbTaskRunnerR66RestMethodHandler
54      extends DataModelRestMethodHandler<DbTaskRunner> {
55    private static final String OWNER_OF_THIS_REQUEST_OPTIONAL_AS_VARCHAR =
56        "Owner of this request (optional) as VARCHAR";
57    private static final String PARTNER_AS_REQUESTED_AS_VARCHAR =
58        "Partner as requested as VARCHAR";
59    private static final String PARTNER_AS_REQUESTER_AS_VARCHAR =
60        "Partner as requester as VARCHAR";
61    private static final String SPECIAL_ID_AS_LONG_IN_URI_AS =
62        "Special Id as LONG in URI as ";
63    public static final String BASEURI = "transfers";
64  
65    public enum FILTER_ARGS {
66      LIMIT("number"), ORDERBYID("boolean"), STARTID("transfer id"),
67      STOPID("transfer id"), IDRULE("rule name"),
68      PARTNER("partner (requester or requested) name"), PENDING("boolean"),
69      INTRANSFER("boolean"), INERROR("boolean"), DONE("boolean"),
70      ALLSTATUS("boolean"), STARTTRANS("Date in ISO 8601 format or ms"),
71      STOPTRANS("Date in ISO 8601 format or ms");
72  
73      public final String type;
74  
75      FILTER_ARGS(final String type) {
76        this.type = type;
77      }
78    }
79  
80    /**
81     * @param config
82     * @param method
83     */
84    public DbTaskRunnerR66RestMethodHandler(final RestConfiguration config,
85                                            final METHOD... method) {
86      super(BASEURI, config, method);
87    }
88  
89    @Override
90    protected final DbTaskRunner getItem(final HttpRestHandler handler,
91                                         final RestArgument arguments,
92                                         final RestArgument result,
93                                         final Object body)
94        throws HttpNotFoundRequestException {
95      try {
96        HttpRestV1Utils.checkSanity(arguments);
97      } catch (final InvalidArgumentException e) {
98        throw new HttpNotFoundRequestException("Issue on values", e);
99      }
100     final ObjectNode arg = arguments.getUriArgs().deepCopy();
101     arg.setAll(arguments.getBody());
102     try {
103       final JsonNode node = RestArgument.getId(arg);
104       final long id;
105       if (node.isMissingNode()) {
106         // shall not be but continue however
107         id = arg.path(DbTaskRunner.Columns.SPECIALID.name()).asLong();
108       } else {
109         id = node.asLong();
110       }
111       return new DbTaskRunner(id,
112                               arg.path(DbTaskRunner.Columns.REQUESTER.name())
113                                  .asText(),
114                               arg.path(DbTaskRunner.Columns.REQUESTED.name())
115                                  .asText(),
116                               arg.path(DbTaskRunner.Columns.OWNERREQ.name())
117                                  .asText());
118     } catch (final WaarpDatabaseException e) {
119       throw new HttpNotFoundRequestException(
120           "Issue while reading from database " + arg, e);
121     }
122   }
123 
124   @Override
125   protected final DbTaskRunner createItem(final HttpRestHandler handler,
126                                           final RestArgument arguments,
127                                           final RestArgument result,
128                                           final Object body)
129       throws HttpIncorrectRequestException {
130     try {
131       HttpRestV1Utils.checkSanity(arguments);
132     } catch (final InvalidArgumentException e) {
133       throw new HttpIncorrectRequestException("Issue on values", e);
134     }
135     final ObjectNode arg = arguments.getUriArgs().deepCopy();
136     arg.setAll(arguments.getBody());
137     try {
138       return new DbTaskRunner(arg);
139     } catch (final WaarpDatabaseException e) {
140       throw new HttpIncorrectRequestException(
141           "Issue while inserting into database", e);
142     }
143   }
144 
145   @Override
146   protected final DbPreparedStatement getPreparedStatement(
147       final HttpRestHandler handler, final RestArgument arguments,
148       final RestArgument result, final Object body)
149       throws HttpIncorrectRequestException {
150     try {
151       HttpRestV1Utils.checkSanity(arguments);
152     } catch (final InvalidArgumentException e) {
153       throw new HttpIncorrectRequestException("Issue on values", e);
154     }
155     final ObjectNode arg = arguments.getUriArgs().deepCopy();
156     arg.setAll(arguments.getBody());
157     final int limit = arg.path(FILTER_ARGS.LIMIT.name()).asInt(0);
158     final boolean orderBySpecialId =
159         arg.path(FILTER_ARGS.ORDERBYID.name()).asBoolean(false);
160     JsonNode node = arg.path(FILTER_ARGS.STARTID.name());
161     String startid = null;
162     if (!node.isMissingNode()) {
163       startid = node.asText();
164     }
165     if (ParametersChecker.isEmpty(startid)) {
166       startid = null;
167     }
168     node = arg.path(FILTER_ARGS.STOPID.name());
169     String stopid = null;
170     if (!node.isMissingNode()) {
171       stopid = node.asText();
172     }
173     if (ParametersChecker.isEmpty(stopid)) {
174       stopid = null;
175     }
176     String rule = arg.path(FILTER_ARGS.IDRULE.name()).asText();
177     if (ParametersChecker.isEmpty(rule)) {
178       rule = null;
179     }
180     String req = arg.path(FILTER_ARGS.PARTNER.name()).asText();
181     if (ParametersChecker.isEmpty(req)) {
182       req = null;
183     }
184     String owner = arg.path(DbTaskRunner.Columns.OWNERREQ.name()).asText();
185     if (ParametersChecker.isEmpty(owner)) {
186       owner = null;
187     }
188     final boolean pending =
189         arg.path(FILTER_ARGS.PENDING.name()).asBoolean(false);
190     final boolean transfer =
191         arg.path(FILTER_ARGS.INTRANSFER.name()).asBoolean(false);
192     final boolean error = arg.path(FILTER_ARGS.INERROR.name()).asBoolean(false);
193     final boolean done = arg.path(FILTER_ARGS.DONE.name()).asBoolean(false);
194     final boolean all = arg.path(FILTER_ARGS.ALLSTATUS.name()).asBoolean(false);
195     Timestamp start = null;
196     node = arg.path(FILTER_ARGS.STARTTRANS.name());
197     if (!node.isMissingNode()) {
198       long val = node.asLong();
199       if (val == 0) {
200         final DateTime received = DateTime.parse(node.asText());
201         val = received.getMillis();
202       }
203       start = new Timestamp(val);
204     }
205     Timestamp stop = null;
206     node = arg.path(FILTER_ARGS.STOPTRANS.name());
207     if (!node.isMissingNode()) {
208       long val = node.asLong();
209       if (val == 0) {
210         final DateTime received = DateTime.parse(node.asText());
211         val = received.getMillis();
212       }
213       stop = new Timestamp(val);
214     }
215     try {
216       return DbTaskRunner.getFilterPrepareStatement(handler.getDbSession(),
217                                                     limit, orderBySpecialId,
218                                                     startid, stopid, start,
219                                                     stop, rule, req, pending,
220                                                     transfer, error, done, all,
221                                                     owner);
222     } catch (final WaarpDatabaseNoConnectionException e) {
223       throw new HttpIncorrectRequestException(
224           "Issue while reading from database", e);
225     } catch (final WaarpDatabaseSqlException e) {
226       throw new HttpIncorrectRequestException(
227           "Issue while reading from database", e);
228     }
229   }
230 
231   @Override
232   protected final DbTaskRunner getItemPreparedStatement(
233       final DbPreparedStatement statement)
234       throws HttpIncorrectRequestException, HttpNotFoundRequestException {
235     try {
236       return DbTaskRunner.getFromStatementNoDbRule(statement);
237     } catch (final WaarpDatabaseNoConnectionException e) {
238       throw new HttpIncorrectRequestException(
239           "Issue while selecting from database", e);
240     } catch (final WaarpDatabaseSqlException e) {
241       throw new HttpNotFoundRequestException(
242           "Issue while selecting from database", e);
243     }
244   }
245 
246   @Override
247   protected final ArrayNode getDetailedAllow() {
248     final ArrayNode node = JsonHandler.createArrayNode();
249 
250     final ObjectNode node1 = JsonHandler.createObjectNode();
251     node1.put(AbstractDbData.JSON_MODEL, DbTaskRunner.class.getSimpleName());
252     for (final DbTaskRunner.Columns column : DbTaskRunner.Columns.values()) {
253       node1.put(column.name(), DbTaskRunner.dbTypes[column.ordinal()]);
254     }
255 
256     ObjectNode node2;
257     ObjectNode node3 = JsonHandler.createObjectNode();
258     if (methods.contains(METHOD.GET)) {
259       node3.put(DbTaskRunner.Columns.SPECIALID.name(),
260                 SPECIAL_ID_AS_LONG_IN_URI_AS + path + "/id");
261       node3.put(DbTaskRunner.Columns.REQUESTER.name(),
262                 PARTNER_AS_REQUESTER_AS_VARCHAR);
263       node3.put(DbTaskRunner.Columns.REQUESTED.name(),
264                 PARTNER_AS_REQUESTED_AS_VARCHAR);
265       node3.put(DbTaskRunner.Columns.OWNERREQ.name(),
266                 OWNER_OF_THIS_REQUEST_OPTIONAL_AS_VARCHAR);
267       node2 = RestArgument.fillDetailedAllow(METHOD.GET, path + "/id",
268                                              COMMAND_TYPE.GET.name(), node3,
269                                              node1);
270       node.add(node2);
271 
272       node3 = JsonHandler.createObjectNode();
273       for (final FILTER_ARGS arg : FILTER_ARGS.values()) {
274         node3.put(arg.name(), arg.type);
275       }
276       node3.put(DbTaskRunner.Columns.OWNERREQ.name(),
277                 OWNER_OF_THIS_REQUEST_OPTIONAL_AS_VARCHAR);
278       node2 = RestArgument.fillDetailedAllow(METHOD.GET, path,
279                                              COMMAND_TYPE.MULTIGET.name(),
280                                              node3,
281                                              JsonHandler.createArrayNode()
282                                                         .add(node1));
283       node.add(node2);
284     }
285     if (methods.contains(METHOD.PUT)) {
286       node3 = JsonHandler.createObjectNode();
287       node3.put(DbTaskRunner.Columns.SPECIALID.name(),
288                 SPECIAL_ID_AS_LONG_IN_URI_AS + path + "/id");
289       node3.put(DbTaskRunner.Columns.REQUESTER.name(),
290                 PARTNER_AS_REQUESTER_AS_VARCHAR);
291       node3.put(DbTaskRunner.Columns.REQUESTED.name(),
292                 PARTNER_AS_REQUESTED_AS_VARCHAR);
293       node3.put(DbTaskRunner.Columns.OWNERREQ.name(),
294                 OWNER_OF_THIS_REQUEST_OPTIONAL_AS_VARCHAR);
295       for (final DbTaskRunner.Columns column : DbTaskRunner.Columns.values()) {
296         if (column.name()
297                   .equalsIgnoreCase(DbTaskRunner.Columns.IDRULE.name())) {
298           continue;
299         }
300         node3.put(column.name(), DbTaskRunner.dbTypes[column.ordinal()]);
301       }
302       node2 = RestArgument.fillDetailedAllow(METHOD.PUT, path + "/id",
303                                              COMMAND_TYPE.UPDATE.name(), node3,
304                                              node1);
305       node.add(node2);
306     }
307     if (methods.contains(METHOD.DELETE)) {
308       node3 = JsonHandler.createObjectNode();
309       node3.put(DbTaskRunner.Columns.SPECIALID.name(),
310                 SPECIAL_ID_AS_LONG_IN_URI_AS + path + "/id");
311       node3.put(DbTaskRunner.Columns.REQUESTER.name(),
312                 PARTNER_AS_REQUESTER_AS_VARCHAR);
313       node3.put(DbTaskRunner.Columns.REQUESTED.name(),
314                 PARTNER_AS_REQUESTED_AS_VARCHAR);
315       node3.put(DbTaskRunner.Columns.OWNERREQ.name(),
316                 OWNER_OF_THIS_REQUEST_OPTIONAL_AS_VARCHAR);
317       node2 = RestArgument.fillDetailedAllow(METHOD.DELETE, path + "/id",
318                                              COMMAND_TYPE.DELETE.name(), node3,
319                                              node1);
320       node.add(node2);
321     }
322     if (methods.contains(METHOD.POST)) {
323       node3 = JsonHandler.createObjectNode();
324       for (final DbTaskRunner.Columns column : DbTaskRunner.Columns.values()) {
325         node3.put(column.name(), DbTaskRunner.dbTypes[column.ordinal()]);
326       }
327       node2 = RestArgument.fillDetailedAllow(METHOD.POST, path,
328                                              COMMAND_TYPE.CREATE.name(), node3,
329                                              node1);
330       node.add(node2);
331     }
332     node2 = RestArgument.fillDetailedAllow(METHOD.OPTIONS, path,
333                                            COMMAND_TYPE.OPTIONS.name(), null,
334                                            null);
335     node.add(node2);
336 
337     return node;
338   }
339 
340   @Override
341   public final String getPrimaryPropertyName() {
342     return Columns.SPECIALID.name();
343   }
344 
345   @Override
346   protected final void checkAuthorization(final HttpRestHandler handler,
347                                           final RestArgument arguments,
348                                           final RestArgument result,
349                                           final METHOD method)
350       throws HttpForbiddenRequestException {
351     try {
352       HttpRestV1Utils.checkSanity(arguments);
353     } catch (final InvalidArgumentException e) {
354       throw new HttpForbiddenRequestException("Issue on values", e);
355     }
356     final HttpRestR66Handler r66handler = (HttpRestR66Handler) handler;
357     final R66Session session = r66handler.getServerHandler().getSession();
358     if (!session.getAuth().isValidRole(ROLE.SYSTEM)) {
359       throw new HttpForbiddenRequestException("Partner must have System role");
360     }
361   }
362 
363 }