/*
COPYRIGHT STATUS:
Dec 1st 2001, Fermi National Accelerator Laboratory (FNAL) documents and
software are sponsored by the U.S. Department of Energy under Contract No.
DE-AC02-76CH03000. Therefore, the U.S. Government retains a world-wide
non-exclusive, royalty-free license to publish or reproduce these documents
and software for U.S. Government purposes. All documents and software
available from this server are protected under the U.S. and Foreign
Copyright Laws, and FNAL reserves all rights.
Distribution of the software available from this server is free of
charge subject to the user following the terms of the Fermitools
Software Legal Information.
Redistribution and/or modification of the software shall be accompanied
by the Fermitools Software Legal Information (including the copyright
notice).
The user is asked to feed back problems, benefits, and/or suggestions
about the software to the Fermilab Software Providers.
Neither the name of Fermilab, the URA, nor the names of the contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
DISCLAIMER OF LIABILITY (BSD):
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL FERMILAB,
OR THE URA, OR THE U.S. DEPARTMENT of ENERGY, OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Liabilities of the Government:
This software is provided by URA, independent from its Prime Contract
with the U.S. Department of Energy. URA is acting independently from
the Government and in its own private capacity and is not acting on
behalf of the U.S. Government, nor as its contractor nor its agent.
Correspondingly, it is understood and agreed that the U.S. Government
has no connection to this software and in no manner whatsoever shall
be liable for nor assume any responsibility or obligation for any claim,
cost, or damages arising out of or resulting from the use of the software
available from this server.
Export Control:
All documents and software available from this server are subject to U.S.
export control laws. Anyone downloading information from this server is
obligated to secure any necessary Government licenses before exporting
documents or software obtained from this server.
*/
/*
* RemoteTurlGetter.java
*
* Created on April 30, 2003, 2:38 PM
*/
package org.dcache.srm.client;
import org.apache.axis.types.URI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.rmi.RemoteException;
import java.util.HashMap;
import org.dcache.srm.AbstractStorageElement;
import org.dcache.srm.SRMException;
import org.dcache.srm.request.RequestCredential;
import org.dcache.srm.util.RequestStatusTool;
import org.dcache.srm.util.SrmUrl;
import org.dcache.srm.v2_2.ArrayOfAnyURI;
import org.dcache.srm.v2_2.ArrayOfString;
import org.dcache.srm.v2_2.ArrayOfTGetFileRequest;
import org.dcache.srm.v2_2.ArrayOfTGetRequestFileStatus;
import org.dcache.srm.v2_2.ISRM;
import org.dcache.srm.v2_2.SrmPrepareToGetRequest;
import org.dcache.srm.v2_2.SrmPrepareToGetResponse;
import org.dcache.srm.v2_2.SrmReleaseFilesRequest;
import org.dcache.srm.v2_2.SrmReleaseFilesResponse;
import org.dcache.srm.v2_2.SrmStatusOfGetRequestRequest;
import org.dcache.srm.v2_2.SrmStatusOfGetRequestResponse;
import org.dcache.srm.v2_2.TAccessPattern;
import org.dcache.srm.v2_2.TConnectionType;
import org.dcache.srm.v2_2.TGetFileRequest;
import org.dcache.srm.v2_2.TGetRequestFileStatus;
import org.dcache.srm.v2_2.TReturnStatus;
import org.dcache.srm.v2_2.TStatusCode;
import org.dcache.srm.v2_2.TTransferParameters;
/**
*
* @author timur
*/
public final class RemoteTurlGetterV2 extends TurlGetterPutter {
private static final Logger logger = LoggerFactory.getLogger(RemoteTurlGetterV2.class);
private ISRM srmv2;
protected final String[] SURLs;
private final String caCertificatePath;
private final HashMap<String,Integer> pendingSurlsToIndex = new HashMap<>();
protected final int number_of_file_reqs;
protected boolean createdMap;
private String requestToken;
private final long lifetime;
SrmPrepareToGetResponse srmPrepareToGetResponse;
private final Transport transport;
final long retry_timout;
final int retry_num;
public RemoteTurlGetterV2(AbstractStorageElement storage,
RequestCredential credential, String[] SURLs,
String[] protocols, PropertyChangeListener listener,
long retry_timeout, int retry_num, long lifetime,
String caCertificatePath, Transport transport) {
super(storage,credential,protocols);
this.SURLs = SURLs;
this.caCertificatePath = caCertificatePath;
this.number_of_file_reqs = SURLs.length;
this.retry_num = retry_num;
this.retry_timout = retry_timeout;
this.lifetime = lifetime;
this.transport = transport;
addListener(listener);
}
protected void releaseFile(String surl) throws RemoteException, URI.MalformedURIException{
SrmReleaseFilesRequest srmReleaseFilesRequest = new SrmReleaseFilesRequest();
srmReleaseFilesRequest.setRequestToken(requestToken);
URI surlArray[] =
new URI[] { new URI(surl)};
srmReleaseFilesRequest.setArrayOfSURLs(new ArrayOfAnyURI(surlArray));
SrmReleaseFilesResponse srmReleaseFilesResponse =
srmv2.srmReleaseFiles(srmReleaseFilesRequest);
TReturnStatus returnStatus = srmReleaseFilesResponse.getReturnStatus();
if(returnStatus == null) {
logger.error("srmReleaseFiles return status is null");
return;
}
logger.debug("srmReleaseFilesResponse status code="+returnStatus.getStatusCode());
}
@Override
public void getInitialRequest() throws SRMException
{
if(number_of_file_reqs == 0) {
logger.debug("number_of_file_reqs is 0, nothing to do");
return;
}
logger.debug("SURLs[0] is "+SURLs[0]);
try {
java.net.URI srmUrl = SrmUrl.createWithDefaultPort(SURLs[0]);
srmv2 = new SRMClientV2(srmUrl,
credential.getDelegatedCredential(),
retry_timout,
retry_num,
false,
false,
caCertificatePath,
transport);
int len = SURLs.length;
TGetFileRequest fileRequests[] = new TGetFileRequest[len];
for(int i = 0; i < len; ++i) {
URI surl = new URI(SURLs[i]);
fileRequests[i] = new TGetFileRequest();
fileRequests[i].setSourceSURL(surl);
pendingSurlsToIndex.put(SURLs[i],i);
}
SrmPrepareToGetRequest srmPrepareToGetRequest = new SrmPrepareToGetRequest();
srmPrepareToGetRequest.setDesiredTotalRequestTime((int)lifetime);
TTransferParameters transferParameters =
new TTransferParameters();
transferParameters.setAccessPattern(TAccessPattern.TRANSFER_MODE);
transferParameters.setConnectionType(TConnectionType.WAN);
transferParameters.setArrayOfTransferProtocols(new ArrayOfString(protocols));
srmPrepareToGetRequest.setTransferParameters(transferParameters);
// we do not want to do this
// we do not know which storage type to use and
// it is read anyway
ArrayOfTGetFileRequest arrayOfTGetFileRequest =
new ArrayOfTGetFileRequest ();
arrayOfTGetFileRequest.setRequestArray(fileRequests);
srmPrepareToGetRequest.setArrayOfFileRequests(arrayOfTGetFileRequest);
srmPrepareToGetResponse = srmv2.srmPrepareToGet(srmPrepareToGetRequest);
}
catch(Exception e) {
logger.error("failed to connect to {} {}",SURLs[0],e.getMessage());
throw new SRMException("failed to connect to "+SURLs[0],e);
}
}
@Override
public void run() {
if(number_of_file_reqs == 0) {
logger.debug("number_of_file_reqs is 0, nothing to do");
return;
}
try {
int len = SURLs.length;
if(srmPrepareToGetResponse == null) {
throw new IOException(" null srmPrepareToGetResponse");
}
TReturnStatus status = srmPrepareToGetResponse.getReturnStatus();
if(status == null) {
throw new IOException(" null return status");
}
TStatusCode statusCode = status.getStatusCode();
if(statusCode == null) {
throw new IOException(" null status code");
}
if(RequestStatusTool.isFailedRequestStatus(status)){
throw new IOException("srmPrepareToGet submission failed, unexpected or failed status : "+
statusCode+" explanation="+status.getExplanation());
}
requestToken = srmPrepareToGetResponse.getRequestToken();
logger.debug(" srm returned requestToken = "+requestToken);
ArrayOfTGetRequestFileStatus arrayOfTGetRequestFileStatus =
srmPrepareToGetResponse.getArrayOfFileStatuses();
if(arrayOfTGetRequestFileStatus == null ) {
throw new IOException("returned GetRequestFileStatuses is an empty array");
}
TGetRequestFileStatus[] getRequestFileStatuses =
arrayOfTGetRequestFileStatus.getStatusArray();
if(getRequestFileStatuses == null ) {
throw new IOException("returned GetRequestFileStatuses is an empty array");
}
if(getRequestFileStatuses.length != len) {
throw new IOException("incorrect number of GetRequestFileStatuses"+
"in RequestStatus expected "+len+" received "+
getRequestFileStatuses.length);
}
boolean haveCompletedFileRequests = false;
while(!pendingSurlsToIndex.isEmpty()) {
long estimatedWaitInSeconds = Integer.MAX_VALUE;
for( TGetRequestFileStatus getRequestFileStatus:getRequestFileStatuses) {
URI surl = getRequestFileStatus.getSourceSURL();
if(surl == null) {
logger.error("invalid getRequestFileStatus, surl is null");
continue;
}
String surl_string = surl.toString();
if(!pendingSurlsToIndex.containsKey(surl_string)) {
logger.error("invalid getRequestFileStatus, surl = "+surl_string+
" not found");
continue;
}
TReturnStatus fileStatus = getRequestFileStatus.getStatus();
if(fileStatus == null) {
throw new IOException(" null file return status");
}
TStatusCode fileStatusCode = fileStatus.getStatusCode();
if(fileStatusCode == null) {
throw new IOException(" null file status code");
}
if(RequestStatusTool.isFailedFileRequestStatus(fileStatus)){
String error ="retreval of surl "+surl_string+
" failed, status = "+fileStatusCode+
" explanation="+fileStatus.getExplanation();
logger.error(error);
int indx = pendingSurlsToIndex.remove(surl_string);
notifyOfFailure(SURLs[indx], error, requestToken, null);
haveCompletedFileRequests = true;
continue;
}
if(getRequestFileStatus.getTransferURL() != null ) {
String transferUrl = getRequestFileStatus.getTransferURL().toString();
int indx = pendingSurlsToIndex.remove(surl_string);
long size=0;
if( getRequestFileStatus.getFileSize() != null ) {
size = getRequestFileStatus.getFileSize().longValue();
}
else {
logger.error("size is not set in FileStatus for SURL="+SURLs[indx]);
}
notifyOfTURL(SURLs[indx], transferUrl, requestToken,null,size );
haveCompletedFileRequests = true;
continue;
}
if(getRequestFileStatus.getEstimatedWaitTime() != null &&
getRequestFileStatus.getEstimatedWaitTime() < estimatedWaitInSeconds &&
getRequestFileStatus.getEstimatedWaitTime() >=1) {
estimatedWaitInSeconds = getRequestFileStatus
.getEstimatedWaitTime();
}
}
if(pendingSurlsToIndex.isEmpty()) {
logger.debug("no more pending transfers, breaking the loop");
break;
}
// do not wait longer then 60 seconds
if(estimatedWaitInSeconds > 60) {
estimatedWaitInSeconds = 60;
}
try {
logger.debug("sleeping "+estimatedWaitInSeconds+" seconds ...");
Thread.sleep(estimatedWaitInSeconds * 1000);
}
catch(InterruptedException ie) {
}
SrmStatusOfGetRequestRequest srmStatusOfGetRequestRequest =
new SrmStatusOfGetRequestRequest();
srmStatusOfGetRequestRequest.setRequestToken(requestToken);
// if we do not have completed file requests
// we want to get status for all files
// we do not need to specify any surls
int expectedResponseLength;
if(haveCompletedFileRequests){
String [] pendingSurlStrings =
pendingSurlsToIndex.keySet()
.toArray(new String[pendingSurlsToIndex.size()]);
expectedResponseLength= pendingSurlStrings.length;
URI surlArray[] = new URI[expectedResponseLength];
for(int i=0;i<expectedResponseLength;++i){
URI surl =
new URI(pendingSurlStrings[i]);
surlArray[i]=surl;
}
srmStatusOfGetRequestRequest.setArrayOfSourceSURLs(new ArrayOfAnyURI(surlArray));
}
else {
expectedResponseLength = SURLs.length;
URI surlArray[] = new URI[expectedResponseLength];
for(int i=0;i<expectedResponseLength;++i){
URI surl =
new URI(SURLs[i]);
surlArray[i]=surl;
}
srmStatusOfGetRequestRequest.setArrayOfSourceSURLs(new ArrayOfAnyURI(surlArray));
}
SrmStatusOfGetRequestResponse srmStatusOfGetRequestResponse =
srmv2.srmStatusOfGetRequest(srmStatusOfGetRequestRequest);
if(srmStatusOfGetRequestResponse == null) {
throw new IOException(" null srmStatusOfGetRequestResponse");
}
arrayOfTGetRequestFileStatus =
srmStatusOfGetRequestResponse.getArrayOfFileStatuses();
if(arrayOfTGetRequestFileStatus == null ) {
logger.error( "incorrect number of RequestFileStatuses");
throw new IOException("incorrect number of RequestFileStatuses");
}
getRequestFileStatuses = arrayOfTGetRequestFileStatus.getStatusArray();
if(getRequestFileStatuses == null ||
getRequestFileStatuses.length != expectedResponseLength) {
logger.error( "incorrect number of RequestFileStatuses");
throw new IOException("incorrect number of RequestFileStatuses");
}
status = srmStatusOfGetRequestResponse.getReturnStatus();
if(status == null) {
throw new IOException(" null return status");
}
statusCode = status.getStatusCode();
if(statusCode == null) {
throw new IOException(" null status code");
}
if(RequestStatusTool.isFailedRequestStatus(status)){
throw new IOException("srmPrepareToGet update failed, unexpected or failed status : "+
statusCode+" explanation="+status.getExplanation());
}
}
}
catch(IOException e) {
logger.error(e.toString());
notifyOfFailure(e);
}
}
public static void staticReleaseFile(RequestCredential credential,
String surl,
String requestToken,
long retry_timeout,
int retry_num,
String caCertificatePath, Transport transport) throws Exception
{
java.net.URI srmUrl = SrmUrl.createWithDefaultPort(surl);
SRMClientV2 srmv2 = new SRMClientV2(srmUrl,
credential.getDelegatedCredential(),
retry_timeout,
retry_num,
false,
false,
caCertificatePath,
transport);
URI surlArray[] = new URI[1];
surlArray[0]= new URI(surl);
SrmReleaseFilesRequest srmReleaseFilesRequest = new SrmReleaseFilesRequest();
srmReleaseFilesRequest.setRequestToken(requestToken);
srmReleaseFilesRequest.setArrayOfSURLs(new ArrayOfAnyURI(surlArray));
SrmReleaseFilesResponse srmReleaseFilesResponse =
srmv2.srmReleaseFiles(srmReleaseFilesRequest);
TReturnStatus returnStatus = srmReleaseFilesResponse.getReturnStatus();
if(returnStatus == null) {
logger.error("srmReleaseFiles return status is null");
return;
}
logger.debug("srmReleaseFilesResponse status code="+returnStatus.getStatusCode());
}
}