Wednesday, September 11, 2013

Using JMeter's Regular Expression Extractor

Here's how to use JMeter's Regular Expression Extractor post-processor to extract the response from a HTTP Request sampler and use it in the subsequent request.


In the screen above, I'm extracting the value of the hidden form element named "t".  If there's no match to the regular expression, the default value "NO TOKEN" will be returned.

To use the extracted value in subsequent HTTP requests, just use the usual JMeter parameter notation.  In this case, it's ${TOKEN}; as defined in the Reference Name value.

Thursday, August 15, 2013

Using Drupal's hook_theme() for custom theming

This is a short post on how to use Drupal's hook_theme() to customize a layout within your own custom module.

Start off with implementing the hook_theme() function in your module:

/**
 * Implements hook_theme()
 * @param type $existing
 * @param type $type
 * @param type $theme
 * @param type $path
 * @return array
 */
function mypm_theme($existing, $type, $theme, $path) {
  $themes = array(
    'chat' => array(
      'variables' => array(
        'message' => NULL,
        'author' => NULL,
        'date_posted' => NULL,
        'is_sender' => NULL,
        'product_url' => NULL,
      )
    ),
  );

  return $themes;
}

What I've declared in the function is that I have a custom theme function called "chat". It takes in 5 variables defined in the variables array. As always, remember to clear Drupal's cache once you've defined a new theme function. Now that we have declared our theme function, we'll have to implement it:

function theme_chat($variables) {
  $main_style = 'chat-holder';

  if (isset($variables['is_sender'])) {
    if ($variables['is_sender'] == TRUE) {
      $main_style .= ' chat-holder-sent';
    }
    else {
      $main_style .= ' chat-holder-received';
    }
  }
  else {
    $main_style .= ' chat-holder-received';
  }

  $output = '
'; $output .= '
'; $output .= $variables['author']; $output .= '
'; $output .= '
'; $output .= format_date($variables['date_posted']); $output .= '
'; $output .= '
'; $output .= nl2br(check_plain($variables['message'])); $output .= '
'; $output .= $variables['product_url']; $output .= '
'; return $output; }

The theme_chat function builds the HTML output based on the variables passed in. You can now use this theme function in your form or normal page callback like below:

    $chat_output .= theme('chat',
            array(
                'message' => $chat->message,
                'author' => $chat->author_name,
                'date_posted' => $chat->created,
                'is_sender' => $chat->sender,
                'product_url' => $chat->product_url,
            ));

Wednesday, August 14, 2013

Spring 3 MVC + Hibernate 4 + JdbcTemplate + Partial REST controller (Part 3)

Last part of the article is to use either Hibernate or Spring's JdbcTemplate to retrieve data. The following class is the BaseDao where DataSource and Hibernate SessionFactory are injected and used by concrete DAO classes:

package com.techtots.services.api.dao;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public abstract class BaseDao {

	@Autowired
	protected SessionFactory sessionFactory;
	
	protected DataSource dataSource;

	protected JdbcTemplate jdbcTemplate;
	protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	public DataSource getDataSource() {
		return dataSource;
	}

	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
		this.jdbcTemplate = new JdbcTemplate(this.dataSource);
		this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(this.dataSource);
		
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
		return namedParameterJdbcTemplate;
	}

}

Once we have this out of the way, we can now define a concrete DAO class. We'll have a simple UserDao for testing.

package com.techtots.services.api.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.techtots.services.api.entity.User;
import com.techtots.services.common.vo.UserVo;

@Repository
public class UserDao extends BaseDao {

	public List<User> getList() {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(User.class);
		
		return criteria.list();
	}
	
	public List<UserVo> list() {
		final List<UserVo> list = new ArrayList<UserVo>();
		
		getJdbcTemplate().query("select * from tbl_user", new RowMapper<Object>() {

			@Override
			public Object mapRow(ResultSet rs, int arg1) throws SQLException {
				UserVo vo = new UserVo();
				
				vo.setId(rs.getInt("id"));
				vo.setUsername(rs.getString("nickname"));
				
				list.add(vo);
				
				return null;
			}
			
		});
		
		return list;
	}
}


