Sunday, January 31, 2010

Could someone please shutdown zillow.com


Attached snapshot says it all.. With illogical zestimates, this site is not only confusing buyers but also depriving sellers of the fair value. How could a condo in an area where prices have dropped and recently sold for $129K now is zestimated a hopping $300K? I am pretty sure the owner has not replaced its walls with golden bricks.

Friday, January 29, 2010

How to SIP a Coherence soup - Part(I)

A few times a requirement has passed our way to find if Oracle Coherence can be integrated with hand-held devices. Either to get a notification of an Entry or as a task submission unit. The short answer is No and the long answer is Yes. No - because Coherence requires at least a J2SE to be used natively. J2ME platform is not supported. Yes - because there is an architectural pattern called edging. Edging is a pattern of platform integration when a system does not support the protocol of another and we have to create an intermediary system that integrates these two protocols by understanding both. This intermediary system is "edged" or proxied in between. So lets cook this recipe.

Problem Statement: Integrating a cellphone with Coherence.

Ingredients
:

  1. A clean servlet container
  2. Coherence jar
  3. A SIP emulator and,
  4. An IDE as per your taste
For a spicy recipe we have used an Oracle WebLogic Application Server, JDeveloper and Sun's now called Oracle's Java ME Platform SDK.

How to Cook:
  • Download Weblogic Application Server from OTN and install it.
  • Install Java ME Platform SDK from http://java.sun.com, install it and start Java_Platform_ME_SDK under toolbar/bin.
  • While j2me SDK is warming up start JDeveloper and a simple Coherence cluster.
  • If this is the first time you are cooking keep coherence-cache-config pretty simple with a distributed cache "A". If you like a little hotter you can spice the cache configuration up as needed.
  • By now JDeveloper should be boiling. Create a new J2EE project and put the following servlet:

public class SipRequestInitiator extends HttpServlet {

private NamedCache nCache = CacheFactory.getCache("A");
public SipRequestInitiator() {
}
public void init(ServletConfig sc) throws ServletException {
super.init(sc);
}
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
int num = 10;
try {
num = Integer.parseInt(req.getParameter("num"));
} catch (NumberFormatException nExp) {
System.out.println("Wrong number, defaulting to 10");
}
Filter filter =
new LimitFilter(new LikeFilter(new KeyExtractor("toString"),
"news-%", '*', true), num);
Set news = nCache.keySet(filter);
StringBuilder sB = new StringBuilder();
Iterator iter = news.iterator();
while (iter.hasNext()) {
String k = (String)iter.next();
sB.append((nCache.get(k)).toString());
sB.append("\n");
}
res.setContentType("text/plain");
res.setContentLength(sB.toString().intern().length());
res.getWriter().println(sB.toString());
}
}
  • Deploy the servlet with a web.xml. WebLogic plate should be ready now.
  • Once J2ME is hot enough start a MIDP project and cook it with the following Midlet:

public class CohMIDlet extends MIDlet
implements CommandListener, SipServerConnectionListener {

private Display display;
private Form form;
private Command myMessages;
private Command exitCommand; // The exit command
private TextField number;

public CohMIDlet() {
display = Display.getDisplay(this);
form = new Form("Receive Message");
exitCommand = new Command("Exit", Command.EXIT, 0);
myMessages = new Command("Messages", Command.ITEM, 1);
number = new TextField ("No. Of Messages", "10", 3, TextField.LAYOUT_LEFT);
form.append (number);
form.addCommand(exitCommand);
form.addCommand(myMessages);
form.setCommandListener(this);
}

public void startApp() {
display.setCurrent(form);
}

public void pauseApp() {
}

public void destroyApp(boolean unconditional) {
notifyDestroyed();
}

public void commandAction(Command c, Displayable s) {
if (c == myMessages) {
Thread t = new Thread() {
public void run() {
getMessages();
}
};
t.start();
}

if (c == exitCommand) {
destroyApp(true);
}
}

private void getMessages() {
int num = Integer.parseInt(number.getString());
HttpConnection hc = null;
InputStream in = null;
String url = "http://localhost:7001/sipinitiator?&num=" + num;
try {
hc = (HttpConnection) Connector.open(url);
in = hc.openInputStream();

int contentLength = (int) hc.getLength();
byte[] raw = new byte[contentLength];
int length = in.read(raw);

in.close();
hc.close();

// Show the response to the user.
String s = new String(raw, 0, length);
form.append(s);
} catch (IOException ioe) {
form.append(ioe.getMessage());
}
}

public void notifyRequest(SipConnectionNotifier arg0) {
}
}
  • put two entries in cache A with keys as "news-$i", where $i is the article number.
  • Choose a Cellphone type as per your choice. I like the good old style flip-phones. Run the emulator. It will deploy the application. Press the Menu button and select Messages. Do you see the following?

In this part we have prepared the soup and tasted it using a Midlet. In part(II) we will try to find how we can SIP it. Enjoy!

Tuesday, January 26, 2010

Customizing JMX Reporter

JMX Reporter is a Coherence utility that generates statistical logs about nodes, networks, memory, proxy and cache usage. If enabled (-Dtangosol.coherence.management.report.autostart=true) by default every minute it prints these statistical logs and every hour creates a new set of files. What if we need to customize it?

  1. Easiest is to unzip coherence.jar and extract reports directory. This is what we would customize by putting in the classpath before coherence.jar
  2. Edit report-group.xml to change the frequency and the location where these reports should be created.
  3. Configure the <report-list> to have a list of <report-config> for the reports we want to have. The report-config takes a location of where the configuration of a specific type is defined.
  4. Copy the report configurations in the directory as defined in the report-group.xml
Following is a sample of report-group.xml under reports/ directory that prints memory status and network health reports at a frequency of 10mins:
<report-group>
<frequency>10m<</frequency>
<output-directory>../StatisticalReports</output-directory>
<report-list>
<report-config>
<location>reports/report-memory-status.xml</location>
</report-config>
<report-config>
<location>reports/report-network-health.xml</location>
</report-config>
</report-list>
</report-group>
reports/report-memory-status.xml and reports/report-network-health.xml has a list of respective attributes to be reported. Each report-config sets the file-name and the delimiter typically set as {date}-<stat-name>.txt and {tab} respectively. The report generated are CSV files that can be opened in MS Excel or Openoffice and historically analyzed. What if at the end of the day you want to open in Excel and analyze it? Following is a simple shell script that concatenates the reports appropriately (by removing repeated headers) and names it aggregate-<report-type>.xls:
#!/bin/bash
p=0;
k=`ls *$1.txt 2>/dev/null | wc -l`
if [[ $k == 0 ]]
then echo "Valid types are: ";
echo -e "\tmemory-status";
echo -e "\tnetwork-health";
exit;
else
for i in `ls --sort time -r *$1.txt`
do
if [[ $p == 0 ]]
then
cat $i >> aggregate-$1.xls;
p=1;
else
sed '1d' $i | cat >> aggregate-$1.xls
fi
done
dos2unix aggregate-$1.xls
fi
Enjoy!

Thursday, January 14, 2010

Drive to Pikes Peak

Sunday, January 10, 2010

Monday, January 04, 2010

An Island from above