Tuesday, April 30, 2013

Backup/ Restore AWS MySQL RDS

You can back up and restore your AWS MySQL RDS in simple few steps


  1. MySQL should be in the class path
  2. mysqldump -h boundydb.xxxxxxxxxxx.ap-southeast-2.rds.amazonaws.com -u root -p boundydb > dumpdb.sql
  3. mysql -u root -p boundydb < dumpdb.sql


Monday, April 29, 2013

Quartz with Spring 3.2


We can integrated popular scheduler Quarts with Spring 3.2 with Few Steps

1. Write your Java class targating to schedule

@Component
public class BoundryUnlimitedSchedule {
...
public void createReports() {
...............
.......
}
}

2. Configure the spring configuration file 
2.1 Add the scheduler class
       <!-- Quartz Scheduler Configurations -->
  <bean id="boundryUnlimitedSchedule"
    class="com.................BoundryUnlimitedSchedule" />
 
2.2. Add the defined schduler with Quartz
<bean id="methodJobDetailBean"
class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"
p:concurrent="false" p:targetObject-ref="boundryUnlimitedSchedule"
p:targetMethod="createReports" />

2.3 Create the schedule
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean" 
p:jobDetail-ref="methodJobDetailBean" 
p:startDelay="10000" 
p:cronExpression="0 0 8 ? * * *" />

3. More on cron expressions
        seconds | minutes  | hours |  daysOfMonth | months | daysOfWeek | years
 0            0           0          1                       *                ?           *          - 00:00:00 on every month on day 1
 0       10    23 L *          ?           *          - at 11:10 PM on the Last Day of the Month
 0        0     0         1W * ?           *  - first working day of each month at 00:00:00
 0             0          11         ?                       *               3           *          - every 3nd day of the week at 11:00 run this
 0            10          10         ?                       *              *           *          - every day at 10:10 run this

Change Timezone of Amazon EC2 Instance (Linux)



1.logging to EC2 instance remotely

2. Check the time of the ec2 instance date by > date

3. Time zone can be check as 
>cat /etc/sysconfig/clock
ZONE="UTC"
UTC=true

4.Change the time
cp /etc/localtime /etc/localtime.backup
ln -sf /usr/share/zoneinfo/Australia/Sydney /etc/localtime

5.Make the change permanent by adding the following line to the "/etc/sysconfig/clock" file: ZONE="Australia/Sydney"

After this this will show the correct Sydney time.
If you do not do item 5, the system time will reverting back when the EC2 instance restarted

Unit Tests with IN-Memory Database


HSQLDB can be to build framework as a in memory database for unit testing
What to be done
Add following to properties file and this should be loaded to Spring config

# Database properties for library services

datasource.driver.class.name = org.hsqldb.jdbcDriver
datasource.url = jdbc:hsqldb:mem:unittest
datasource.user.name = sa
datasource.user.password = test
hdb.dialect = org.hibernate.dialect.HSQLDialect
hdb.show_sql = true
hdb.hbm2ddl.auto = update

Add following line to Spring configuration

<jdbc:embedded-database id="embedded" type="HSQL" />
<jdbc:initialize-database data-source="dataSource">
    <jdbc:script location="classpath:schema.sql" />
    <jdbc:script location="classpath:data.sql" />
</jdbc:initialize-database>

Add necessary SQL files

schema.sql - SQL to create the tables and its relationships data.sql - Basic data 

Write a JUnit Test class pointing to new Spring config

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:dispatcher-servlet.xml" })
public class BoundryTestClass {
..

}

Tuesday, April 23, 2013

Unit tests for private methods in JAVA


Here is the easy way of testing  private methods in a java class using reflection

public class MyBoundry {
String returnValue ="hello";

private String getBoundryName(String name) {
return returnValue +name;
}

}

public class MyBoundryTest {
  @Test
  public void shouldMyBoundryReturnsExpectedStringValue(){
    Method method =   MyBoundry.class.getDeclaredMethod("getBoundryName", String.class);
    method.setAccessible(true);  
          MyBoundry myBoundry = new MyBoundry();
    assertEquals("helloboundry", method.invoke(myBoundry, "boundry"));
}
}

Thursday, April 18, 2013

Logback Appender for RESTFull


Logback (http://logback.qos.ch/) is the big brother of popular log4j which is getting more support from the development community. 
By default Logback does not support RESTFull access
What needs to be done
  • Implementation of custom log appender to send data to remote server 
public class RestFullLogbackAppender extends AppenderBase<ILoggingEvent> {
    String url;
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    @Override
    protected void append(ILoggingEvent event) {
        sendToTrackingServer(event.getlogMessage());
    }
    private boolean sendToTrackingServer(String logMessage) {
        DefaultHttpClient httpclient = new DefaultHttpClient();
        if (logMessage != null || logMessage.length() > 1) {
            HttpPost request = new HttpPost(url);
            StringEntity params;
            try {
                params = new StringEntity(logMessage);
                request.addHeader("content-type", "application/json");
                request.setEntity(params);
                httpclient.execute(request);
            } catch (UnsupportedEncodingException e) {
            } catch (ClientProtocolException e) {
            } catch (IOException e) {
            }
        }
        return true;
    }
}
  • Implementation of custom log maker 
public class CustomLogMaker extends AbstractMatcherFilter<ILoggingEvent> {
    Marker markerToMatch;   
    public void start() {
        if (this.markerToMatch != null) {
            super.start();
        } else {
            addError(String.format("The marker property must be set for [%s]", getName()));
        }
    }
    public void setMarker(String markerStr) {
        if (markerStr != null) {
            markerToMatch = MarkerFactory.getMarker(markerStr);
        }
    }
    @Override
    public FilterReply decide(ILoggingEvent event) {
        Marker marker = event.getMarker();
        if (!isStarted()) {
            return FilterReply.NEUTRAL;
        }
        if (marker == null) {
            return onMismatch;
        }
        if (markerToMatch.contains(marker)) {
            return onMatch;
        }
        return onMismatch;
    }
}
  • Add following appender to  logback.xml 
<appender name="REMOTE"  class="com.boundry.logback.RestFullLogbackAppender">   
    <filter class="com.boundry.logback.CustomLogMaker">
        <marker>REST_LOGGER</marker>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
    </filter>
    <url>http://localhost:8080/boundry/logging</url>
</appender>
  • Add log maker 
public class RestFullLogMarkers {
   public static final Marker SEND_TO_LOG_SERVER =             MarkerFactory.getMarker("REST_LOGGER");
}
  • Create a Rest with SpringMVC
@RequestMapping(method = RequestMethod.POST, value = { "/logging" })
public @ResponseBody String postLogger(@RequestBody String log,HttpServletRequest request) throws IOException {
String logMessage = log;
//TODO: Write to the server
return "Log Message received at " + new Date();
}
  • How to use the new REST Logger
private static final Logger logger = LoggerFactory.getLogger(MyBoundry.class);

...

log.info(LogMarkers.SEND_TO_LOG_SERVER ,"Hello World");