Since this is just a reference, I've implemented 2 different function to retrieve data. getList() uses Hibernate's SessionFactory while list() uses JdbcTemplate. Following classes are the UserVo and User entity classes which are used by the DAO respectively:

package com.techtots.services.common.vo;

public class UserVo {

	private int id;
	private String username;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

}

package com.techtots.services.api.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tbl_user2")
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", nullable = false)
	private int id;

	@Column(name = "name", nullable = false, length = 200)
	private String name;

	@Column(name = "email", nullable = false, length = 250, unique = true)
	private String email;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}

To call this from your UserController, you'll need to add the @Transactional annotation at either the class or method level. You wouldn't usually add this at the controller level as it's better to have everything wrapped up in a service class.

Spring 3 MVC + Hibernate 4 + JdbcTemplate + Partial REST controller (Part 2)

Second part of the article will focus on the controllers which will process clients' requests as well as other helper classes.

We start off with a custom exception. We add on a HttpStatus code into the exception to return to clients:

package com.techtots.services.api.common.exceptions;

import org.springframework.http.HttpStatus;

public class RestException extends Exception {

 private static final long serialVersionUID = -6373811042517187537L;

 public static final HttpStatus DEFAULT_ERROR_STATUS = HttpStatus.BAD_REQUEST;
 
 private HttpStatus status;
  
 public HttpStatus getStatus() {
  return status;
 }

 public void setStatus(HttpStatus status) {
  this.status = status;
 }

 public RestException() {
  super();
  
  this.status = DEFAULT_ERROR_STATUS;
 }

 public RestException(String message) {
  super(message);
 
  this.status = DEFAULT_ERROR_STATUS;
 }
 
 public RestException(HttpStatus status, String message) {
  super(message);
  
  this.status = status;
 }
}

With Spring 3.2, we can use the @ControllerAdvice annotation to centralize validation and exception handling.

package com.techtots.services.api.common;

import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import com.techtots.services.api.common.exceptions.RestException;

@ControllerAdvice
public class RestResponseExceptionHandler extends ResponseEntityExceptionHandler {

 Logger log = LoggerFactory.getLogger(RestResponseExceptionHandler.class);
 
 @ExceptionHandler(RestException.class)
 protected ResponseEntity handleBadRequest(RestException ex) {

  log.error(ExceptionUtils.getStackTrace(ex));
  
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.TEXT_HTML);
  
  ResponseEntity entity = new ResponseEntity(ex.getMessage(), headers, ex.getStatus()); 
  
  return entity;
 }
}


Finally, a test controller to hook everything up:

package com.techtots.services.api.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.techtots.services.api.common.exceptions.RestException;

@Controller
@RequestMapping("/auth")
public class AuthController extends BaseController {
 @RequestMapping(value = "/test", method = RequestMethod.GET, produces = "application/json")
 @ResponseBody
 public String test() throws Exception {

  return "ok";
 }

 @RequestMapping(value = "/test2", method = RequestMethod.POST, consumes = "application/json", produces = "application/json")
 @ResponseBody
 public void test2() throws Exception {

  throw new RestException("something's missing...");
 }

}

Calling the test method will return a JSON encoded message. While calling the test2 method will throw a HTTP exception with the message "something's missing" with HTTP error code 400 (the default HTTP error code returned in RestResponseExceptionHandler).

Spring 3 MVC + Hibernate 4 + JdbcTemplate + Partial REST controller (Part 1)

This is post serves as a reference point to quickly setup a Java web application with Spring 3 MVC, Hibernate 4, JdbcTemplate and a partial REST controller. We'll be consuming and responding JSON content via the REST controllers.

I'm using Eclipse as the IDE and will be connecting to MySQL database.

