Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
0176035
Creates POJO to hold the information about file that was created by t…
velmer Jun 12, 2019
c9ef418
Extracts service to provide operations for communication with the Swi…
velmer Jun 12, 2019
e0cdd52
Extracts service to provide operations for processed ImageTasks
velmer Jun 12, 2019
021743f
Removes duplicated code from ProcessedImagesEmailBuilder
velmer Jun 13, 2019
0b794a6
Creates POJO to represent a list of ImageTaskFile
velmer Jun 13, 2019
70e7f42
Init renaming of resources to better understanding, separating a reso…
velmer Jun 13, 2019
d846927
Creates method to return from Catalog a list of ImageTasks given a li…
velmer Jun 13, 2019
2ce7dba
Creates api route to return the files of processed image tasks that h…
velmer Jun 13, 2019
fe38904
Extracts methods in ImageTaskFiles retrieval
velmer Jun 14, 2019
c4c466d
Creates Service to handle email operations
velmer Jun 14, 2019
fd4dbc5
Creates reduced constructor for ImageTask
velmer Jun 14, 2019
e4c4624
Creates constructor from JSONObject for ImageTaskFileList
velmer Jun 14, 2019
0ac4ea0
Replaces ProcessedImagesEmailBuilder by EmailService and refacts Imag…
velmer Jun 14, 2019
c4d0739
Fix SQL query to find image tasks that have its ID in specified list …
velmer Jun 14, 2019
dbb0982
Merge branch 'share-task-access-url' into request-image-task-access-url
velmer Jun 14, 2019
55560c1
Updates way of sending list of IDs of ImageTasks (before it was throu…
velmer Jun 14, 2019
c181d4e
Adds missing setter methods
velmer Jun 15, 2019
3625889
Adds error message when getting of files of ImageTask fails
velmer Jun 15, 2019
e34b94f
Undo unnecessary modifications in `ProcessedImagesEmailBuilder`
velmer Jun 15, 2019
55612e0
Utilizes extracted `ProcessedImagesService` in `ProcessedImagesEmailB…
velmer Jun 15, 2019
49004d6
Merge branch 'share-task-access-url' into request-image-task-access-url
velmer Jun 15, 2019
730acf1
Fixes javadoc and constant name
velmer Jun 17, 2019
77f2965
Creates toJSON and constructor from JSON for `ImageTaskFile`
velmer Jun 17, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,6 @@ public List<ImageTask> getProcessedImages(
String inputGathering,
String inputPreprocessing,
String algorithmExecution) throws SQLException;

List<ImageTask> getImageTasks(String[] imageTasksIds) throws SQLException;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
package org.fogbowcloud.saps.engine.core.database;

import java.sql.Array;
import java.sql.Connection;
import java.sql.JDBCType;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.dbcp2.BasicDataSource;
Expand Down Expand Up @@ -1020,6 +1017,27 @@ public List<ImageTask> getAllTasks() throws SQLException {
}
}

private static final String SELECT_IMAGES_IN_ID_LIST_SQL = "SELECT * FROM " + IMAGE_TABLE_NAME
+ " WHERE " + TASK_ID_COL + " IN (?)";

@Override
public List<ImageTask> getImageTasks(String[] imageTasksIds) throws SQLException {
PreparedStatement statement = null;
Connection conn = null;
try {
conn = getConnection();
statement = conn.prepareStatement(SELECT_IMAGES_IN_ID_LIST_SQL);
Array imageTasksIdsArray = conn.createArrayOf(JDBCType.VARCHAR.getName(), imageTasksIds);
statement.setArray(1, imageTasksIdsArray);
statement.setQueryTimeout(300);
statement.execute();
ResultSet rs = statement.getResultSet();
return extractImageTaskFrom(rs);
} finally {
close(statement, conn);
}
}

private static final String SELECT_USER_SQL = "SELECT * FROM " + USERS_TABLE_NAME + " WHERE "
+ USER_EMAIL_COL + " = ?";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ void removeUserNotification(String submissionId, String taskId, String userEmail
boolean isUserNotifiable(String userEmail) throws SQLException;

List<ImageTask> searchProcessedTasks(SubmissionParameters submissionParameters);

List<ImageTask> getImageTasks(String[] imageTasksIds) throws SQLException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,11 @@ public List<ImageTask> getTaskListInDB() throws SQLException, ParseException {
return imageStore.getAllTasks();
}

@Override
public List<ImageTask> getImageTasks(String[] imageTasksIds) throws SQLException {
return imageStore.getImageTasks(imageTasksIds);
}

@Override
public List<Ward> getUsersToNotify() throws SQLException {
List<Ward> wards = imageStore.getUsersToNotify();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,13 @@ public ImageTask(JSONObject imageTaskJsonObject) throws JSONException {
);
}

public String getTaskId() {
public ImageTask(String taskId, String region, Date imageDate) {
this.taskId = taskId;
this.region = region;
this.imageDate = imageDate;
}

public String getTaskId() {
return taskId;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.fogbowcloud.saps.engine.core.pojo;

import org.fogbowcloud.saps.engine.core.model.ImageTask;
import org.json.JSONException;
import org.json.JSONObject;

/**
* Holds the information of a file generated by the processing of a {@link ImageTask}.
*/
public class ImageTaskFile {

private static final String NAME_KEY = "name";
private static final String URL_KEY = "url";

private String path;
private String name;
private String URL;

public ImageTaskFile(String path, String name) {
this(path, name, null);
}

public ImageTaskFile(String path, String name, String URL) {
this.path = path;
this.name = name;
this.URL = URL;
}

public ImageTaskFile(JSONObject jsonObject) throws JSONException {
this(null,
jsonObject.getString(NAME_KEY),
jsonObject.getString(URL_KEY));
}

public JSONObject toJSON() throws JSONException {
JSONObject imageTaskFileJSONObject = new JSONObject();
imageTaskFileJSONObject.put(NAME_KEY, name);
imageTaskFileJSONObject.put(URL_KEY, URL);
return imageTaskFileJSONObject;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getURL() {
return URL;
}

public void setURL(String URL) {
this.URL = URL;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.fogbowcloud.saps.engine.core.pojo;

import org.fogbowcloud.saps.engine.core.model.ImageTask;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* Represents a list of {@link ImageTaskFile} for a specific {@link ImageTask}.
*/
public class ImageTaskFileList {

private static final String IMAGE_TASK_ID = "imageTaskId";
private static final String REGION = "region";
private static final String COLLECTION_TIER_NAME = "collectionTierName";
private static final String IMAGE_DATE = "imageDate";
private static final String FILES = "files";
private static final String STATUS = "status";
private static final String UNAVAILABLE = "UNAVAILABLE";

private ImageTask imageTask;
private List<ImageTaskFile> imageTaskFiles;

public ImageTaskFileList(ImageTask imageTask, List<ImageTaskFile> imageTaskFiles) {
this.imageTask = imageTask;
this.imageTaskFiles = imageTaskFiles;
}

public ImageTaskFileList(JSONObject jsonObject) throws JSONException {
ImageTask imageTask = new ImageTask(jsonObject.getString(IMAGE_TASK_ID),
jsonObject.getString(REGION),
(Date) jsonObject.get(IMAGE_DATE)
);
List<ImageTaskFile> imageTaskFiles = new ArrayList<>();
JSONArray filesJSONArray = jsonObject.getJSONArray(FILES);
for (int i = 0; i < filesJSONArray.length(); i++) {
imageTaskFiles.add(new ImageTaskFile(filesJSONArray.optJSONObject(i)));
}
this.imageTask = imageTask;
this.imageTaskFiles = imageTaskFiles;
}

public JSONObject toJSON() throws JSONException {
JSONObject jsonObject = new JSONObject();
jsonObject.put(IMAGE_TASK_ID, imageTask.getTaskId());
try {
jsonObject.put(REGION, imageTask.getRegion());
jsonObject.put(IMAGE_DATE, imageTask.getImageDate());
jsonObject.put(COLLECTION_TIER_NAME, imageTask.getCollectionTierName());
JSONArray imageTaskFilesJSONArray = new JSONArray();
for (ImageTaskFile imageTaskFile : imageTaskFiles) {
imageTaskFilesJSONArray.put(imageTaskFile.toJSON());
}
jsonObject.put(FILES, imageTaskFilesJSONArray);
} catch (JSONException e) {
jsonObject.put(STATUS, UNAVAILABLE);
throw e;
}
return jsonObject;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.fogbowcloud.saps.engine.core.service;

import org.fogbowcloud.saps.engine.scheduler.util.SapsPropertiesConstants;
import org.fogbowcloud.saps.notifier.GoogleMail;

import java.util.Properties;

/**
* Service to handle Email operations.
*/
public class EmailService {

/**
* Asynchronously sends an email with specified parameters and default
* no-reply email and password.
*
* @param recipientEmail Recipient email.
* @param title Email title.
* @param message Email message.
*/
public static void sendEmail(
Properties properties,
String recipientEmail,
String title,
String message) {
sendEmail(
properties.getProperty(SapsPropertiesConstants.NO_REPLY_EMAIL),
properties.getProperty(SapsPropertiesConstants.NO_REPLY_PASS),
recipientEmail,
title,
message
);
}

/**
* Asynchronously sends an email with specified parameters.
*
* @param username Username of sender account.
* @param password Password of sender account.
* @param recipientEmail Recipient email.
* @param title Email title.
* @param message Email message.
*/
public static void sendEmail(
String username,
String password,
String recipientEmail,
String title,
String message) {
Thread emailThread = new Thread(() -> GoogleMail.Send(
username,
password,
recipientEmail,
title,
message
));
emailThread.start();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package org.fogbowcloud.saps.engine.core.service;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.fogbowcloud.manager.core.plugins.identity.openstack.KeystoneV3IdentityPlugin;
import org.fogbowcloud.manager.occi.model.Token;
import org.fogbowcloud.saps.engine.core.model.ImageTask;
import org.fogbowcloud.saps.engine.scheduler.util.SapsPropertiesConstants;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;

/**
* Service that provides operations for communication with Object Store.
*/
public class ObjectStoreService {

private static final Logger LOGGER = Logger.getLogger(ObjectStoreService.class);

private static final String HTTPS_SCHEME = "https";
private static final String PROJECT_ID = "projectId";
private static final String USER_ID = "userId";
private static final String PASSWORD = "password";
private static final String AUTH_URL = "authUrl";
private static final String PATH_PARAM = "path";
private static final String X_AUTH_TOKEN = "X-Auth-Token";
private static final String HTTP_RESPONSE_SEPARATOR = "\n";
private static final String ARCHIVER_PATH = "archiver/";
private static final String DATA_OUTPUT_PATH = "/data/output/";

/**
* Returns all the paths for every file generated by the {@link ImageTask}
* that had its ID specified.
*
* @param properties Properties that contains Object Store information.
* @param imageTaskId ImageTask's ID.
* @return List of paths.
*/
public static List<String> getImageTaskFilesPaths(Properties properties, String imageTaskId) {
List<String> imageTaskFilesPaths = new ArrayList<>();
try {
HttpClient client = HttpClients.createDefault();
HttpGet httpget = prepareObjectStoreRequest(properties, imageTaskId);
HttpResponse response = client.execute(httpget);
imageTaskFilesPaths = parseHttpResponse(response);
} catch (IOException | URISyntaxException e) {
LOGGER.error("Error while retrieving path of files of ImageTask" +
" with ID: " + imageTaskId, e);
}
return imageTaskFilesPaths;
}

/**
* Parses the given {@link HttpResponse} to a list of Strings.
*
* @param response Response to be parsed.
* @return List of Strings parsed from response.
* @throws IOException
*/
private static List<String> parseHttpResponse(HttpResponse response) throws IOException {
return Arrays.asList(EntityUtils.toString(response.getEntity()).split(HTTP_RESPONSE_SEPARATOR));
}

/**
* Prepares a {@link HttpGet} request for the Object Store.
*
* @param properties Properties that contains Object Store information.
* @param imageTaskId ImageTask's ID.
* @return A {@link HttpGet} request.
* @throws URISyntaxException
*/
private static HttpGet prepareObjectStoreRequest(Properties properties,
String imageTaskId) throws URISyntaxException {
String objectStoreHost = properties.getProperty(SapsPropertiesConstants.SWIFT_OBJECT_STORE_HOST);
String objectStorePath = properties.getProperty(SapsPropertiesConstants.SWIFT_OBJECT_STORE_PATH);
String objectStoreContainer = properties.getProperty(SapsPropertiesConstants.SWIFT_OBJECT_STORE_CONTAINER);
String pathParamValue = ARCHIVER_PATH + imageTaskId + DATA_OUTPUT_PATH;
URI uri = new URIBuilder()
.setScheme(HTTPS_SCHEME)
.setHost(objectStoreHost)
.setPath(objectStorePath + "/" + objectStoreContainer)
.addParameter(PATH_PARAM, pathParamValue)
.build();
LOGGER.debug("Getting list of files for task " + imageTaskId + " from " + uri);
HttpGet httpget = new HttpGet(uri);
Token token = getKeystoneToken(properties);
httpget.addHeader(X_AUTH_TOKEN, token.getAccessId());
return httpget;
}

/**
* Returns a Keystone Token for the given properties.
*
* @param properties Properties that contains Object Store information.
* @return Keystone Token.
*/
private static Token getKeystoneToken(Properties properties) {
Map<String, String> credentials = new HashMap<>();
credentials.put(PROJECT_ID, properties.getProperty(SapsPropertiesConstants.SWIFT_PROJECT_ID));
credentials.put(USER_ID, properties.getProperty(SapsPropertiesConstants.SWIFT_USER_ID));
credentials.put(PASSWORD, properties.getProperty(SapsPropertiesConstants.SWIFT_PASSWORD));
credentials.put(AUTH_URL, properties.getProperty(SapsPropertiesConstants.SWIFT_AUTH_URL));
KeystoneV3IdentityPlugin keystone = new KeystoneV3IdentityPlugin(properties);
return keystone.createToken(credentials);
}

}
Loading