Project

General

Profile

Download (16.8 KB) Statistics
| Branch: | Revision:

git_sitools_idoc / solar / asynchronous_download_public / Asynchronous_Download_java_sitools2 / PublicOrderResource.java @ master

1
 /*******************************************************************************
2
 * Copyright 2010-2014 CNES - CENTRE NATIONAL d'ETUDES SPATIALES
3
 *
4
 * This file is part of SITools2.
5
 *
6
 * SITools2 is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * SITools2 is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with SITools2.  If not, see <http://www.gnu.org/licenses/>.
18
 ******************************************************************************/
19
package fr.cnes.sitools.resources.order;
20

    
21
import java.io.IOException;
22
import java.util.ArrayList;
23
import java.util.Iterator;
24
import java.util.List;
25
import java.util.logging.Level;
26
import java.util.Map;
27
import java.util.HashMap;
28
import java.io.UnsupportedEncodingException;
29
import java.net.URLEncoder;
30

    
31
import org.restlet.data.Reference;
32
import org.restlet.data.Status;
33
import org.restlet.representation.Representation;
34
import org.restlet.resource.ResourceException;
35
import org.restlet.security.User;
36

    
37
import fr.cnes.sitools.common.exception.SitoolsException;
38
import fr.cnes.sitools.dataset.database.DatabaseRequest;
39
import fr.cnes.sitools.datasource.jdbc.model.AttributeValue;
40
import fr.cnes.sitools.datasource.jdbc.model.Record;
41
import fr.cnes.sitools.plugins.resources.model.ResourceModel;
42
import fr.cnes.sitools.plugins.resources.model.ResourceParameter;
43
import fr.cnes.sitools.resources.order.utils.ListReferencesAPI;
44
import fr.cnes.sitools.resources.order.utils.OrderAPI;
45
import fr.cnes.sitools.resources.order.utils.OrderResourceUtils;
46
import fr.cnes.sitools.server.Consts;
47
import fr.cnes.sitools.util.RIAPUtils;
48
import fr.cnes.sitools.order.model.Order;
49
import org.restlet.Context;
50
import fr.cnes.sitools.tasks.business.Task;
51
import fr.cnes.sitools.mail.model.Mail;
52
import org.restlet.Request;
53
import org.restlet.data.Method;
54
import org.restlet.representation.ObjectRepresentation;
55
import fr.cnes.sitools.util.TemplateUtils;
56
import fr.cnes.sitools.util.Util;
57

    
58

    
59
/**
60
 * Default OrderResource implementation.
61
 * <p>
62
 * The parameter colUrl is used to specify a column containing the list of URLs of the files to order. Each file is then
63
 * either copied or Zipped to the userstorage of the user.
64
 * </p>
65
 * 
66
 * 
67
 * @author m.gond
68
 */