Let's start off with the libraries:

  • antlr-2.7.7.jar
  • aopalliance.jar
  • bonecp-0.7.1.RELEASE.jar
  • commons-lang3-3.1.jar
  • commons-logging-1.1.3.jar
  • dom4j-1.6.1.jar
  • guava-14.0.1.jar
  • hibernate-commons-annotations-4.0.2.Final.jar
  • hibernate-core-4.2.4.Final.jar
  • hibernate-jpa-2.0-api-1.0.1.Final.jar
  • jackson-annotations-2.2.0.jar
  • jackson-core-2.2.0.jar
  • jackson-databind-2.2.0.jar
  • javassist-3.15.0-GA.jar
  • jboss-logging-3.1.0.GA.jar
  • jboss-transaction-api_1.1_spec-1.0.1.Final.jar
  • mysql-connector-java-5.1.26-bin.jar
  • slf4j-api-1.7.5.jar
  • slf4j-simple-1.7.5.jar
  • spring-aop-3.2.3.RELEASE.jar
  • spring-beans-3.2.3.RELEASE.jar
  • spring-context-3.2.3.RELEASE.jar
  • spring-core-3.2.3.RELEASE.jar
  • spring-expression-3.2.3.RELEASE.jar
  • spring-jdbc-3.2.3.RELEASE.jar
  • spring-orm-3.2.3.RELEASE.jar
  • spring-tx-3.2.3.RELEASE.jar
  • spring-web-3.2.3.RELEASE.jar
  • spring-webmvc-3.2.3.RELEASE.jar

