Search in sources :

Example 1 with TransmissionException

use of org.opendatakit.briefcase.model.TransmissionException in project briefcase by opendatakit.

the class ServerFetcher method downloadMediaFileIfChanged.

private void downloadMediaFileIfChanged(File mediaDir, MediaFile m, FormStatus fs) throws Exception {
    File mediaFile = new File(mediaDir, m.filename);
    if (m.hash.startsWith(MD5_COLON_PREFIX)) {
        // see if the file exists and has the same hash
        String hashToMatch = m.hash.substring(MD5_COLON_PREFIX.length());
        if (mediaFile.exists()) {
            String hash = FileSystemUtils.getMd5Hash(mediaFile);
            if (hash.equalsIgnoreCase(hashToMatch))
                return;
            mediaFile.delete();
        }
    }
    if (isCancelled()) {
        fs.setStatusString("aborting fetch of media file...", true);
        EventBus.publish(new FormStatusEvent(fs));
        throw new TransmissionException("Transfer cancelled by user.");
    }
    AggregateUtils.commonDownloadFile(serverInfo, mediaFile, m.downloadUrl);
}
Also used : TransmissionException(org.opendatakit.briefcase.model.TransmissionException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) File(java.io.File)

Example 2 with TransmissionException

use of org.opendatakit.briefcase.model.TransmissionException in project briefcase by opendatakit.

the class ServerUploader method uploadForm.

public boolean uploadForm(FormStatus formToTransfer, File briefcaseFormDefFile, File briefcaseFormMediaDir) {
    // very similar to upload submissions...
    URI u;
    try {
        u = AggregateUtils.testServerConnectionWithHeadRequest(serverInfo, "formUpload");
    } catch (TransmissionException e) {
        formToTransfer.setStatusString(e.getMessage(), false);
        EventBus.publish(new FormStatusEvent(formToTransfer));
        return false;
    }
    // try to send form...
    if (!briefcaseFormDefFile.exists()) {
        String msg = "Form definition file not found: " + briefcaseFormDefFile.getAbsolutePath();
        formToTransfer.setStatusString(msg, false);
        EventBus.publish(new FormStatusEvent(formToTransfer));
        return false;
    }
    // find all files in parent directory
    File[] allFiles = null;
    if (briefcaseFormMediaDir != null) {
        allFiles = briefcaseFormMediaDir.listFiles();
    }
    // clean up the list, removing anything that is suspicious
    // or that we won't attempt to upload. For OpenRosa servers,
    // we'll upload just about everything...
    List<File> files = new ArrayList<>();
    if (allFiles != null) {
        for (File f : allFiles) {
            String fileName = f.getName();
            if (fileName.startsWith(".")) {
                // potential Apple file attributes file -- ignore it
                continue;
            }
            files.add(f);
        }
    }
    DocumentDescription formDefinitionUploadDescription = new DocumentDescription("Form definition upload failed.  Detailed error: ", "Form definition upload failed.", "form definition", terminationFuture);
    return AggregateUtils.uploadFilesToServer(serverInfo, u, "form_def_file", briefcaseFormDefFile, files, formDefinitionUploadDescription, null, terminationFuture, formToTransfer);
}
Also used : DocumentDescription(org.opendatakit.briefcase.model.DocumentDescription) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) ArrayList(java.util.ArrayList) URI(java.net.URI) File(java.io.File)

Example 3 with TransmissionException

use of org.opendatakit.briefcase.model.TransmissionException in project briefcase by opendatakit.

the class ServerFetcher method downloadFormAndSubmissionFiles.