69
public class PublicOrderResource extends AbstractDatasetOrderResource {
70
  /** Maximum number of file to download authorized, default to -1 => no limit */
71
  private int nbMaxDownload = -1;
72
  private fr.cnes.sitools.security.model.User userDetails; 
73
  /*
74
   * (non-Javadoc)
75
   *
76
   * @see fr.cnes.sitools.resources.order.AbstractOrderResource#checkUser()
77
   */
78
  @Override
79
  public void checkUser() {
80
    User user = getClientInfo().getUser();
81
    if (user == null) {
82
      userDetails=null;
83
    }
84
    else{
85
      try {
86
        userDetails = this.getUserDetails(user.getIdentifier(), getContext());
87
      }
88
      catch (SitoolsException e) {
89
        userDetails=null;
90
      }
91

    
92
    }
93

    
94

    
95
  }
96

    
97
  public void notifyAdminEnd() throws SitoolsException {
98
    try {
99
      sendMail(order, getContext(), userDetails, task);
100
    }
101
    catch (SitoolsException e) {
102
      // ne rien faire si le mail n'est pas parti
103
      OrderAPI.createEvent(order, getContext(), "MAIL_NOT_SEND_TO_USER");
104
    }
105
  }
106

    
107
  protected void sendMail(Order order, Context context, fr.cnes.sitools.security.model.User user, Task task)
108
        throws SitoolsException{
109
    List<String> toList = new ArrayList<String>();
110
if(user!=null){        
111
    String userAdd = user.getEmail();
112
    if (userAdd != null && !userAdd.equals("")) {
113
      // System.out.println("EMAIL ADDRESS = " + userAdd);
114
      toList.add(userAdd);
115

    
116
      Mail mailToUser = new Mail();
117
      mailToUser.setToList(toList);
118

    
119
      // TODO EVOL : email subject should be a parameter
120
      mailToUser.setSubject(getMailSubject());
121

    
122
      // default body
123
      mailToUser.setBody(getMailBody(mailToUser));
124

    
125
      org.restlet.Response sendMailResponse = null;
126
      try {
127
        // riap request to MailAdministration application
128
        Request request = new Request(Method.POST, RIAPUtils.getRiapBase()
129
            + settings.getString(Consts.APP_MAIL_ADMIN_URL), new ObjectRepresentation<Mail>(mailToUser));
130

    
131
        sendMailResponse = getContext().getClientDispatcher().handle(request);
132
      }
133
      catch (Exception e) {
134
        getLogger().warning("SERVER ERROR SENDING EMAIL TO USER");
135
        throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
136
      }
137
      if (sendMailResponse.getStatus().isError()) {
138
        throw new SitoolsException("SERVER ERROR SENDING EMAIL TO USER");
139
      }
140

    
141
      // OK
142
    }
143
    else {
144
      throw new SitoolsException("NO EMAIL ADDRESS DEFINED");
145
    }
146
}
147
else{
148
  ResourceModel resourceModel = getModel();
149
  ResourceParameter email = resourceModel.getParameterByName("Email");
150
  String userAdd = this.getRequest().getResourceRef().getQueryAsForm().getFirstValue("Email");
151
 //String userAdd = email.getValue();
152
  getContext().getLogger().info("******************* UserEmail : "+userAdd);
153
  if (userAdd != null && !userAdd.equals("")) {
154
    toList.add(userAdd);
155
    Mail mailToPublic = new Mail();
156
    mailToPublic.setToList(toList);
157
    mailToPublic.setSubject(getMailSubject());
158
    mailToPublic.setBody(getMailBodyPublic(mailToPublic));
159
    org.restlet.Response sendMailResponse = null;
160
      try {
161
        Request request = new Request(Method.POST, RIAPUtils.getRiapBase()
162
            + settings.getString(Consts.APP_MAIL_ADMIN_URL), new ObjectRepresentation<Mail>(mailToPublic));
163

    
164
        sendMailResponse = getContext().getClientDispatcher().handle(request);
165
      }
166
      catch (Exception e) {
167
        getLogger().warning("SERVER ERROR SENDING EMAIL TO PUBLIC DOWNLOADER");
168
        throw new ResourceException(Status.SERVER_ERROR_INTERNAL, e);
169
      }
170
      if (sendMailResponse.getStatus().isError()) {
171
        throw new SitoolsException("SERVER ERROR SENDING EMAIL TO PUBLIC DOWNLOADER");
172
      }
173
  }
174
  else{
175
    throw new SitoolsException("NO EMAIL ADDRESS DEFINED");
176
  }
177
}
178

    
179
  }
180

    
181

    
182
protected String getMailBodyPublic(Mail mailToPublic) {
183
    // default body
184
    String orderNameEncoded = order.getDescription();
185
    String fileNameEncoded = order.getDescription();
186
        
187
    try{
188
        orderNameEncoded = URLEncoder.encode(order.getDescription(),"UTF-8");
189
    } catch (UnsupportedEncodingException e){
190
        e.printStackTrace();
191
    }
192
    try{
193
        fileNameEncoded = URLEncoder.encode(orderNameEncoded,"UTF-8");
194
    } catch (UnsupportedEncodingException e){
195
        e.printStackTrace();
196
    }
197
    String mailBody = "Dear visiter"+":<br/><br/>Your command is complete. <br/>" + "File Name : "
198
        + order.getDescription() + "<br/>"
199
        +"Now you can click the link below to download it:<br/><a href='http://idoc-picard.ias.u-psud.fr:8182/sitools/userstorage/public/files/resources_orders/"
200
        +orderNameEncoded+"/"+fileNameEncoded+".zip"
201
        +"'>http://idoc-picard.ias.u-psud.fr:8182/sitools/userstorage/public/files/resources_orders/"
202
        +orderNameEncoded+"/"+fileNameEncoded+".zip</a>"
203
        +"<br/><br/>Admin<br/><a href='http://idoc-picard.ias.u-psud.fr'>PICARD ARCHIVE</a>";
204

    
205
    // use a freemarker template for email body with Mail object
206
    String templatePath = settings.getRootDirectory() + settings.getString(Consts.TEMPLATE_DIR)
207
        + "mail.order.complete.ftl";
208

    
209
    Map<String, Object> root = new HashMap<String, Object>();
210
    root.put("mail", mailToPublic);
211
    root.put("order", order);
212
    String adminmail = settings.getString("Starter.StatusService.CONTACT_MAIL");
213
    root.put("adminmail", adminmail);
214

    
215
    TemplateUtils.describeObjectClassesForTemplate(templatePath, root);
216

    
217
    root.put("context", getContext());
218

    
219
    String body = TemplateUtils.toString(templatePath, root);
220
    if (Util.isNotEmpty(body)) {
221
      return body;
222
    }
223
    else {
224
      return mailBody;
225
    }
226
  }
227

    
228

    
229

    
230
  @Override
231
  public ListReferencesAPI listFilesToOrder(DatabaseRequest dbRequest) throws SitoolsException {
232
    task.setCustomStatus("Creating list of files to order");
233
    ResourceModel resourceModel = getModel();
234
    ResourceParameter nbMaxDownloadParam = resourceModel.getParameterByName("too_many_selected_threshold");
235
    if (nbMaxDownloadParam != null && !"".equals(nbMaxDownloadParam)) {
236
      try {
237
        nbMaxDownload = Integer.parseInt(nbMaxDownloadParam.getValue());
238
      }
239
      catch (NumberFormatException e) {
240
        nbMaxDownload = -1;
241
      }
242
    }
243
    
244
    if (nbMaxDownload != -1 && nbMaxDownload < dbRequest.getCount()) {
245
      ResourceParameter errorTextParam = resourceModel.getParameterByName("too_many_selected_threshold_text");
246
      String errorText = (errorTextParam != null && !"".equals(errorTextParam.getValue())) ? errorTextParam.getValue()
247
          : "Too many file selected";
248
      throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, errorText);
249
    }
250

    
251
    ResourceParameter colUrl = resourceModel.getParameterByName("colUrl");
252
    if (colUrl.getValue() == null || colUrl.getValue().equals("")) {
253
      throw new SitoolsException("NO COLUMN DEFINED FOR ORDER");
254
    }
255

    
256
    ListReferencesAPI list = new ListReferencesAPI(settings.getPublicHostDomain() + settings.getString(Consts.APP_URL));
257
    while (dbRequest.nextResult()) {
258
      Record rec = dbRequest.getRecord();
259
      AttributeValue attributeValue = OrderResourceUtils.getInParam(colUrl, rec);
260

    
261
      if (attributeValue != null && attributeValue.getValue() != null) {
262
        // get the file path
263
        String filePath = (String) attributeValue.getValue();
264
        String urlAttach = settings.getString(Consts.APP_DATASTORAGE_URL);
265
        // if it contains "/datastorage" get rid of everything before
266
        if (filePath.contains(urlAttach)) {
267
          filePath = filePath.substring(filePath.lastIndexOf(urlAttach));
268
        }
269
        if (filePath.startsWith("http://")) {
270
          list.addReferenceSource(new Reference(filePath));
271
        }
272
        else {
273
          list.addReferenceSource(new Reference(RIAPUtils.getRiapBase() + filePath));
274
        }
275

    
276
      }
277
    }
278
    return list;
279
  }
