forked from nus-cs2103-AY1718S2/addressbook-level4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Network component #58
Merged
qiu-siqi
merged 8 commits into
CS2103JAN2018-F14-B4:morph
from
takuyakanbr:add-google-books-api
Mar 10, 2018
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
fe4e92a
Add network component
takuyakanbr c6ebdfb
Add json deserializers
takuyakanbr 67f9ed9
Remove getAuthorSet and getCategorySet from SampleDataUtil
takuyakanbr adfbb6b
Add tests for json deserializers
takuyakanbr a165464
Add tests for GoogleBooksApi
takuyakanbr 99b9655
Add request and result events for obtaining book details
takuyakanbr b884360
Fix issues in network component
takuyakanbr 6ff902f
Fix content type check in GoogleBooksApi
takuyakanbr File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
20 changes: 20 additions & 0 deletions
20
src/main/java/seedu/address/commons/events/network/ApiBookDetailsRequestEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package seedu.address.commons.events.network; | ||
|
||
import seedu.address.commons.events.BaseEvent; | ||
|
||
/** | ||
* Indicates a request to obtain details for a book using the Google Books API. | ||
*/ | ||
public class ApiBookDetailsRequestEvent extends BaseEvent { | ||
|
||
public final String bookId; | ||
|
||
public ApiBookDetailsRequestEvent(String bookId) { | ||
this.bookId = bookId; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "book details for: " + bookId; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/seedu/address/commons/events/network/ApiBookDetailsResultEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package seedu.address.commons.events.network; | ||
|
||
import seedu.address.commons.events.BaseEvent; | ||
import seedu.address.model.book.Book; | ||
|
||
/** | ||
* Represents the results of a search for book details using the Google Books API. | ||
*/ | ||
public class ApiBookDetailsResultEvent extends BaseEvent { | ||
|
||
public final ResultOutcome outcome; | ||
public final Book book; | ||
|
||
public ApiBookDetailsResultEvent(ResultOutcome outcome, Book book) { | ||
this.outcome = outcome; | ||
this.book = book; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
if (outcome == ResultOutcome.FAILURE) { | ||
return "API failure"; | ||
} | ||
return "book: " + book; | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/seedu/address/commons/events/network/ApiSearchRequestEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package seedu.address.commons.events.network; | ||
|
||
import seedu.address.commons.events.BaseEvent; | ||
|
||
/** | ||
* Indicates a request to search for books using the Google Books API. | ||
*/ | ||
public class ApiSearchRequestEvent extends BaseEvent { | ||
|
||
public final String searchParameters; | ||
|
||
public ApiSearchRequestEvent(String searchParameters) { | ||
this.searchParameters = searchParameters; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "searching for: " + searchParameters; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/seedu/address/commons/events/network/ApiSearchResultEvent.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package seedu.address.commons.events.network; | ||
|
||
import seedu.address.commons.events.BaseEvent; | ||
import seedu.address.model.ReadOnlyBookShelf; | ||
|
||
/** | ||
* Represents the results of a search for books using the Google Books API. | ||
*/ | ||
public class ApiSearchResultEvent extends BaseEvent { | ||
|
||
public final ResultOutcome outcome; | ||
public final ReadOnlyBookShelf bookShelf; | ||
|
||
public ApiSearchResultEvent(ResultOutcome outcome, ReadOnlyBookShelf bookShelf) { | ||
this.outcome = outcome; | ||
this.bookShelf = bookShelf; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
if (outcome == ResultOutcome.FAILURE) { | ||
return "API failure"; | ||
} | ||
return "number of books " + bookShelf.getBookList().size(); | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/seedu/address/commons/events/network/ResultOutcome.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package seedu.address.commons.events.network; | ||
|
||
/** | ||
* Represents the type of result outcome of a network request. | ||
*/ | ||
public enum ResultOutcome { | ||
FAILURE, SUCCESS | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package seedu.address.model.util; | ||
|
||
import java.util.HashSet; | ||
import java.util.Set; | ||
|
||
import seedu.address.model.book.Author; | ||
import seedu.address.model.book.Category; | ||
|
||
/** | ||
* Contains utility methods for manipulating book data. | ||
*/ | ||
public class BookDataUtil { | ||
|
||
/** | ||
* Returns an author set containing the list of strings given. | ||
*/ | ||
public static Set<Author> getAuthorSet(String... strings) { | ||
HashSet<Author> authors = new HashSet<>(); | ||
for (String s : strings) { | ||
authors.add(new Author(s)); | ||
} | ||
|
||
return authors; | ||
} | ||
|
||
/** | ||
* Returns a category set containing the list of strings given. | ||
*/ | ||
public static Set<Category> getCategorySet(String... strings) { | ||
HashSet<Category> categories = new HashSet<>(); | ||
for (String s : strings) { | ||
categories.add(new Category(s)); | ||
} | ||
|
||
return categories; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
package seedu.address.network; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.logging.Logger; | ||
|
||
import org.asynchttpclient.AsyncHttpClient; | ||
|
||
import seedu.address.commons.core.LogsCenter; | ||
|
||
/** | ||
* A wrapper around the AsyncHttpClient class from async-http-client. | ||
*/ | ||
public class HttpClient { | ||
|
||
private static final Logger logger = LogsCenter.getLogger(HttpClient.class); | ||
|
||
private final AsyncHttpClient asyncHttpClient; | ||
|
||
public HttpClient(AsyncHttpClient asyncHttpClient) { | ||
this.asyncHttpClient = asyncHttpClient; | ||
} | ||
|
||
/** | ||
* Asynchronously executes a HTTP GET request to the specified url. | ||
*/ | ||
public CompletableFuture<HttpResponse> makeGetRequest(String url) { | ||
return asyncHttpClient | ||
.prepareGet(url) | ||
.execute() | ||
.toCompletableFuture() | ||
.thenApply(HttpResponse::new); | ||
} | ||
|
||
/** | ||
* Stops and closes the underlying AsyncHttpClient. | ||
*/ | ||
public void close() { | ||
try { | ||
if (!asyncHttpClient.isClosed()) { | ||
asyncHttpClient.close(); | ||
} | ||
} catch (IOException e) { | ||
logger.warning("Failed to shut down AsyncHttpClient."); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package seedu.address.network; | ||
|
||
import org.asynchttpclient.Response; | ||
|
||
/** | ||
* A wrapper around the Response class from async-http-client. | ||
*/ | ||
public class HttpResponse { | ||
|
||
private final int statusCode; | ||
private final String contentType; | ||
private final String responseBody; | ||
|
||
public HttpResponse(int statusCode, String contentType, String responseBody) { | ||
this.statusCode = statusCode; | ||
this.contentType = contentType; | ||
this.responseBody = responseBody; | ||
} | ||
|
||
public HttpResponse(Response response) { | ||
this(response.getStatusCode(), response.getContentType(), response.getResponseBody()); | ||
} | ||
|
||
public int getStatusCode() { | ||
return statusCode; | ||
} | ||
|
||
public String getContentType() { | ||
return contentType; | ||
} | ||
|
||
public String getResponseBody() { | ||
return responseBody; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package seedu.address.network; | ||
|
||
/** | ||
* The API of the Network component. | ||
*/ | ||
public interface Network { | ||
|
||
/** | ||
* Stops the Network component. | ||
*/ | ||
void stop(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package seedu.address.network; | ||
|
||
import java.util.logging.Logger; | ||
|
||
import org.asynchttpclient.AsyncHttpClient; | ||
import org.asynchttpclient.Dsl; | ||
|
||
import com.google.common.eventbus.Subscribe; | ||
|
||
import seedu.address.commons.core.ComponentManager; | ||
import seedu.address.commons.core.LogsCenter; | ||
import seedu.address.commons.events.network.ApiBookDetailsRequestEvent; | ||
import seedu.address.commons.events.network.ApiBookDetailsResultEvent; | ||
import seedu.address.commons.events.network.ApiSearchRequestEvent; | ||
import seedu.address.commons.events.network.ApiSearchResultEvent; | ||
import seedu.address.commons.events.network.ResultOutcome; | ||
import seedu.address.commons.util.StringUtil; | ||
import seedu.address.network.api.google.GoogleBooksApi; | ||
|
||
/** | ||
* Provides networking functionality (making API calls). | ||
* | ||
* No API methods are directly exposed on this class. To make an API call, | ||
* raise the corresponding *RequestEvent. To receive the results of the call, | ||
* handle the corresponding *ResultEvent. | ||
*/ | ||
public class NetworkManager extends ComponentManager implements Network { | ||
|
||
private static final Logger logger = LogsCenter.getLogger(NetworkManager.class); | ||
private static final int CONNECTION_TIMEOUT_MILLIS = 1000 * 5; // 5 seconds | ||
private static final int READ_TIMEOUT_MILLIS = 1000 * 5; // 5 seconds | ||
private static final int REQUEST_TIMEOUT_MILLIS = 1000 * 5; // 5 seconds | ||
|
||
private final HttpClient httpClient; | ||
private final GoogleBooksApi googleBooksApi; | ||
|
||
public NetworkManager() { | ||
super(); | ||
AsyncHttpClient asyncHttpClient = Dsl.asyncHttpClient(Dsl.config() | ||
.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS) | ||
.setReadTimeout(READ_TIMEOUT_MILLIS) | ||
.setRequestTimeout(REQUEST_TIMEOUT_MILLIS)); | ||
httpClient = new HttpClient(asyncHttpClient); | ||
googleBooksApi = new GoogleBooksApi(httpClient); | ||
} | ||
|
||
@Override | ||
public void stop() { | ||
httpClient.close(); | ||
} | ||
|
||
@Subscribe | ||
private void handleGoogleApiSearchRequestEvent(ApiSearchRequestEvent event) { | ||
logger.info(LogsCenter.getEventHandlingLogMessage(event)); | ||
googleBooksApi.searchBooks(event.searchParameters) | ||
.thenApply(bookShelf -> { | ||
raise(new ApiSearchResultEvent(ResultOutcome.SUCCESS, bookShelf)); | ||
return bookShelf; | ||
}) | ||
.exceptionally(e -> { | ||
logger.warning("Search request failed: " + StringUtil.getDetails(e)); | ||
raise(new ApiSearchResultEvent(ResultOutcome.FAILURE, null)); | ||
return null; | ||
}); | ||
} | ||
|
||
@Subscribe | ||
private void handleGoogleApiBookDetailsRequestEvent(ApiBookDetailsRequestEvent event) { | ||
logger.info(LogsCenter.getEventHandlingLogMessage(event)); | ||
googleBooksApi.getBookDetails(event.bookId) | ||
.thenApply(book -> { | ||
raise(new ApiBookDetailsResultEvent(ResultOutcome.SUCCESS, book)); | ||
return book; | ||
}) | ||
.exceptionally(e -> { | ||
logger.warning("Book detail request failed: " + StringUtil.getDetails(e)); | ||
raise(new ApiBookDetailsResultEvent(ResultOutcome.FAILURE, null)); | ||
return null; | ||
}); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should mention in method description that it returns empty string if invalid