We'll continue to configure the web app by specifying the web.xml:





  
    contextConfigLocation    /WEB-INF/*ctx.xml  

  
    org.springframework.web.context.ContextLoaderListener
  

  
    api
    org.springframework.web.servlet.DispatcherServlet
    1
  

  
    api
    /api/*
  

  
    /errors/error.jsp
  



Next is to create the application context XML. We'll only have 3 bean definitions in the app-ctx:





 
  
  
  
  
  
  
  
  
  
  
  
  
 

 
  

  
    
      org.hibernate.dialect.MySQL5Dialect
      true
    
  
  
 
 
 
  
 
 



Now for the api-servlet.xml. No bean definition in this file as everything is annotation based.




 

 

 



We also have a single JSP to handle errors in errors/error.jsp. This is as bare as it gets:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




ERROR



<%
out.println(request.getAttribute("javax.servlet.error.message"));
out.println(request.getAttribute("javax.servlet.error.status_code"));

%>



This concludes basic setup for the webapp. Next part will include Java classes for the controller and error handling.

Thursday, August 1, 2013

Two things to get Kohana up and running

Here are 2 things to do right after meeting all requirements dictated by Kohana's install script:


  1. Set Cookie::$salt value in application/bootstrap.php:

    Cookie::$salt = 'my*salt*value*';
    

  2. Change base_url value in application/bootstrap.php to match the server configuration:

    Kohana::init(array(
     'base_url'   => '/my_app/',
    ));
    

    In this example, you should be calling http://myserver.com/my_app/

Wednesday, July 31, 2013

Java Message Format Using Named Placeholder

The Java MessageFormat class allows user to pre-define a string with placeholders and then fill the placeholders with actual strings later to construct a proper message.

It's all fine if you're used to numbered placeholders e.g. {0} and {1}. Since I'm used to Drupal's format_string() function, here's a better alternative. Apache Commons has a StrSubstitutor class which allows use of named placeholders. Instead of using:

String template = "Welcome {0}!  Your last login was {1}";
String output = MessageFormat.format(template1, new Object[] { "gabe", new Date().toString() });

You can now do:

String template = "Welcome ${username}!  Your last login was ${lastlogin}";

Map data = new HashMap();
data.put("username", "gabe");
data.put("lastlogin", new Date().toString());
  
String output2 = StrSubstitutor.replace(template2, data);

Although StrSubstitutor is a bit more verbose, but it helps when you're handling lots of key/value pairs.

Tuesday, July 30, 2013

SQL UNION using Drupal db_select

Here's how to use Drupal's db_select function to perform a SQL UNION like below:

select uid from users where type = 'i'
union
select uid from users_archive where type = 'i'

Bad example, but I can't think of a proper example now :)

Drupal db_select version:

$q1 = db_select('users', 'u')
       ->fields('u', array('uid'))
       ->condition('type', 'i');

$q2 = db_select('users_archive', 'ua')
       ->fields('ua', array('uid'))
       ->condition('type', 'i');

$q1->union($q2);

$results = $q1->execute();

Friday, July 26, 2013

Getting last run SQL from CodeIgniter's DB class

Here's a convenient way to obtain the last executed SQL query when using CodeIgniter's database class.

Code snippet for this example:

$this->db->select('status');
$this->db->from('tbl_user');
$this->db->where('user_id', $user_id);

$results = $this->db->get();

echo $this->db->last_query();

The last call to last_query() will output the actual SQL executed.

Wednesday, July 17, 2013

SQL JOINS using Drupal db_select

Here's how to use Drupal's db_select function to perform a SQL INNER JOIN like below:

SELECT n.*, u.name FROM node n 
INNER JOIN users u on n.uid = u.uid
WHERE u.id = 3

Drupal db_select version:

$q = db_select('node', 'n');
$q->join('users', 'u', 'u.uid = n.uid');

$q->fields('n');
$q->fields('u', array('name'));

$q->condition('u.uid', 3);
  
$results = $q->execute();

Monday, July 15, 2013

Output XLS file to servlet output stream using JExcelAPI

Here's a quick way (although not the best one) to stream an Excel file generated by JExcelAPI (http://jexcelapi.sourceforge.net/). I'm using the servlet output stream in this case.

HttpServletResponse response = getContext().getResponse();

ServletOutputStream sos = response.getOutputStream();

WritableWorkbook workbook = Workbook.createWorkbook(sos);
WritableSheet sheet = workbook.createSheet("Report", 0);
sheet.addCell(new Label(1, 1, "asdfasdfasdf"));

response.setContentType("application/vnd.ms-excel");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setHeader("Content-Disposition", "inline; filename=report-.xls");

workbook.write();
workbook.close();
sos.close();

Monday, July 1, 2013

Formatting Drupal's UNIX timestamp dates

Drupal stores date/time value as int columns in MySQL. Its value is UNIX timestamp based. You will not be able to determine the actual date/time by selecting from the table.

Here's a convenient way to convert the date/time columns directly from SQL:

SELECT cid, data, FROM_UNIXTIME(created) FROM main_cache

You can also use this in the WHERE clause like below:

SELECT COUNT( * ) 
FROM  main_commerce_product 
WHERE FROM_UNIXTIME( created ) 
BETWEEN  '2013-07-17 00:00:00'
AND  '2013-07-17 23:59:59'

Here's the result:


Friday, June 14, 2013

Programmatically parse webform submissions

Here's how to retrieve a webform submission and process its submission values programmatically. We'll need two IDs. First is the webform node id (nid) and the second is the submission id (sid). You can retrieve these IDs from viewing the webform results listing. The URL is something like below:

http://localhost/dt/node/124/submission/18

In this case, 124 is the node id while 18 is the submission id.

Now, on to the code.

$nid = 124;
$sid = 18;

$webform = node_load($nid);
$sub = webform_get_submission($nid, $sid);

// Capture the component IDs for easier array mapping.
foreach ($webform->components as $cid => $cfield) {
  $components[$cfield['form_key']] = $cid;
}

// Retrieve user info
$user_info = new stdClass();
$user_info->username = $sub->data[$components['username']][0];
$user_info->email = $sub->data[$components['e_mail_address']][0];

// And the rest of your processing...

You can use this method to easily reference the fields stored in the row by field name instead of index number.

Tuesday, May 28, 2013

Parsing a Base64 encoded image string in PHP

Here's a quick way to parse a Base64 encoded image file to check if it's a proper image file. First, the PHP code:

$file_encoded = '[very LONG BASE64 STRING]';

$file_decoded = base64_decode($file_encoded);

$info = getimagesizefromstring($file_decoded);

print_r($size);

If the decoded data is a valid image, the getimagesizefromstring() function will return the following info if said string is a proper image:

Array
(
    [0] => 240
    [1] => 464
    [2] => 3
    [3] => width="240" height="464"
    [bits] => 8
    [mime] => image/png
)

Which makes it perfect for image validation. It returns FALSE if it's not able to parse the input as an image.

You'll need to have the GD image library installed to use this function.

Monday, May 27, 2013

SELECT COUNT(*) using Drupal db_select

Here's how to use Drupal's db_select function to perform a SQL equivalent of:

SELECT COUNT(uid) FROM users WHERE name = $username

Sunday, February 24, 2013

JavaOne 2012 videos on YouTube

Here's list of videos from the recent JavaOne 2012 symposium:

http://www.theserverside.com/news/thread.tss?thread_id=72456

Have fun!

Wednesday, February 20, 2013

Configuring Apache and DNS to access site without www prefixawesomehost.com

When hosting a site, it's convenient to just type the domain name e.g. mydomain.com instead of pre-fixing it with www.  This can be easily configured using Apache and by adding one additional entry to the DNS.  For this article's purpose, we'll be using awesomehost.com as the domain.

To start off with, add a new A DNS entry to point to the same IP as the A entry which maps to www.awesomehost.com.  You'll have something like below:

Name Type Value
awesomehost.com A 192.168.0.1
www.awesomehost.com A 192.168.0.1

Once that's done, we configure Apache.  Inside the VirtualHost directive, add the Alias directive as well as the rewrite condition:

<VirtualHost *:80>
ServerName awesomehost.com
ServerAlias www.awesomehost.com

DocumentRoot /home/blah/public_html
        <Directory /home/blah/public_html/>
AllowOverride All
Order allow,deny
allow from all
        </Directory>

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [L,R=301]

</VirtualHost>


The rewrite condition redirects all requests beginning with www to the domain without www prefix.




Tuesday, February 19, 2013

Using MySQL General Query Log

MySQL comes with the feature to log all SQL queries which is sent to the server.  This feature can be enabled dynamically without having to restart the server.  However, only MySQL 5.1 and above supports this.

To enable this feature, login to MySQL as root.  At the MySQL prompt, type this:

mysql> SET GLOBAL log_output = 'TABLE';
Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL general_log = 'ON';
Query OK, 0 rows affected (0.00 sec)

Double check if it's really been turned on:

mysql> select @@global.general_log;
+----------------------+
| @@global.general_log |
+----------------------+
|                    1 |
+----------------------+
1 row in set (0.00 sec)

The value should read '1'.  You can now see all SQL queries logged in the general_log table in the mysql database.  

To turn off the logging, set the general_log to OFF using the same syntax as above.

Tuesday, February 5, 2013

Extracting public key for OpenSSH use from AWS generated keypair

To extract a public key from the AWS generated keypairs for use in OpenSSH, use the following command:

$ ssh-keygen -y -f my-key.pem

That will output the public key in a nice string which can then be inserted into authorized_keys.

APNS and PHP gotcha...

This got me good.  Wondering why your APNS messages aren't delivered?  And there's no error message from your client?  Well now, print out the APS payload after it has been JSON encoded.  A correct message should look like this:

{"aps":{"alert":"Oh really?","badge":1,"sound":"default"},"message_type":"message"}

Compare that to a message which supposedly looks fine but doesn't get sent:

{"aps":{"alert":"Ughieness:nfng","badge":"1","sound":"default"},"message_type":"message"}

See the difference? :)

Yup, the "badge" value.  PHP cast the "badge" value to a string :(  Blogging this so that I don't crack my head in the future.