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  
21  package org.waarp.openr66.protocol.http.restv2.dbhandlers;
22  
23  import com.fasterxml.jackson.databind.node.ObjectNode;
24  import io.cdap.http.HttpResponder;
25  import io.netty.handler.codec.http.DefaultHttpHeaders;
26  import io.netty.handler.codec.http.HttpHeaders;
27  import io.netty.handler.codec.http.HttpMethod;
28  import io.netty.handler.codec.http.HttpRequest;
29  import org.waarp.openr66.dao.DAOFactory;
30  import org.waarp.openr66.dao.Filter;
31  import org.waarp.openr66.dao.RuleDAO;
32  import org.waarp.openr66.dao.TransferDAO;
33  import org.waarp.openr66.dao.exception.DAOConnectionException;
34  import org.waarp.openr66.dao.exception.DAONoDataException;
35  import org.waarp.openr66.database.data.DbTaskRunner;
36  import org.waarp.openr66.pojo.Rule;
37  import org.waarp.openr66.protocol.http.restv2.converters.RuleConverter;
38  import org.waarp.openr66.protocol.http.restv2.utils.JsonUtils;
39  
40  import javax.ws.rs.Consumes;
41  import javax.ws.rs.DELETE;
42  import javax.ws.rs.GET;
43  import javax.ws.rs.InternalServerErrorException;
44  import javax.ws.rs.OPTIONS;
45  import javax.ws.rs.PUT;
46  import javax.ws.rs.Path;
47  import javax.ws.rs.PathParam;
48  import java.util.ArrayList;
49  import java.util.List;
50  
51  import static io.netty.handler.codec.http.HttpResponseStatus.*;
52  import static javax.ws.rs.core.HttpHeaders.*;
53  import static javax.ws.rs.core.MediaType.*;
54  import static org.waarp.common.role.RoleDefault.ROLE.*;
55  import static org.waarp.openr66.protocol.http.restv2.RestConstants.*;
56  
57  /**
58   * This is the {@link AbstractRestDbHandler} handling all requests made on a
59   * single rule REST entry point.
60   */
61  @Path(RULE_ID_HANDLER_URI)
62  public class RuleIdHandler extends AbstractRestDbHandler {
63  
64    /**
65     * The content of the 'Allow' header sent when an 'OPTIONS' request is made
66     * on the handler.
67     */
68    private static final HttpHeaders OPTIONS_HEADERS;
69  
70    static {
71      OPTIONS_HEADERS = new DefaultHttpHeaders();
72      final List<HttpMethod> allow = new ArrayList<HttpMethod>();
73      allow.add(HttpMethod.GET);
74      allow.add(HttpMethod.PUT);
75      allow.add(HttpMethod.DELETE);
76      allow.add(HttpMethod.OPTIONS);
77      OPTIONS_HEADERS.add(ALLOW, allow);
78    }
79  
80    /**
81     * Initializes the handler with the given CRUD mask.
82     *
83     * @param crud the CRUD mask for this handler
84     */
85    public RuleIdHandler(final byte crud) {
86      super(crud);
87    }
88  
89    /**
90     * Method called to retrieve a transfer rule with the id given in the
91     * request URI.
92     *
93     * @param request the HttpRequest made on the resource
94     * @param responder the HttpResponder which sends the reply to the
95     *     request
96     * @param id the requested rule's name
97     */
98    @GET
99    @Consumes(WILDCARD)
100   @RequiredRole(NOACCESS)
101   public final void getRule(final HttpRequest request,
102                             final HttpResponder responder,
103                             @PathParam(URI_ID) final String id) {
104     checkSanity(id);
105     RuleDAO ruleDAO = null;
106     try {
107       ruleDAO = DAO_FACTORY.getRuleDAO(true);
108       final Rule rule = ruleDAO.select(id);
109 
110       if (rule == null) {
111         responder.sendStatus(NOT_FOUND);
112         return;
113       }
114       final ObjectNode responseObject = RuleConverter.ruleToNode(rule);
115       final String responseText = JsonUtils.nodeToString(responseObject);
116       responder.sendJson(OK, responseText);
117     } catch (final DAOConnectionException e) {
118       throw new InternalServerErrorException(e);
119     } catch (final DAONoDataException e) {
120       responder.sendStatus(NOT_FOUND);
121     } finally {
122       DAOFactory.closeDAO(ruleDAO);
123     }
124   }
125 
126   /**
127    * Method called to update a transfer rule.
128    *
129    * @param request the HttpRequest made on the resource
130    * @param responder the HttpResponder which sends the reply to the
131    *     request
132    * @param id the requested rule's name
133    */
134   @PUT
135   @Consumes(APPLICATION_JSON)
136   @RequiredRole(RULE)
137   public final void updateRule(final HttpRequest request,
138                                final HttpResponder responder,
139                                @PathParam(URI_ID) final String id) {
140     checkSanity(id);
141     RuleDAO ruleDAO = null;
142     try {
143       ruleDAO = DAO_FACTORY.getRuleDAO(false);
144       final Rule oldRule = ruleDAO.select(id);
145 
146       if (oldRule == null) {
147         responder.sendStatus(NOT_FOUND);
148         return;
149       }
150 
151       final ObjectNode requestObject = JsonUtils.deserializeRequest(request);
152       checkSanity(requestObject);
153       final Rule newRule =
154           RuleConverter.nodeToUpdatedRule(requestObject, oldRule);
155 
156       ruleDAO.update(newRule);
157 
158       final ObjectNode responseObject = RuleConverter.ruleToNode(newRule);
159       final String responseText = JsonUtils.nodeToString(responseObject);
160       responder.sendJson(CREATED, responseText);
161     } catch (final DAOConnectionException e) {
162       throw new InternalServerErrorException(e);
163     } catch (final DAONoDataException e) {
164       responder.sendStatus(NOT_FOUND);
165     } finally {
166       DAOFactory.closeDAO(ruleDAO);
167     }
168   }
169 
170   /**
171    * Method called to delete a transfer rule from the database.
172    * Note that if a Transfer exists that used this rule, the delete
173    * cannot be achieved.
174    *
175    * @param request the HttpRequest made on the resource
176    * @param responder the HttpResponder which sends the reply to the
177    *     request
178    * @param id the requested rule's name
179    */
180   @DELETE
181   @Consumes(WILDCARD)
182   @RequiredRole(RULE)
183   public final void deleteRule(final HttpRequest request,
184                                final HttpResponder responder,
185                                @PathParam(URI_ID) final String id) {
186     checkSanity(id);
187     TransferDAO transferDAO = null;
188     try {
189       transferDAO = DAO_FACTORY.getTransferDAO();
190       final List<Filter> filters = new ArrayList<Filter>();
191       final Filter filter =
192           new Filter(DbTaskRunner.Columns.IDRULE.name(), "=", id);
193       filters.add(filter);
194       final long nb = transferDAO.count(filters);
195       if (nb > 0) {
196         responder.sendStatus(NOT_FOUND);
197       }
198     } catch (final DAOConnectionException e) {
199       throw new InternalServerErrorException(e);
200     } finally {
201       DAOFactory.closeDAO(transferDAO);
202     }
203     RuleDAO ruleDAO = null;
204     try {
205       ruleDAO = DAO_FACTORY.getRuleDAO(false);
206       final Rule rule = ruleDAO.select(id);
207       if (rule == null) {
208         responder.sendStatus(NOT_FOUND);
209       } else {
210         ruleDAO.delete(rule);
211         responder.sendStatus(NO_CONTENT);
212       }
213     } catch (final DAOConnectionException e) {
214       throw new InternalServerErrorException(e);
215     } catch (final DAONoDataException e) {
216       responder.sendStatus(NOT_FOUND);
217     } finally {
218       DAOFactory.closeDAO(ruleDAO);
219     }
220   }
221 
222   /**
223    * Method called to get a list of all allowed HTTP methods on this entry
224    * point. The HTTP methods are sent as
225    * an array in the reply's headers.
226    *
227    * @param request the HttpRequest made on the resource
228    * @param responder the HttpResponder which sends the reply to the
229    *     request
230    * @param id the requested rule's name
231    */
232   @OPTIONS
233   @Consumes(WILDCARD)
234   @RequiredRole(NOACCESS)
235   public final void options(final HttpRequest request,
236                             final HttpResponder responder,
237                             @PathParam(URI_ID) final String id) {
238     checkSanity(id);
239     responder.sendStatus(OK, OPTIONS_HEADERS);
240   }
241 }