public boolean downloadFormAndSubmissionFiles(List<FormStatus> formsToTransfer) {
    boolean allSuccessful = true;
    // boolean error = false;
    int total = formsToTransfer.size();
    for (int i = 0; i < total; i++) {
        FormStatus fs = formsToTransfer.get(i);
        if (isCancelled()) {
            fs.setStatusString("Aborted. Skipping fetch of form and submissions...", true);
            EventBus.publish(new FormStatusEvent(fs));
            return false;
        }
        RemoteFormDefinition fd = getRemoteFormDefinition(fs);
        fs.setStatusString("Fetching form definition", true);
        EventBus.publish(new FormStatusEvent(fs));
        try {
            File tmpdl = FileSystemUtils.getTempFormDefinitionFile();
            AggregateUtils.commonDownloadFile(serverInfo, tmpdl, fd.getDownloadUrl());
            fs.setStatusString("resolving against briefcase form definitions", true);
            EventBus.publish(new FormStatusEvent(fs));
            boolean successful = false;
            BriefcaseFormDefinition briefcaseLfd;
            DatabaseUtils formDatabase = null;
            try {
                try {
                    briefcaseLfd = BriefcaseFormDefinition.resolveAgainstBriefcaseDefn(tmpdl);
                    if (briefcaseLfd.needsMediaUpdate()) {
                        if (fd.getManifestUrl() != null) {
                            File mediaDir = FileSystemUtils.getMediaDirectory(briefcaseLfd.getFormDirectory());
                            String error = downloadManifestAndMediaFiles(mediaDir, fs);
                            if (error != null) {
                                allSuccessful = false;
                                fs.setStatusString("Error fetching form definition: " + error, false);
                                EventBus.publish(new FormStatusEvent(fs));
                                continue;
                            }
                        }
                    }
                    formDatabase = DatabaseUtils.newInstance(briefcaseLfd.getFormDirectory());
                } catch (BadFormDefinition e) {
                    allSuccessful = false;
                    String msg = "Error parsing form definition";
                    log.error(msg, e);
                    fs.setStatusString(msg + ": " + e.getMessage(), false);
                    EventBus.publish(new FormStatusEvent(fs));
                    continue;
                }
                fs.setStatusString("preparing to retrieve instance data", true);
                EventBus.publish(new FormStatusEvent(fs));
                File formInstancesDir = FileSystemUtils.getFormInstancesDirectory(briefcaseLfd.getFormDirectory());
                // this will publish events
                successful = downloadAllSubmissionsForForm(formInstancesDir, formDatabase, briefcaseLfd, fs);
            } catch (SQLException | FileSystemException e) {
                allSuccessful = false;
                String msg = "unable to open form database";
                log.error(msg, e);
                fs.setStatusString(msg + ": " + e.getMessage(), false);
                EventBus.publish(new FormStatusEvent(fs));
                continue;
            } finally {
                if (formDatabase != null) {
                    try {
                        formDatabase.close();
                    } catch (SQLException e) {
                        allSuccessful = false;
                        String msg = "unable to close form database";
                        log.error(msg, e);
                        fs.setStatusString(msg + ": " + e.getMessage(), false);
                        EventBus.publish(new FormStatusEvent(fs));
                        continue;
                    }
                }
            }
            allSuccessful = allSuccessful && successful;
            // on success, we haven't actually set a success event (because we don't know we're done)
            if (successful) {
                fs.setStatusString(SUCCESS_STATUS, true);
                EventBus.publish(new FormStatusEvent(fs));
            } else {
                fs.setStatusString(FAILED_STATUS, true);
                EventBus.publish(new FormStatusEvent(fs));
            }
        } catch (SocketTimeoutException se) {
            allSuccessful = false;
            log.error("error accessing URL", se);
            fs.setStatusString("Communications to the server timed out. Detailed message: " + se.getLocalizedMessage() + " while accessing: " + fd.getDownloadUrl() + " A network login screen may be interfering with the transmission to the server.", false);
            EventBus.publish(new FormStatusEvent(fs));
        } catch (IOException e) {
            allSuccessful = false;
            log.error("error accessing form download URL", e);
            fs.setStatusString("Unexpected error: " + e.getLocalizedMessage() + " while accessing: " + fd.getDownloadUrl() + " A network login screen may be interfering with the transmission to the server.", false);
            EventBus.publish(new FormStatusEvent(fs));
        } catch (FileSystemException | TransmissionException | URISyntaxException e) {
            allSuccessful = false;
            log.error("error accessing form download URL", e);
            fs.setStatusString("Unexpected error: " + e.getLocalizedMessage() + " while accessing: " + fd.getDownloadUrl(), false);
            EventBus.publish(new FormStatusEvent(fs));
        }
    }
    return allSuccessful;
}
Also used : SQLException(java.sql.SQLException) FormStatusEvent(org.opendatakit.briefcase.model.FormStatusEvent) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) FileSystemException(org.opendatakit.briefcase.model.FileSystemException) SocketTimeoutException(java.net.SocketTimeoutException) RemoteFormDefinition(org.opendatakit.briefcase.model.RemoteFormDefinition) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) FormStatus(org.opendatakit.briefcase.model.FormStatus) BriefcaseFormDefinition(org.opendatakit.briefcase.model.BriefcaseFormDefinition) File(java.io.File)

