Blog Archives

Tungsten Replicator setting up and Gotchas

Tungsten Replicator site Clicky

So we have a big MYSQL server with mission critical data on it.

I want to replicate it accross to another MYSQL database, they are both ubuntu servers with Percona MYSQL database.

1. Preparation

Master – Install RUBY, JAVA,

Slave – Install RUBY, JAVA

edit the hosts files on both machines in etc/hosts and add the other servers in each one and reference the IP address – just makes things easier.

2. SSH

Make sure you set up SSH so that you can ssh from one server to the other WITHOUT using passwords.

3. PORTS

make sure all ports required 10000,10001 are available (particularly problematical PLESK, WEBMIN a whole host of things like these ports) on all machines. One server actually had a PLESK tool on it even though plesk was not installed!!

4. MYSQL

make sure everything is set up and restore a backup of the database before you start.

5. Helper scripts

Set up your tungsten. You’ll need to edit NODES_MASTER_SLAVE.sh to make sure your nodes are correct and USER_CONFIG as per the tungsten documentation.

install.sh – put in the tungsten folder e.g. tungsten-replicator-2.1.0-343

VERBOSE=1 ./cookbook/install_master_slave ./cookbook/NODES_MASTER_SLAVE.sh

tungsten.sh (actually I renamed this to tungsten and did a chmod +x tungsten)

if [ "$1" == "help" ] || [ "$1" == "" ]; then
 echo "Commands"
 ls installs/cookbook/tungsten/tungsten-replicator/bin/
else
installs/cookbook/tungsten/tungsten-replicator/bin/$1 $2 $3 $4 $5
fi

So you can type

./tungsten replicator status

To run commands.

EJB downloading an excel file from JSP

The Calling Page

Let’s say you have a button on a JSP page that calls it. One of the problems is stopping the page opening as blank. So here’s the calling button

<form method="post" action="#">
 <input type="button" value="Download" onClick="return downloadButton();"/>
        </form>
        

The iFRame is used to trigger the excel call, and here’s the download button javascript.

function downloadButton() {
 
    document.getElementById("excel").src="exportxl.jsp?sql=select * from mytable";
    return false;
    
}

The Responding Page

Now the Calling JSP Page that goes off and gets the Excel Spreadsheet from the EJB, I have an EJB called server and the corresponding remote interface “server remote” note that these must be registered in the xml files in the web app so the web app can see the remote interface in the EJB

<%-- 
    Document   : exportxl
    Created on : Aug 1, 2011, 8:36:23 AM
    Author     : paulc
--%>
<%@ page import = "java.sql.*" %>
<%@ page import = "javax.naming.Context" %>
<%@ page import = "javax.naming.InitialContext; "%>
<%@ page import = "PHJ.*" %>
<%@page contentType="application/vnd.ms-excel" pageEncoding="UTF-8"%>
<%

    PHJ.ServerRemote jobManagerBean = null;
    try {
        Context c = new InitialContext();
        jobManagerBean = (PHJ.ServerRemote) c.lookup("java:comp/env/Server");
    } catch (Exception ne) {
        System.out.println("Could not find Job Manager Bean " + ne);
        out.println("Could not find Job Manager Bean");
        return;
    }

    response.setHeader("Content-disposition", "attachment; filename=excelexport.csv");

    String sql = "";
    if (request.getParameter("sql") != null) {
        sql = request.getParameter("sql");

        out.print(jobManagerBean.prepareCSVForExcel(sql));

    } else {
        out.println("Error, No SQL statement specified");

    }
    
    

%>

The EJB