280

    
281
  @Override
282
  public Representation processOrder(ListReferencesAPI listReferences) throws SitoolsException {
283
    task.setCustomStatus("Order processing");
284
    OrderAPI.createEvent(order, getContext(), "PROCESSING ORDER");
285

    
286
    List<Reference> listOfFilesToOrder = listReferences.getReferencesSource();
287

    
288
    getContext().getLogger().info("******************* User : "+task.getUser());
289
    getContext().getLogger().info("******************* folder : "+settings.getString(Consts.USERSTORAGE_RESOURCE_ORDER_DIR) + folderName);
290
    Reference destRef = OrderResourceUtils.getUserAvailableFolderPath(task.getUser(),
291
        settings.getString(Consts.USERSTORAGE_RESOURCE_ORDER_DIR) + folderName, getContext());
292

    
293
    ResourceModel resourceModel = getModel();
294
    ResourceParameter zipParam = resourceModel.getParameterByName("zip");
295

    
296
    // zip is a USER_INPUT parameter, let's get it from the request
297
    // parameters
298
    String zipValue = this.getRequest().getResourceRef().getQueryAsForm().getFirstValue("zip");
299
    if (zipValue == null || zipValue.equals("") || (!"false".equals(zipValue) && !"true".equals(zipValue))) {
300
      zipValue = zipParam.getValue();
301
    }
302

    
303
    Boolean zip = Boolean.parseBoolean(zipValue);
304
    if (zip) {
305
      task.getLogger().log(Level.INFO, zipParam.getName().toUpperCase() + " in progress for user : " 
306
          + task.getUser().getIdentifier() + " -> ip :" + getClientInfo().getUpstreamAddress());
307
      
308
      task.getLogger().info("List of files ordered :");
309
      for (Reference r : listReferences.getReferencesSource()) {
310
        task.getLogger().info(" - " + r.getIdentifier().substring(16));
311
        r.getPath();
312
      }
313
      zip(listOfFilesToOrder, listReferences, destRef);
314
    }
315
    else {
316
      task.getLogger().log(Level.INFO, "FILE in progress for user : "
317
          + task.getUser().getIdentifier() + " -> ip :" + getClientInfo().getUpstreamAddress());
318
      task.getLogger().info("List of files ordered :");
319
      for (Reference r : listReferences.getReferencesSource()) {
320
        task.getLogger().info(" - " + r.getIdentifier().substring(16));
321
        r.getPath();
322
      }
323
      
324
      Reference ref;
325
      for (Iterator<Reference> iterator = listOfFilesToOrder.iterator(); iterator.hasNext();) {
326
        Reference sourceRef = iterator.next();
327
        task.getLogger().log(Level.WARNING, "{0}", sourceRef);
328
        try {
329
          ref = new Reference(destRef);
330
          ref.addSegment(sourceRef.getLastSegment());
331
          OrderResourceUtils.copyFile(sourceRef, ref, getRequest().getClientInfo(), getContext());
332
          listReferences.addReferenceDest(ref);
333
        }
334
        catch (SitoolsException e) {
335
          task.getLogger().log(Level.WARNING, "File not copied : " + sourceRef, e);
336
        }
337
      }
338
    }
339

    
340
    task.getLogger().log(Level.INFO, "Number of downloaded files : " + listOfFilesToOrder.size());
341
    
342
    // set the result in the task
343
    task.setUrlResult(settings.getString(Consts.APP_URL) + settings.getString(Consts.APP_ORDERS_USER_URL) + "/"
344
        + order.getId());
345

    
346
    try {
347
      // copy the indexFile to the destination reference
348
      String orderFileListName = fileName;
349
      if (orderFileListName == null || "".equals(orderFileListName)) {
350
        orderFileListName = OrderResourceUtils.FILE_LIST_PATTERN.replace("{orderName}", ds.getName());
351
        orderFileListName = orderFileListName.replace("{timestamp}", formatedDate);
352
      }
353
      else {
354
        orderFileListName += "_fileList";
355
      }
356
      destRef.addSegment(orderFileListName);
357
      destRef.setExtensions("txt");
358
      Reference urlUserIndex = listReferences.copyToUserStorage(destRef, getContext(), getClientInfo());
359

    
360
      // add it the order
361
      ArrayList<String> orderedResource = new ArrayList<String>();
362
      orderedResource.add(urlUserIndex.toString());
363
      order.setResourceCollection(orderedResource);
364
      order = OrderAPI.updateOrder(order, getContext());
365

    
366
    }
367
    catch (IOException e) {
368
      throw new SitoolsException("Error while creating the file index in the userstorage", e);
369
    }
370
    return null;
371

    
372
  }