Example 4 with TransmissionException

use of org.opendatakit.briefcase.model.TransmissionException in project briefcase by opendatakit.

the class AggregateUtils method commonDownloadFile.

/**
 * Common routine to download a document from the downloadUrl and save the
 * contents in the file 'f'. Shared by media file download and form file
 * download.
 *
 * @param f
 * @param downloadUrl
 * @throws URISyntaxException
 * @throws IOException
 * @throws ClientProtocolException
 * @throws TransmissionException
 */
public static final void commonDownloadFile(ServerConnectionInfo serverInfo, File f, String downloadUrl) throws URISyntaxException, IOException, TransmissionException {
    log.info("Downloading URL {} into {}", downloadUrl, f);
    // OK. We need to download it because we either:
    // (1) don't have it
    // (2) don't know if it is changed because the hash is not md5
    // (3) know it is changed
    URI u = null;
    try {
        log.info("Parsing URL {}", downloadUrl);
        URL uurl = new URL(downloadUrl);
        u = uurl.toURI();
    } catch (MalformedURLException | URISyntaxException e) {
        log.warn("bad download url", e);
        throw e;
    }
    HttpClient httpclient = WebUtils.createHttpClient();
    // get shared HttpContext so that authentication and cookies are retained.
    HttpClientContext localContext = WebUtils.getHttpContext();
    // set up request...
    HttpGet req = WebUtils.createOpenRosaHttpGet(u);
    WebUtils.setCredentials(localContext, serverInfo, u);
    HttpResponse response = null;
    // try
    {
        response = httpclient.execute(req, localContext);
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == 401) {
            // We reset the Http context to force next request to authenticate itself
            WebUtils.resetHttpContext();
            throw new TransmissionException("Authentication failure");
        } else if (statusCode != 200) {
            String errMsg = "Fetch failed. Detailed reason: " + response.getStatusLine().getReasonPhrase() + " (" + statusCode + ")";
            log.error(errMsg);
            flushEntityBytes(response.getEntity());
            throw new TransmissionException(errMsg);
        }
        try (InputStream is = response.getEntity().getContent();
            OutputStream os = new FileOutputStream(f)) {
            byte[] buf = new byte[1024];
            int len;
            while ((len = is.read(buf)) > 0) {
                os.write(buf, 0, len);
            }
            os.flush();
        }
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) InputStream(java.io.InputStream) HttpGet(org.apache.http.client.methods.HttpGet) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) HttpResponse(org.apache.http.HttpResponse) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) URL(java.net.URL) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) HttpClient(org.apache.http.client.HttpClient) FileOutputStream(java.io.FileOutputStream)

Example 5 with TransmissionException

use of org.opendatakit.briefcase.model.TransmissionException in project briefcase by opendatakit.

the class AggregateUtils method testServerConnectionWithHeadRequest.

/**
 * Send a HEAD request to the server to confirm the validity of the URL and
 * credentials.
 *
 * @param serverInfo
 * @param actionAddr
 * @return the confirmed URI of this action.
 * @throws TransmissionException
 */