And here’s the routine in the EJB.

 
    private Connection conn;
    private String dbName = "myJNDIRESOURCE"; // make sure you have JNDI resource setup 
    /* This routine gets a connection from the above DBName, however, if it can't find it it lists the available JNDI resourcees
     * to the console or log
     */ 
    private Connection getConnection() {
        if (conn != null) {
            try {
                if (!conn.isClosed()) {
                    return conn;
                }
            } catch (SQLException ex) {
                // Do nothing just carry on.
            }

        }
        InitialContext ic = null;

        Query q = null;

        try {
            // initialize JNDI lookup parameters
            ic = new InitialContext();
            DataSource ds = (DataSource) ic.lookup(dbName);
            conn = ds.getConnection();
        } catch (Exception e) {
            try {
                System.out.println("JNDI Resource " + dbName + " not found " + e);
                NamingEnumeration children = ic.list("");
                while (children.hasMore()) {
                    NameClassPair ncPair = (NameClassPair) children.next();
                    System.out.print(ncPair.getName() + " (type " + ncPair.getClassName() + ")");

                }
                System.out.println("**** CANNOT FIND DATABASE ************************");
                children = ic.list("jdbc");
                while (children.hasMore()) {
                    NameClassPair ncPair = (NameClassPair) children.next();
                    System.out.print(ncPair.getName() + " (type " + ncPair.getClassName() + ")");

                }
                System.out.println("****************************************");
            } catch (Exception f) {
                System.out.println("Error 57:" + f);
            }
            System.out.println("ERROR 52: " + e);
            return null;
        }
        return conn;

    }

    public String prepareCSVForExcel(String sSQL) {

        String sResult = "";
        try {
            conn = getConnection();
            Statement s = conn.createStatement();
            ResultSet r = s.executeQuery(sSQL);
            // feldnames
            for (int i = 1; i != r.getMetaData().getColumnCount(); ++i) {
                sResult = sResult + r.getMetaData().getColumnName(i) + ",";


            }
            sResult = sResult + "\n";

            while (r.next()) {
                for (int i = 1; i != r.getMetaData().getColumnCount(); ++i) {
                    try {
                    if (r.getObject(i) != null) {
                        sResult = sResult + r.getString(i) + ",";
                    } else {
                        sResult = sResult + ",";

                    }
                    } catch (Exception e) {
                        sResult = sResult + ","; // Happens when there is a conversion error to a tiemstamp
                    }


                }
                sResult=sResult+"\n";



            }




        } catch (Exception e) {
            return e + "";
        }
        return sResult;
    }

Android Global Variables.

Those of you familiar with android programming will be used to using intents to pass data from activity to activity but there is a much easier way of storing state information. Using a global variable class.

1. Create a class

public class GlobalVariables extends Application {

    public String sResult = "";
}

This extends the application class.

Then edit your AndroidManifest.xml file

   <application android:name="GlobalVariables" android:theme="@style/CustomTheme" android:label="@string/app_name"
                 android:icon="@drawable/icon"  >

When you want access to one of those juicy globals in your application just use:-

  GlobalVariables gb = ((GlobalVariables) getApplicationContext());
  Log.i("Test Variable is "+gb.sResult);

Simples!

 

Java Server Faces and Google Chrome — Goodbye IE!

When Firefox 3 came out I was hoping it would run JSF faster than IE did, instead it actually failed to run at all well so we just forgot about it and went back to sunny IE for our clients.

Today! I install Google Chrome… Actually I expected JSF not to work at all… let alone how it does.

JSF runs VERY VERY VERY Fast in Google Chrome, sorry, actually, the whole internet runs VERY VERY VERY FAST.

Our tests so far show perfect compatibilty with JSF and it turns the web browser into an application browser, apart from the fact we can perform more customisations of the browser and use it as a real tool for accessing the multiple JSF projects we have.

We can now see bottlenecks without running profiler. The time between the pages loading shows where the problems are. IE really struggled with massive amounts of componants on pages. 

GOOD JOB GOOGLE

If you’ve not tried Google Chrome please please do… hitch it up to your JSF application (or any web app) or your favorite website and just fall off your chair at the MARKED DIFFERENCE in speed. 

I would think once word gets out that people will not want to use IE any longer.

Making an email link in a table with Java Server Faces

Ok, here’s how to do it.

1. Edit the table with the email in it – and set the type of the email field to a HYPERLINK.

2. Create a STATIC TEXT field on the form somewhere, change its ID to txtJAVASCRIPT, turn off the escape property and add a binding attribute to it. We’ll use this to run a bit of javascript to call the email.

3. Add a binding attribute to tablerowgroup1 on your table

4. In the action code for the Hyperlink insert the following code, this will make the javascript basically tell the browser to open the users email programme with the email address in the subject. Obviously you’ll need to change tblcustomersDataProvider1 to your data provider and email to the field in the database corresponding to the persons email address.

