Informatics 122 Winter 2013
Project #3: Right in the Middle (Design)
Due dates and times
Thursday, February 14, 5:00pm
This project is to be done individually
Introduction
The web is a vast collection of documents and information, with each piece of information identified by a Uniform Resource Locator (URL). URLs serve multiple purposes:
So URLs serve more than just the basic purpose of providing a link to web content. A particular URL, like http://www.ics.uci.edu/~thornton/inf122/CodeExamples, might serve some of those purposes well but not others. Depending on what you plan to use a URL for, you might design it differently. One rather extreme use of URLs that has developed in recent years is the ability to include them in short messages, such as those posted on Twitter or sent as text messages, where the length of the URL becomes a major factor in its usability. Many URLs are longer than 140 characters, which is the maximum length of conventional text messages or messages posted via Twitter; other URLs are shorter than 140 characters, but still so long that you can't write any meaningful text to accompany them in a short message.
For at least the last ten years, URL shortener services have been available. A URL shortener acts as a middleman in the process of linking to a resource on the web, by allowing a shortened URL such as bit.ly/XqBwx2 to refer to another resource that already has a longer URL such as http://www.ics.uci.edu/~thornton/inf122/CodeExamples/. The URL shortener service redirects all of the shortened URLs to their longer counterparts, while also tracking information about their use (e.g., how many clicks the shortened URL has received, where the shortened URL has been referred from, etc.). Text messaging and Twitter became the "killer app" for URL shorteners, which have exploded in popularity in recent years.
This project asks you to design and implement a small program that uses an API for the bit.ly URL shortener service to generate some popularity metrics. But the implementation is not the sole purpose of the project; this is an exploration of a design for the program, with the implementation used to validate the design and provide the accomplished feeling of having a finished product.
Getting started with bit.ly
Creating an account and having a look around
Your first order of business, if you've never used bit.ly before, is to create yourself a bit.ly account. The account is free and creating it is very straightforward. Go to bit.ly, click the Join Now. It's free! button, and follow the on-screen instructions. You'll need to associate your account with a valid email account but, of course, you can create an email account (e.g., using Gmail) just for the purposes of writing this project if you'd like.
Once you've created your bit.ly account, have a look around bit.ly's Knowledge Base to gain an understanding of what the service does and what kinds of features it offers. Necessarily, whenever you're learning about a new service or library, you will end up needing to find out more about it than you will actually need to know in order to solve your problem; however, this kind of knowledge-building has been endlessly useful for me throughout my career, as I find that I quite often end up needing that knowledge later to solve a new problem (or to suggest a solution to someone else).
bit.ly calls its shortened URLs bitmarks. Try creating a few bitmarks via the web interface. Visit your bitmarks directly, put them on to web pages and click the links, and even share some of them with others, then take a look at what kind of information bit.ly collections and presents you through the web interface.
Using the bit.ly API
Once you've acclimated yourself to bit.ly, it's time to start looking at the bit.ly API. The bit.ly API is described at dev.bitly.com. It is a RESTful API, which essentially means that it is an API you can use by visiting URLs over HTTP connections (i.e., the same way that browsers visit web pages) and downloading the results in one of a few different formats. As a consequence, you can use the API by typing URLs directly into your web browser and visiting them — though some of the API's operations are trickier to visit that way than others, particularly those that are implemented as HTTP POST requests. Similarly, your Java program will be able to use built-in classes in the Java library, such as URL and URLConnection, to make these API calls and receive the results.
Before you can use the bit.ly API, you'll need to register your application with bit.ly, which will provide you credentials that you can use to do authentication. Log into the bit.ly web site and then go to this link to "create an OAuth application." Click the Get Registration Code button; this will send you an email with a registration link. Clicking that registration link will allow you to register your application and will reveal two critical pieces of information needed for your application to be able to authenticate with bit.ly: a client ID and a client secret. Once you've registered your application, make a note of these two pieces of information; you'll need them again later.
Authentication with OAuth
In recent years, web-based APIs have been converging on a single, unified standard for authentication called OAuth. The use of OAuth in the bit.ly API is described here. Note that there is more than one way to do authentication with OAuth, but you'll probably be most interested in using the OAuth Basic Authentication Flow, in which you send the client ID and client secret you registered previously, along with a username and password, and are returned an access token that you can use in subsequent calls to the API.
API rate limits and avoiding running over them
The bit.ly API will only allow you to make a limited number of calls in any given length of time — see this link for more about rate limits. The best approach to avoid running over these limits is to use unit testing and stubs/mocks for the majority of your implementation work, using the actual API only as one small part of your testing effort. This way, you won't find yourself making that many API calls, which will prevent you from ever running over these limits.
A note about libraries that wrap the bit.ly API
While the basic interface to bit.ly is via HTTP (i.e., web) calls, there are what are called client libraries that wrap these calls in easy-to-use classes, methods, and/or functions in a variety of programming languages. These kinds of libraries are, of course, excellent tools for practical projects, because they save you time and energy; later this quarter, we will explore the use of third-party libraries and how to make good choices about them. However, since our goal here is to explore the design of a program that requires the use of external resources, these libraries are strictly off-limits for this project. Don't use them, download them, or look at them when considering your design or doing your implementation.
You can, if you'd like, use the JSON in Java librari if you plan to consume bit.ly results in JSON format; to keep things simple, feel free to add its source code directly to your Git repository, rather than worrying about .jar files. (Parsing JSON, while straightforward, is well beyond the scope of what we're trying to accomplish here.) If you prefer XML, that's fine, too, as the Java library has XML processors built into it.
The problem
For this project, you will design a program that applies some simple popularity metrics to a set of bit.ly links. As in Project #2, the program will have a console-mode user interface, though you're welcome to implement a graphical user interface this time, if you prefer. If you go to the console route, here are the commands you will need to support; if you decide to build a graphical user interface, you would need (at least) equivalent functionality.
The program will provide the ability to do a small handful of tasks with bit.ly:
The console user interface must consist of the following commands:
Command | Description |
LOGIN username password | Sets the username and password to be used when connecting to the bit.ly API. Before these have been set, connections to the bit.ly API should not be alloewd. Note, too, that it is possible to use this command multiple times; any call to the bit.ly API should use the most recent username and password. If the username and password combination is invalid, print Invalid to the console; otherwise, print Welcome. |
LOGOUT | Clears the username and password to be used when connecting to the bit.ly API. Once these are cleared, it is no longer possible to connect to the bit.ly API until another login has been performed. |
BITMARK URL | Asks bit.ly to create a bitmark from a URL. The shortened URL is printed to the console upon success. |
EXPAND shortened_URL | Asks bit.ly to expand a shortened URL. Prints the full URL to the console, if any. |
WATCH shortened_URL | Adds a shortened URL to the watch list, which is a list of shortened URLs for which metrics are to be generated. |
UNWATCH shortened_URL | Removes a shortened URL from the watch list, so that subsequent commands that generate metrics will not include it. |
HOUR | Shows a list of shortened URLs on the watch list and the number of times they've been clicked in the last hour, sorted in descending order by the number of clicks. |
WEEK | Shows a list of shortened URLs on the watch list and the number of times they've been clicked in the last week, sorted in descending order by the number of clicks. |
Basic design goals
In this section of the course, our lectures are heavily focused on implementation-level design concerns: decomposing a problem into classes with single responsibilities, achieving high cohesion and low coupling, finding appropriate uses for design patterns such as those described by the "Gang of Four" in their seminal work on the subject, and how the need for unit testing (and other forms of testing) profoundly affects design. This project — and the subsequent one, which will ask you to implement your design — explores these issues in detail. As you work through your design, and later your implementation, you should keep the following basic design goals in mind; these goals will be on our minds, too, as we grade your work.
Deliverables
Create an object-oriented design for the program, expressed as a UML class diagram. You should assume that the implementation language is Java, so your design should use only features that you would find in Java (e.g., no multiple inheritance) and you should use any Java feature that you feel is appropriate. Your UML class diagram should include the signatures of public methods and constructors, along with the types and names of any private fields and the signatures of any private methods you think you'll need in each class.
Again, as with Project #1, you can use any tool you'd like to draw your UML diagram, but you must submit it to us as a single PDF file.
Accompanying your diagram should be a short document that briefly describes any design patterns that you used in your design and why you thought these design patterns were a good fit.
What and when to submit
Your design is due on Thursday, February 14 at 5:00pm (i.e., the beginning of lecture). Submit the following before lecture:
Follow this link for a discussion of how to submit files via Checkmate. Be aware that we'll be holding you to all of the rules specified in that document, including the one that says that you're responsible for submitting the version of your files that you want graded.
Peer Design Review
The lecture on Thursday, February 14 will be devoted to a peer review of your design from this project, where you will share your design with other students and receive feedback from them about their perceptions of its quality.
The review is somewhat less formal than the last one, in the sense that nothing will need to be written up and submitted ot us. However, everyone is required to participate and we will be tracking who attends and who participates. A couple of ground rules apply here:
As you work on your reviews during the Peer Design Review session, feel free to mark up the copies of the designs that you're reviewing, as well as making notes about the issues you find and the things you discuss. However, this time, give the printed copies of the designs and documentation, along with any notes you've made, back to their original authors before you leave.