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.context.task;
21  
22  import org.waarp.common.command.exception.CommandAbstractException;
23  import org.waarp.common.database.exception.WaarpDatabaseException;
24  import org.waarp.openr66.context.R66Session;
25  import org.waarp.openr66.database.data.DbTaskRunner;
26  import org.waarp.openr66.protocol.exception.OpenR66ProtocolNetworkException;
27  import org.waarp.openr66.protocol.localhandler.LocalChannelReference;
28  import org.waarp.openr66.s3.WaarpR66S3Client;
29  import org.waarp.openr66.s3.taskfactory.S3TaskFactory;
30  import org.waarp.openr66.s3.taskfactory.S3TaskFactory.S3TaskType;
31  
32  import java.io.File;
33  import java.util.HashMap;
34  import java.util.Map;
35  import java.util.Set;
36  
37  /**
38   * S3 GET Task<br>
39   * <br>
40   * The Rule shall be using SENDMD5THROUGHMODE or SENDTHROUGHMODE mode
41   * (respectively 7 or 5) or RECVMD5THROUGHMODE or RECVTHROUGHMODE mode
42   * (respectively 8 or 6) as pre-tasks since the file does not exist at
43   * startup.<br>
44   * <p>
45   * Result of arguments will be as a S3 GET command.<br>
46   * Format is the following:<br>
47   * "-URL url of S3 service <br>
48   * -accessKey access Key for S3 service <br>
49   * -secretKey secret Key for S3 service <br>
50   * -bucketName bucket Name where to retrieve the object <br>
51   * -sourceName source Name from the bucket to select the final Object <br>
52   * -file final File path (absolute or relative from IN path) <br>
53   * [-getTags [* or list of tag names comma separated without space]]" <br>
54   * <br>
55   * <br>
56   * The order of actions will be:<br>
57   * 1) connection to S3 service using access Key and Secret Key<br>
58   * 2) Retrieve from the bucket the source Object and store it in the file specified<br>
59   * 3) if getTags is true, the informations are added to transferInfo and fileInfo<br>
60   * 4) the current File is set to this new GET file<br>
61   * 5) the sender send an update on file information (name and size)<br>
62   */
63  public class S3GetTask extends S3AbstractTask {
64    private static final S3TaskFactory.S3TaskType taskType =
65        S3TaskFactory.S3TaskType.S3GET;
66  
67    /**
68     * Constructor
69     *
70     * @param argRule
71     * @param delay
72     * @param argTransfer
73     * @param session
74     */
75    public S3GetTask(final String argRule, final int delay,
76                     final String argTransfer, final R66Session session) {
77      super(TaskType.EXTENDED, delay, argRule, argTransfer, session);
78    }
79  
80    /**
81     * The order of actions will be:<br>
82     * 1) connection to S3 service using access Key and Secret Key<br>
83     * 2) Retrieve from the bucket the source Object and store it in the file specified<br>
84     * 3) if getTags is true, the informations are added to transferInfo and fileInfo<br>
85     * 4) the current File is set to this new GET file<br>
86     * 5) the sender send an update on file information (name and size)<br>
87     */
88    @Override
89    public void run() {
90      try {
91        internalRun();
92        // The update will be done after PRE task done
93        futureCompletion.setSuccess();
94      } catch (final OpenR66ProtocolNetworkException | CommandAbstractException |
95                     WaarpDatabaseException e) {
96        finalizeInError(e, "Error while S3 Action");
97      }
98    }
99  
100   void internalRun()
101       throws OpenR66ProtocolNetworkException, CommandAbstractException,
102              WaarpDatabaseException {
103     if (!getParams()) {
104       throw new OpenR66ProtocolNetworkException(
105           "Error while Parameters parsing");
106     }
107     final WaarpR66S3Client s3Client =
108         new WaarpR66S3Client(taskUtil.getAccessKey(), taskUtil.getSecretKey(),
109                              taskUtil.getUrl());
110     Map<String, String> map =
111         s3Client.getFile(taskUtil.getBucketName(), taskUtil.getSourceName(),
112                          taskUtil.getFile(), taskUtil.getGetTag());
113     final File file = taskUtil.getFile();
114     final String filePath = file.getAbsolutePath();
115     if (!file.canRead()) {
116       throw new OpenR66ProtocolNetworkException(
117           "File was not received in " + filePath);
118     }
119     final DbTaskRunner runner = session.getRunner();
120     if (taskUtil.getGetTag() && map != null && !map.isEmpty() &&
121         runner != null) {
122       final Set<String> keySet = taskUtil.getGetTags();
123       if (keySet != null && !keySet.isEmpty()) {
124         final Map<String, String> map2 = new HashMap<>(keySet.size());
125         for (final String key : keySet) {
126           final String value = map.get(key);
127           if (value != null) {
128             map2.put(key, value);
129           }
130         }
131         if (map2.isEmpty()) {
132           map = null;
133         } else {
134           map = map2;
135         }
136       }
137       if (map != null && !map.isEmpty()) {
138         runner.setTransferMap(map);
139       }
140     }
141 
142     final RenameTask renameTask = new RenameTask(filePath, 0, "", session);
143     renameTask.run();
144     if (renameTask.futureCompletion.isSuccess()) {
145       final LocalChannelReference lcr = session.getLocalChannelReference();
146       if (lcr != null && lcr.isSendThroughMode()) {
147         lcr.setSendThroughMode(false);
148       }
149       if (runner != null && runner.isSendThrough()) {
150         runner.checkThroughMode();
151       }
152       logger.debug("GET {} RENAME to {}", taskUtil.getSourceName(),
153                    taskUtil.getFile().getAbsolutePath());
154       futureCompletion.setSuccess();
155     } else {
156       logger.error("GET file OK but local file renaming in error");
157       futureCompletion.setResult(renameTask.futureCompletion.getResult());
158       futureCompletion.setFailure(renameTask.futureCompletion.getCause());
159     }
160   }
161 
162   @Override
163   public S3TaskType getS3TaskType() {
164     return taskType;
165   }
166 }