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.client;
21  
22  import com.fasterxml.jackson.databind.node.ObjectNode;
23  import io.netty.channel.Channel;
24  import io.netty.channel.ChannelInitializer;
25  import io.netty.channel.socket.SocketChannel;
26  import io.netty.handler.codec.http.HttpMethod;
27  import org.waarp.common.database.data.AbstractDbData;
28  import org.waarp.common.json.JsonHandler;
29  import org.waarp.common.utility.ParametersChecker;
30  import org.waarp.gateway.kernel.exception.HttpIncorrectRequestException;
31  import org.waarp.gateway.kernel.rest.DataModelRestMethodHandler;
32  import org.waarp.gateway.kernel.rest.HttpRestHandler;
33  import org.waarp.gateway.kernel.rest.RestArgument;
34  import org.waarp.gateway.kernel.rest.RestConfiguration;
35  import org.waarp.gateway.kernel.rest.client.HttpRestClientHelper;
36  import org.waarp.gateway.kernel.rest.client.RestFuture;
37  import org.waarp.openr66.protocol.http.rest.HttpRestR66Handler.RESTHANDLERS;
38  import org.waarp.openr66.protocol.localhandler.packet.json.JsonPacket;
39  
40  import java.util.Map;
41  
42  /**
43   * Http Rest R66 client helper class
44   */
45  public class HttpRestR66Client extends HttpRestClientHelper {
46  
47    /**
48     * Send an HTTP query using the channel for target
49     *
50     * @param config configuration for REST service
51     * @param channel target of the query
52     * @param method HttpMethod to use
53     * @param host target of the query (shall be the same as for the
54     *     channel)
55     * @param addedUri additional uri, added to baseUri (shall include
56     *     also
57     *     extra arguments) (might be null)
58     * @param user user to use in authenticated Rest procedure (might be
59     *     null)
60     * @param pwd password to use in authenticated Rest procedure (might
61     *     be
62     *     null)
63     * @param uriArgs arguments for Uri if any (might be null)
64     * @param json json to send as body in the request (might be null);
65     *     Useful
66     *     in PUT, POST but should not in
67     *     GET, DELETE, OPTIONS
68     *
69     * @return the RestFuture associated with this request
70     */
71    public RestFuture sendQuery(final RestConfiguration config,
72                                final Channel channel, final HttpMethod method,
73                                final String host, final String addedUri,
74                                final String user, final String pwd,
75                                final Map<String, String> uriArgs,
76                                final String json) {
77      if (config.isRestSignature()) {
78        return sendQuery(config.getHmacSha256(), channel, method, host, addedUri,
79                         user, pwd, uriArgs, json);
80      } else {
81        return sendQuery(channel, method, host, addedUri, user, uriArgs, json);
82      }
83    }
84  
85    /**
86     * Prepare the future connection
87     *
88     * @param baseUri in general = '/'
89     * @param initializer the associated Initializer including the REST
90     *     handler for client side
91     * @param client limit number of concurrent connected clients
92     * @param timeout time out for network connection
93     */
94    public HttpRestR66Client(final String baseUri,
95                             final ChannelInitializer<SocketChannel> initializer,
96                             final int client, final long timeout) {
97      super(baseUri, client, timeout, initializer);
98    }
99  
100   /**
101    * @param bodyResponse
102    *
103    * @return the associated RESTHANDLERS if any, else null
104    */
105   public RESTHANDLERS getRestHandler(final RestArgument bodyResponse) {
106     final ObjectNode node = bodyResponse.getAnswer();
107     final String model = node.path(AbstractDbData.JSON_MODEL).asText();
108     try {
109       if (ParametersChecker.isNotEmpty(model)) {
110         return RESTHANDLERS.valueOf(model);
111       }
112     } catch (final Exception ignored) {
113       // nothing
114     }
115     return null;
116   }
117 
118   /**
119    * @param bodyResponse
120    *
121    * @return the primary property value associated with the Model (from the
122    *     bodyResponse), else null
123    */
124   public String getPrimaryProperty(final RestArgument bodyResponse) {
125     final ObjectNode answer = bodyResponse.getAnswer();
126     final String model = answer.path(AbstractDbData.JSON_MODEL).asText();
127     final String property = getPrimaryPropertyName(model);
128     if (property == null) {
129       return null;
130     }
131     return answer.path(property).asText();
132   }
133 
134   /**
135    * @param model
136    *
137    * @return the primary property name associated with the Model
138    */
139   public String getPrimaryPropertyName(final String model) {
140     try {
141       if (ParametersChecker.isNotEmpty(model)) {
142         final RESTHANDLERS dbdata = RESTHANDLERS.valueOf(model);
143         final DataModelRestMethodHandler<?> handler =
144             (DataModelRestMethodHandler<?>) HttpRestHandler.defaultConfiguration.restHashMap.get(
145                 dbdata.uri);
146         return handler.getPrimaryPropertyName();
147       }
148     } catch (final Exception ignored) {
149       // ignore
150     }
151     return null;
152   }
153 
154   /**
155    * @param future
156    *
157    * @return the DbData allocated from result if any, else null
158    *
159    * @throws HttpIncorrectRequestException
160    */
161   @SuppressWarnings("unchecked")
162   public AbstractDbData getDbDataFromFuture(final RestFuture future)
163       throws HttpIncorrectRequestException {
164     if (future.getRestArgument() != null) {
165       final RestArgument arg = future.getRestArgument();
166       final ObjectNode node = arg.getAnswer();
167       final String model = node.path(AbstractDbData.JSON_MODEL).asText();
168       try {
169         if (ParametersChecker.isNotEmpty(model)) {
170           final RESTHANDLERS rmodel = RESTHANDLERS.valueOf(model);
171           try {
172             return (AbstractDbData) rmodel.clasz.getConstructor(
173                 ObjectNode.class).newInstance(node);
174           } catch (final Exception e) {
175             throw new HttpIncorrectRequestException(e);
176           }
177         }
178       } catch (final Exception ignored) {
179         // ignore
180       }
181     }
182     return null;
183   }
184 
185   /**
186    * @param future
187    *
188    * @return the JsonPacket from result if any, else null
189    *
190    * @throws HttpIncorrectRequestException
191    */
192   public JsonPacket getJsonPacketFromFuture(final RestFuture future)
193       throws HttpIncorrectRequestException {
194     if (future.getRestArgument() != null) {
195       final RestArgument arg = future.getRestArgument();
196       final ObjectNode node = arg.getAnswer();
197       try {
198         return JsonPacket.createFromBuffer(JsonHandler.writeAsString(node));
199       } catch (final Exception e) {
200         throw new HttpIncorrectRequestException(e);
201       }
202     }
203     return null;
204   }
205 
206 }