public String hyperlink2_action() {
        // Process email
        tblcustomersDataProvider1.setCursorRow(
                tableRowGroup1.getRowKey());
        String sEmail=tblcustomersDataProvider1.getValue("email")+"";
        if (!sEmail.equals("")) {
           
            txtJAVASCRIPT.setText("<script language='javascript'>\nwindow.location=\"mailto:"+sEmail+"\";\n</script>");
           
        } else {
           
            txtJAVASCRIPT.setText("");
        }
        return null;
    }

5. To cancel the email request we add the following into the public void preprocess() code for the jsf page

    txtJAVASCRIPT.setText(""); 

Using this technique you can pretty much make any javascript happen on a page based on an event.

Writing out from a Java Server Faces table to a CSV….

Imagine if you will that you have a Java Server Faces table and you want to write it out to a CSV file.

1. Put The following code in your application bean.

public String OutputFromTableToCSV(
String sFilename,
TableRowGroup tableRowGroup1,
CachedRowSetDataProvider tblzonesDataProvider) {
// Create an ooutput text file
FileOutputStream out; // declare a file output object
PrintStream p; // declare a print stream object

try {
out = new FileOutputStream(sFilename
+".txt");

p=new PrintStream(out);
} catch (Exception e) {
return "Error, could not write to "+sFilename+".txt";
}

String sFields = "";
String sColumnTitle = "";
String sThisFieldName="";
List theseColumns = tableRowGroup1.getChildren();
// Columns
for (int i = 0; i < tableRowGroup1.getColumnCount(); ++i) {
sColumnTitle = sColumnTitle.concat(sColumnTitle);
sColumnTitle = sColumnTitle.concat(",");

// Get the SQL mapped fields
TableColumn thisComponant = (TableColumn) theseColumns.get(i);
try {
sColumnTitle = sColumnTitle.concat(
thisComponant.getHeaderText());
} catch (Exception e) {
}
}
if (!sColumnTitle.equals("")) {
sColumnTitle=sColumnTitle.substring(1); // Chop off initial ,
}
// Write it out
p.println(sColumnTitle);

RowKey[] TheseRows = tblzonesDataProvider.getAllRows();
for (int rowCount = 0; rowCount < TheseRows.length; ++rowCount) {
// Now do the rows
tblzonesDataProvider.setCursorRow(TheseRows[rowCount]);
for (int i = 0; i < tableRowGroup1.getColumnCount(); ++i) {
sFields = sFields.concat(sFields);
sFields = sFields.concat(",");
// Get the SQL mapped fields
TableColumn thisColumn = (TableColumn) theseColumns.get(i);
UIComponent thisChild=(UIComponent) thisColumn.getChildren().get(0);
// ",[#{currentRow.value['ZoneDescription']}]"
try {
sThisFieldName = thisChild.getValueExpression("text").toString();
sThisFieldName = sThisFieldName.substring(
sThisFieldName.indexOf("['") + 2);
sThisFieldName = sThisFieldName.substring(0,
sThisFieldName.indexOf("']"));

} catch (Exception e) {
}

// Add the field to the string to write out

sFields = sFields.concat(
tblzonesDataProvider.getValue(sThisFieldName).toString()
);

}
if (!sFields.equals("")) {
sFields = sFields.substring(1); // Chop off initial ,
}
p.println(sFields);

sFields="";
} // Next Row
// At this point we have to csv strings
// sfields and column title

// Now we have a comma delimited string called sresult in theory

p.close();
return "OK";
}

2. On the form with the JSF page.
a. Add the binding attribute to the tableRowGroup (in the left hand bottom pane).

Create an “Export to CSV file” button and in the event when clicked add this code:-

thefilename – the filename you want to write to
tableRowGroup1 – The table row group from your JSF page table
yourdataprovider – The data provider that feeds the JSF table

getApplicationBean1().OutputFromTableToCSV("thefilename", tableRowGroup1, yourDataProvider);

Popup Windows Javaserver faces.

I wanted to build a popup window that I could use to bring up a print dialog in a web page. It’s no use using the JAVA print dialog because it would appear on the web server.

So:-

FORM WITH DATA —> CLICK PRINT —> Bring up Popup Print Window —> CLOSE WINDOW –> RETURN TO FORM

The Popup JSF page