public static final URI testServerConnectionWithHeadRequest(ServerConnectionInfo serverInfo, String actionAddr) throws TransmissionException {
    String urlString = serverInfo.getUrl();
    if (urlString.endsWith("/")) {
        urlString = urlString + actionAddr;
    } else {
        urlString = urlString + "/" + actionAddr;
    }
    log.info("Parsing URL {}", urlString);
    URI u;
    try {
        URL url = new URL(urlString);
        u = url.toURI();
    } catch (MalformedURLException e) {
        String msg = "Invalid url for " + actionAddr + ". Failed with error: " + e.getMessage();
        if (!urlString.toLowerCase().startsWith("http://") && !urlString.toLowerCase().startsWith("https://")) {
            msg += ". Did you forget to prefix the address with 'http://' or 'https://' ?";
        }
        log.warn(msg, e);
        throw new TransmissionException(msg);
    } catch (URISyntaxException e) {
        String msg = "Invalid uri for " + actionAddr + ". Failed with error: " + e.getMessage();
        log.warn(msg, e);
        throw new TransmissionException(msg);
    }
    HttpClient httpClient = WebUtils.createHttpClient();
    // get shared HttpContext so that authentication and cookies are retained.
    HttpClientContext localContext = WebUtils.getHttpContext();
    WebUtils.setCredentials(localContext, serverInfo, u);
    {
        // we need to issue a head request
        HttpHead httpHead = WebUtils.createOpenRosaHttpHead(u);
        // prepare response
        HttpResponse response = null;
        try {
            response = httpClient.execute(httpHead, localContext);
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 401) {
                // We reset the Http context to force next request to authenticate itself
                WebUtils.resetHttpContext();
                throw new TransmissionException("Authentication failure");
            } else if (statusCode == 204) {
                Header[] openRosaVersions = response.getHeaders(WebUtils.OPEN_ROSA_VERSION_HEADER);
                if (openRosaVersions == null || openRosaVersions.length == 0) {
                    String msg = "Header missing: " + WebUtils.OPEN_ROSA_VERSION_HEADER;
                    log.warn(msg);
                    throw new TransmissionException(msg);
                }
                Header[] locations = response.getHeaders("Location");
                if (locations != null && locations.length == 1) {
                    try {
                        URL url = new URL(locations[0].getValue());
                        URI uNew = url.toURI();
                        log.info("Redirection to URI {}", uNew);
                        if (u.getHost().equalsIgnoreCase(uNew.getHost())) {
                            // trust the server to tell us a new location
                            // ... and possibly to use https instead.
                            u = uNew;
                            // out.
                            return u;
                        } else {
                            // Don't follow a redirection attempt to a different host.
                            // We can't tell if this is a spoof or not.
                            String msg = "Unexpected redirection attempt";
                            log.warn(msg);
                            throw new TransmissionException(msg);
                        }
                    } catch (Exception e) {
                        String msg = "Unexpected exception: " + e.getLocalizedMessage();
                        log.warn(msg, e);
                        throw new TransmissionException(msg);
                    }
                } else {
                    String msg = "The url is not ODK Aggregate - status code on Head request: " + statusCode;
                    log.warn(msg);
                    throw new TransmissionException(msg);
                }
            } else {
                // may be a server that does not handle HEAD requests
                if (response.getEntity() != null) {
                    try {
                        // don't really care about the stream...
                        InputStream is = response.getEntity().getContent();
                        // read to end of stream...
                        final long count = 1024L;
                        while (is.skip(count) == count) ;
                        is.close();
                    } catch (Exception e) {
                        log.error("failed to process http stream", e);
                    }
                }
                String msg = "The username or password may be incorrect or the url is not ODK Aggregate - status code on Head request: " + statusCode;
                log.warn(msg);
                throw new TransmissionException(msg);
            }
        } catch (Exception e) {
            String msg = "Unexpected exception: " + e.getLocalizedMessage();
            log.warn(msg, e);
            throw new TransmissionException(msg);
        }
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) InputStream(java.io.InputStream) HttpResponse(org.apache.http.HttpResponse) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) URL(java.net.URL) HttpHead(org.apache.http.client.methods.HttpHead) ClientProtocolException(org.apache.http.client.ClientProtocolException) URISyntaxException(java.net.URISyntaxException) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) MalformedURLException(java.net.MalformedURLException) XmlDocumentFetchException(org.opendatakit.briefcase.model.XmlDocumentFetchException) IOException(java.io.IOException) MetadataUpdateException(org.opendatakit.briefcase.model.MetadataUpdateException) UnknownHostException(java.net.UnknownHostException) Header(org.apache.http.Header) TransmissionException(org.opendatakit.briefcase.model.TransmissionException) HttpClient(org.apache.http.client.HttpClient)

Aggregations

TransmissionException (org.opendatakit.briefcase.model.TransmissionException)5 File (java.io.File)3 URI (java.net.URI)3 URISyntaxException (java.net.URISyntaxException)3 FormStatusEvent (org.opendatakit.briefcase.model.FormStatusEvent)3 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 MalformedURLException (java.net.MalformedURLException)2 URL (java.net.URL)2 HttpResponse (org.apache.http.HttpResponse)2 HttpClient (org.apache.http.client.HttpClient)2 HttpClientContext (org.apache.http.client.protocol.HttpClientContext)2 FileOutputStream (java.io.FileOutputStream)1 OutputStream (java.io.OutputStream)1 SocketTimeoutException (java.net.SocketTimeoutException)1 UnknownHostException (java.net.UnknownHostException)1 SQLException (java.sql.SQLException)1 ArrayList (java.util.ArrayList)1 Header (org.apache.http.Header)1 ClientProtocolException (org.apache.http.client.ClientProtocolException)1