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);
}
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);
}
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;
}
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();
}
}
}
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);
}
}
}
Aggregations