373

    
374
  /**
375
   * Create the Zip from the listOfFilesToOrder
376
   * 
377
   * @param listOfFilesToOrder
378
   *          the list of files to order
379
   * @param listReferences
380
   *          the ListReferenceAPI to add some reference
381
   * @param destRef
382
   *          the destination reference
383
   * @throws SitoolsException
384
   *           if there is an error
385
   */
386
  private void zip(List<Reference> listOfFilesToOrder, ListReferencesAPI listReferences, Reference destRef)
387
    throws SitoolsException {
388

    
389
    String zipFileName = fileName;
390
    if (zipFileName == null || "".equals(zipFileName)) {
391
      zipFileName = OrderResourceUtils.ZIP_FILE_PATTERN.replace("{orderName}", ds.getName());
392
      zipFileName = zipFileName.replace("{timestamp}", formatedDate);
393
    }
394

    
395
    Reference zipRef = new Reference(RIAPUtils.getRiapBase() + settings.getString(Consts.APP_TMP_FOLDER_URL));
396
    zipRef.addSegment(zipFileName);
397
    zipRef.setExtensions("zip");
398

    
399
    // create an index and add it to the zip files
400
    Reference ref;
401
    Reference sourceRef;
402
    for (Iterator<Reference> iterator = listOfFilesToOrder.iterator(); iterator.hasNext();) {
403
      sourceRef = iterator.next();
404
      ref = new Reference(destRef);
405
      ref.addSegment(sourceRef.getLastSegment());
406
      listReferences.addReferenceDest(ref);
407
    }
408

    
409
    // copy the indexFile to the destination reference
410
    Reference destRefListFileInZip = new Reference(destRef);
411

    
412
    String orderFileListName = fileName;
413
    if (orderFileListName == null || "".equals(orderFileListName)) {
414
      orderFileListName = OrderResourceUtils.FILE_LIST_PATTERN.replace("{orderName}", ds.getName());
415
      orderFileListName = orderFileListName.replace("{timestamp}", formatedDate);
416
    }
417
    else {
418
      orderFileListName += "_fileList";
419
    }
420
    destRefListFileInZip.addSegment(orderFileListName);
421
    destRefListFileInZip.setExtensions("txt");
422
    try {
423
      listReferences.copyToUserStorage(destRefListFileInZip, getContext(), getClientInfo());
424
      listReferences.clearReferencesDest();
425
      listReferences.addReferenceSource(destRefListFileInZip);
426
    }
427
    catch (IOException e) {
428
      e.printStackTrace();
429
    }
430

    
431
    OrderResourceUtils.zipFiles(listOfFilesToOrder, settings.getTmpFolderUrl() + "/" + zipFileName + ".zip",
432
        getRequest().getClientInfo(), getContext());
433
    destRef.addSegment(zipRef.getLastSegment());
434
    OrderResourceUtils.copyFile(zipRef, destRef, getRequest().getClientInfo(), getContext());
435
    OrderResourceUtils.deleteFile(zipRef, getRequest().getClientInfo(), getContext());
436

    
437
    Reference destZipRef = new Reference(destRef);
438
    listReferences.addReferenceDest(destZipRef);
439

    
440
    destRef.setLastSegment("");
441
  }
442
}