1. Create the Popup window java server faces page. (just a normal jsf page)
2. Add a Button to the page to close it
3. Add a static text box, rename it to txtJAVASCRIPT, set the escape checkbox to off, add a binding attribute
4. Now, on the Popup I have a close button and the code in the close button simply sets the static text box’s javascript:

public String cmdClOSE_action() {
getSessionBean1().sPrintReportRequest="";
        txtJAVASCRIPT.setText("<script language='javascript'>window.close();</script>");
        txtJAVASCRIPT.setVisible(true); 
        return null;
}

The calling JSF page

1. Create your page that you want to call the popup box.
2. Add the popup code into the JSF for the page calling the popup (I put it into a page fragement that appears on every page):-

<script LANGUAGE="JavaScript">
       
            function popUp(URL) {
            day = new Date();
            id = day.getTime();
            eval("page" + id + " = window.open(URL, '" + id + "',
'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=382,height=286,left = 529,top = 307');");
            }
       
        </script>

Ofcourse you can change the settings as you wish (i.e. popup window size)

3. Making the popup appear.

a. Add a static text box, rename it to txtJAVASCRIPT, set the escape checkbox to off, add a binding attribute (this stores the javascript when i want the box to appear).

b. Add a button to the form you want the popup to appear on, in the button java put :-

  public String cmdPRINT_action() {
      // in this case i am printing a report so i set the session variable to tell the server the popup needs to be displayed
         getSessionBean1().sPrintReportRequest="rptzones";
// now set the txt of the static text box I set up on the same page, note its normally not visible or rendered
// in this case the popup is a jsf page called frmPRINTREPORTS.jsp
         txtJAVASCRIPT.setRendered(true);
         txtJAVASCRIPT.setText("<script language='javascript'>popUp('frmPRINTREPORTS.jsp');</script>" );
        txtJAVASCRIPT.setVisible(true);
       
       
        return null;
    }
 

 

4. Lastly in the form that called the popup I want to stop it from appearing so I have to kill the javascript.

    public void preprocess() {
       
        String sReportRequest=getSessionBean1().sPrintReportRequest;
        if (sReportRequest.equals("")) {
            txtJAVASCRIPT.setVisible(false);
            txtJAVASCRIPT.setText("");
           
        }
       
       
   

Note that the code has to run in the preprocess stage of the page, this simply makes sure that the javascript won’t run when it’s not wanted.

There you go!

Master / Detail Pages with Netbeans 6.1 and Java Server Faces

A lot of times you will want to create a page that has a header and a table that is a child, such as a purchase order where you have a “Purchase order header” and “Purchase Order Lines”

In this case I have a master detail form here as you can see. Now. To make sure the detail form only has the data in from THAT purchase order I insert some code into the init() function of the page.

 try {
            String sSQL="SELECT ALL polines.id, polines.poid, polines.description, polines.qty, polines.price, polines.total  FROM polines WHERE poid=" + cachedRowSetDataProvider1.getValue("id");
            polinesDataProvider.getCachedRowSet().setCommand(sSQL);
            polinesDataProvider.getCachedRowSet().execute();
            polinesDataProvider.refresh();
              } catch (Exception e) {
                  
              }

(polinesDataProvider is the rows of the table, the “detail part” if you like, cachedDataProvider1 is the header)

Now here’s the tricky part. Normally I would do an ADDNEW and just do:-

 RowKey newRow = polinesDataProvider.appendRow();
        polinesDataProvider.setCursorRow(newRow);
        polinesDataProvider.setValue("poid", cachedRowSetDataProvider1.getValue("id"));
        return null;

But I discovered that when you do the “CommitChanges()” command the new row is not saved because there is a WHERE in the command query I set earlier. This is a bug (http://www.netbeans.org/issues/show_bug.cgi?id=139024), in fact the software just ignores the command (I got my MYSQL server to log the queiries and nothing happens).

So the workaround code for the New Item (new detail line) button is:-

        RowKey newRow = polinesDataProvider.appendRow();
        polinesDataProvider.setCursorRow(newRow);
        polinesDataProvider.setValue("poid", cachedRowSetDataProvider1.getValue("id"));
        polinesDataProvider.commitChanges();
        polinesDataProvider.refresh();
        return null;

Note that I set the poid field to the header’s PrimaryKey otherwise it will not look up correctly.

Strangely If you edit a record it works absolutely fine with the default just “commitingchanges” when someone clicks save.