/*
* RUBiS
* Copyright (C) 2002, 2003, 2004 French National Institute For Research In Computer
* Science And Control (INRIA).
* Contact: jmob@objectweb.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or any later
* version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
* Initial developer(s): Emmanuel Cecchet, Julie Marguerite
* Contributor(s):
*/
package edu.rice.rubis.client;
import java.io.File;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.lang.Thread;
import java.lang.reflect.Array;
import java.net.URL;
import java.util.Random;
/**
* This program initializes the RUBiS database according to the rubis.properties file
* found in the classpath.
*
* @author <a href="mailto:cecchet@rice.edu">Emmanuel Cecchet</a> and <a href="mailto:julie.marguerite@inrialpes.fr">Julie Marguerite</a>
* @version 1.0
*/
public class InitDB
{
private URLGenerator urlGen = null;
private Random rand = new Random();
private RUBiSProperties rubis = null;
private int[] itemsPerCategory;
/**
* Creates a new <code>InitDB</code> instance.
*
*/
public InitDB()
{
rubis = new RUBiSProperties();
urlGen = rubis.checkPropertiesFileAndGetURLGenerator();
if (urlGen == null)
Runtime.getRuntime().exit(1);
itemsPerCategory = rubis.getItemsPerCategory();
}
/**
* Main program accepts any combination of the following arguments: <pre>
* all: generate the complete database
* users: generate only users
* items: generate only items
* bids: generate bids and items (it is not possible to create bids without creating the related items)
* comments: generate comments and items (it is not possible to create comments without creating the related items)
*
* @param args all|users|items|bids|comments
*/
public static void main(String[] args)
{
System.out.println("RUBiS database initialization - (C) Rice University/INRIA 2001\n");
InitDB initDB = new InitDB();
int argc = Array.getLength(args);
String params = "";
if (argc == 0)
{
System.out.println("Command line : java -classpath .:./database edu.rice.rubis.client.InitDB parameters");
System.out.println("Using Makefile: make initDB PARAM=\"parameters\"");
System.out.println("where parameter is one or any combination of the following arguments:");
System.out.println(" all: generate the complete database");
System.out.println(" users: generate only users");
System.out.println(" items: generate only items");
System.out.println(" bids: generate bids and items (it is not possible to create bids without creating the related items)");
System.out.println(" comments: generate comments and items (it is not possible to create comments without creating the related items)");
Runtime.getRuntime().exit(1);
}
for (int i = 0 ; i < argc ; i++)
params = params +" "+ args[i];
if ((params.indexOf("users") != -1) || (params.indexOf("all") != -1))
initDB.generateUsers();
if ((params.indexOf("items") != -1) || (params.indexOf("bids") != -1) ||
(params.indexOf("comments") != -1) || (params.indexOf("all") != -1))
initDB.generateItems((params.indexOf("bids") != -1) || (params.indexOf("all") != -1), (params.indexOf("comments") != -1) || (params.indexOf("all") != -1));
}
/**
* This method add users to the database according to the parameters
* given in the database.properties file.
*/
public void generateUsers()
{
String firstname;
String lastname;
String nickname;
String email;
String password;
String regionName;
String HTTPreply;
int i;
URL url;
// Cache variables
int getNbOfUsers = rubis.getNbOfUsers();
int getNbOfRegions = rubis.getNbOfRegions();
System.out.print("Generating "+getNbOfUsers+" users ");
for (i = 0 ; i < getNbOfUsers ; i++)
{
firstname = "Great"+(i+1);
lastname = "User"+(i+1);
nickname = "user"+(i+1);
email = firstname+"."+lastname+"@rubis.com";
password = "password"+(i+1);
regionName = (String)rubis.getRegions().elementAt(i % getNbOfRegions);
// Call the HTTP server to register this user
url = urlGen.registerUser(firstname, lastname, nickname, email, password, regionName);
HTTPreply = callHTTPServer(url);
if (HTTPreply.indexOf("ERROR") != -1)
{
System.err.println("Failed to add user "+firstname+"|"+lastname+"|"+nickname+"|"+email+"|"+password+"|"+regionName);
System.err.println(HTTPreply);
}
if (i % 100 == 0)
System.out.print(".");
}
System.out.println(" Done!");
}
/**
* This method add items to the database according to the parameters
* given in the database.properties file.
*/
public void generateItems(boolean generateBids, boolean generateComments)
{
// Items specific variables
String name;
String description;
float initialPrice;
float reservePrice;
float buyNow;
int duration;
int quantity;
int categoryId;
int sellerId;
int oldItems = rubis.getNbOfOldItems();
int activeItems = rubis.getTotalActiveItems();
int totalItems = oldItems + activeItems;
String staticDescription = "This incredible item is exactly what you need !<br>It has a lot of very nice features including "+
"a coffee option.<p>It comes with a free license for the free RUBiS software, that's really cool. But RUBiS even if it "+
"is free, is <B>(C) Rice University/INRIA 2001</B>. It is really hard to write an interesting generic description for "+
"automatically generated items, but who will really read this ?<p>You can also check some cool software available on "+
"http://sci-serv.inrialpes.fr. There is a very cool DSM system called SciFS for SCI clusters, but you will need some "+
"SCI adapters to be able to run it ! Else you can still try CART, the amazing 'Cluster Administration and Reservation "+
"Tool'. All those software are open source, so don't hesitate ! If you have a SCI Cluster you can also try the Whoops! "+
"clustered web server. Actually Whoops! stands for something ! Yes, it is a Web cache with tcp Handoff, On the fly "+
"cOmpression, parallel Pull-based lru for Sci clusters !! Ok, that was a lot of fun but now it is starting to be quite late "+
"and I'll have to go to bed very soon, so I think if you need more information, just go on <h1>http://sci-serv.inrialpes.fr</h1> "+
"or you can even try http://www.cs.rice.edu and try to find where Emmanuel Cecchet or Julie Marguerite are and you will "+
"maybe get fresh news about all that !!<p>";
// Comments specific variables
int staticDescriptionLength = staticDescription.length();
String[] staticComment = { "This is a very bad comment. Stay away from this seller !!<p>",
"This is a comment below average. I don't recommend this user !!<p>",
"This is a neutral comment. It is neither a good or a bad seller !!<p>",
"This is a comment above average. You can trust this seller even if it is not the best deal !!<p>",
"This is an excellent comment. You can make really great deals with this seller !!<p>" };
int[] staticCommentLength = { staticComment[0].length(), staticComment[1].length(), staticComment[2].length(),
staticComment[3].length(), staticComment[4].length()};
int[] ratingValue = { -5, -3, 0, 3, 5 };
int rating;
String comment;
// Bids specific variables
int nbBids;
// All purpose variables
int i, j;
URL url;
String HTTPreply;
// Cache variables
int getItemDescriptionLength = rubis.getItemDescriptionLength();
float getPercentReservePrice = rubis.getPercentReservePrice();
float getPercentBuyNow = rubis.getPercentBuyNow();
float getPercentUniqueItems = rubis.getPercentUniqueItems();
int getMaxItemQty = rubis.getMaxItemQty();
int getCommentMaxLength = rubis.getCommentMaxLength();
int getNbOfCategories = rubis.getNbOfCategories();
int getNbOfUsers = rubis.getNbOfUsers();
int getMaxBidsPerItem = rubis.getMaxBidsPerItem();
System.out.println("Generating "+oldItems+" old items and "+activeItems+" active items.");
if (generateBids)
System.out.println("Generating up to "+getMaxBidsPerItem+" bids per item.");
if (generateComments)
System.out.println("Generating 1 comment per item");
for (i = 0 ; i < totalItems ; i++)
{
// Generate the item
name = "RUBiS automatically generated item #"+(i+1);
int descriptionLength = rand.nextInt(getItemDescriptionLength)+1;
description = "asd";
// while (staticDescriptionLength < descriptionLength)
// {
// description = description+staticDescription;
// descriptionLength -= staticDescriptionLength;
// }
// description += staticDescription.substring(0, descriptionLength);
initialPrice = rand.nextInt(5000)+1;
duration = rand.nextInt(7)+1;
if (i < oldItems)
{ // This is an old item
duration = -duration; // give a negative auction duration so that auction will be over
if (i < getPercentReservePrice*oldItems/100)
reservePrice = rand.nextInt(1000)+initialPrice;
else
reservePrice = 0;
if (i < getPercentBuyNow*oldItems/100)
buyNow = rand.nextInt(1000)+initialPrice+reservePrice;
else
buyNow = 0;
if (i < getPercentUniqueItems*oldItems/100)
quantity = 1;
else
quantity = rand.nextInt(getMaxItemQty)+1;
}
else
{
if (i < getPercentReservePrice*activeItems/100)
reservePrice = rand.nextInt(1000)+initialPrice;
else
reservePrice = 0;
if (i < getPercentBuyNow*activeItems/100)
buyNow = rand.nextInt(1000)+initialPrice+reservePrice;
else
buyNow = 0;
if (i < getPercentUniqueItems*activeItems/100)
quantity = 1;
else
quantity = rand.nextInt(getMaxItemQty)+1;
}
categoryId = i % getNbOfCategories;
// Hopefully everything is ok and we will not have a deadlock here
while (itemsPerCategory[categoryId] == 0)
categoryId = (categoryId + 1) % getNbOfCategories;
if (i >= oldItems)
itemsPerCategory[categoryId]--;
sellerId = rand.nextInt(getNbOfUsers) + 1;
// Call the HTTP server to register this item
url = urlGen.registerItem(name, description, initialPrice, reservePrice, buyNow, duration, quantity, sellerId, categoryId+1);
HTTPreply = callHTTPServer(url);
if (HTTPreply.indexOf("ERROR") != -1)
{
System.err.println("Failed to add item "+name+" ("+url+")");
System.err.println(HTTPreply);
}
if (generateBids)
{ // Now deal with the bids
nbBids = rand.nextInt(getMaxBidsPerItem);
for (j = 0 ; j < nbBids ; j++)
{
int addBid = rand.nextInt(10)+1;
url = urlGen.storeBid(i+1, rand.nextInt(getNbOfUsers)+1, initialPrice, initialPrice+addBid, initialPrice+addBid*2, rand.nextInt(quantity)+1, quantity);
HTTPreply = callHTTPServer(url);
if (HTTPreply.indexOf("ERROR") != -1)
{
System.err.println("Failed to bid #"+j+" on item "+name+" ("+url+")");
System.err.println(HTTPreply);
}
initialPrice += addBid; // We use initialPrice as minimum bid
}
}
if (generateComments)
{ // Generate the comment
rating = rand.nextInt(5);
int commentLength = rand.nextInt(getCommentMaxLength)+1;
comment = "";
while (staticCommentLength[rating] < commentLength)
{
comment = comment+staticComment[rating];
commentLength -= staticCommentLength[rating];
}
comment += staticComment[rating].substring(0, commentLength);
// Call the HTTP server to store this comment
url = urlGen.storeComment(i+1, sellerId, rand.nextInt(getNbOfUsers)+1, ratingValue[rating], comment);
HTTPreply = callHTTPServer(url);
if (HTTPreply.indexOf("ERROR") != -1)
{
System.err.println("Failed to add comment for item #"+(i+1)+" ("+url+")");
System.err.println(HTTPreply);
}
}
if (i % 10 == 0)
System.out.print(".");
}
System.out.println(" Done!");
}
/**
* Call the HTTP Server according to the given URL and get the reply
*
* @param url URL to access
* @return <code>String</code> containing the web server reply (HTML file)
*/
private String callHTTPServer(URL url)
{
String HTMLReply = "";
BufferedInputStream in = null;
int retry = 0;
while (retry < 5)
{
// Open the connexion
try
{
in = new BufferedInputStream(url.openStream(), 4096);
}
catch (IOException ioe)
{
System.err.println("Unable to open URL "+url+" ("+ioe.getMessage()+")");
retry++;
try
{
Thread.currentThread().sleep(1000L);
}
catch (InterruptedException i)
{
System.err.println("Interrupted in callHTTPServer()");
return null;
}
continue;
}
// Get the data
try
{
byte[] buffer = new byte[4096];
int read;
while ((read = in.read(buffer, 0, buffer.length)) != -1)
{
if (read > 0)
HTMLReply = HTMLReply + new String(buffer, 0, read);
}
}
catch (IOException ioe)
{
System.err.println("Unable to read from URL "+url+" ("+ioe.getMessage()+")");
return null;
}
// No retry at this point
break;
}
try
{
if (in != null)
in.close();
}
catch (IOException ioe)
{
System.err.println("Unable to close URL "+url+" ("+ioe.getMessage()+")");
}
return HTMLReply;
}
}