VOOZH about

URL: http://tugdualgrall.blogspot.com/search/label/java

⇱ Tug's Blog: java


skip to main | skip to sidebar
Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Tuesday, September 3, 2019

Getting Started With Redis Streams & Java

Read this article on my new blog

As you may have seen, I have joined Redis Labs a month ago; one of the first task as a new hire is to learn more about Redis. So I learned, and I am still learning.
This is when I discovered Redis Streams. I am a big fan of streaming-based applications so it is natural that I start with a small blog post explaining how to use Redis Streams and Java.

Posted by Tug Grall at 2:12 AM 0 comments 👁 Image

Labels: java, kafka, redis, streams

Wednesday, January 4, 2017

Getting Started with MQTT and Java



MQTT (MQ Telemetry Transport) is a lightweight publish/subscribe messaging protocol. MQTT is used a lot in the Internet of Things applications, since it has been designed to run on remote locations with system with small footprint.

The MQTT 3.1 is an OASIS standard, and you can find all the information at http://mqtt.org/

This article will guide you into the various steps to run your first MQTT application:

  1. Install and Start a MQTT Broker
  2. Write an application that publishes messages
  3. Write an application that consumes messages

The source code of the sample application is available on GitHub.

Posted by Tug Grall at 4:08 AM 0 comments 👁 Image

Labels: iot, java, mqtt, streaming

Thursday, March 31, 2016

Save MapR Streams messages into MapR DB JSON

In this article you will learn how to create a MapR Streams Consumer that saves all the messages into a MapR-DB JSON Table.

Posted by Tug Grall at 12:06 AM 0 comments 👁 Image

Labels: howto, java, kafka, mapr, streams

Thursday, March 10, 2016

Getting Started with MapR Streams

You can find a new tutorial that explains how to deploy an Apache Kafka application to MapR Streams, the tutorial is available here:

MapR Streams is a new distributed messaging system for streaming event data at scale, and it’s integrated into the MapR converged platform. MapR Streams uses the Apache Kafka API, so if you’re already familiar with Kafka, you’ll find it particularly easy to get started with MapR Streams.

Posted by Tug Grall at 2:18 AM 0 comments 👁 Image

Labels: java, kafka, mapr, streams

Wednesday, February 10, 2016

Getting Started With Sample Programs for Apache Kafka 0.9

Ted Dunning and I have worked on a tutorial that explains how to write your first Kafka application. In this tutorial you will learn how to:

  • Install and start Kafka
  • Create and Run a producer and a consumer

You can find the tutorial on the MapR blog:

Posted by Tug Grall at 2:02 AM 0 comments 👁 Image

Labels: big data, java, kafka

Tuesday, July 21, 2015

Apache Drill : How to Create a New Function?


Apache Drill allows users to explore any type of data using ANSI SQL. This is great, but Drill goes even further than that and allows you to create custom functions to extend the query engine. These custom functions have all the performance of any of the Drill primitive operations, but allowing that performance makes writing these functions a little trickier than you might expect.

In this article, I’ll explain step by step how to create and deploy a new function using a very basic example. Note that you can find lot of information about Drill Custom Functions in the documentation.

Let’s create a new function that allows you to mask some characters in a string, and let’s make it very simple. The new function will allow user to hide x number of characters from the start and replace then by any characters of their choice. This will look like:

1
MASK( 'PASSWORD' , '#' , 4 ) => ####WORD

You can find the full project in the following Github Repository.
As mentioned before, we could imagine many advanced features to this, but my goal is to focus on the steps to write a custom function, not so much on what the function does.


Posted by Tug Grall at 10:04 AM 1 comments 👁 Image

Labels: drill, function, java, sql, udf

Sunday, February 1, 2015

Moving My Beers From Couchbase to MongoDB

See it on my new blog : here

Few days ago I have posted a joke on Twitter
Moving my Java from Couchbase to MongoDB pic.twitter.com/Wnn3pXfMGi
— Tugdual Grall (@tgrall) January 26, 2015

So I decided to move it from a simple picture to a real project. Let’s look at the two phases of this so called project:
  • Moving the data from Couchbase to MongoDB
  • Updating the application code to use MongoDB
Look at this screencast to see it in action:



Posted by Tug Grall at 7:01 AM 2 comments 👁 Image

Labels: couchbase, java, mongodb, nosql

Thursday, July 18, 2013

How to implement Document Versioning with Couchbase

Introduction

Developers are often asking me how to "version" documents with Couchbase 2.0. The short answer is: the clients and server do not expose such feature, but it is quite easy to implement.

In this article I will use a basic approach, and you will be able to extend it depending of your business requirements. 

Design

The first thing to do is to select how to "store/organize" the versions of your document, and for this you have different designs:
  • copy the versions the document into new documents
  • copy the versions of the document into a list of embedded documents
  • store the list of attributes that have been changed into a embedded element (or new documents)
  • store the "delta"
You will have to chose the design based on your application requirements (business logic, size of the dataset, ...).  For this article, let's use one of the most simplistic approach: create new document for each version with the following rules for the keys:
  1. The current version is is a simple Key/Document, no change to the key.
  2. The version is a copy of the document, and the version number is added to the key.
This looks like:
Current Version  mykey
Version 1  mykey::v1
Version 2  mykey::v2
...     ...

With this approach, existing applications will always use the current version of the document, since the key is not changed. But this approach creates new documents that will be indexed by existing views.

For example, in the Beer Sample application, the following view is used to list the beer by name:

function (doc, meta) {
 if(doc.type && doc.type == "beer") {
 emit(doc.name);
 }
}


It is quite simple to "support" versioning without impacting the existing code, except the view itself. The new view needs to emit keys,value only for the current version of the document. This is the new view code:

function (doc, meta) {
 if(doc.type && doc.type == "beer" && (meta.id).indexOf("::v") == -1 ) {
 emit(doc.name);
 }
}

With this change the existing applications that are using this view will continue to work with the same behavior.

Implementing the versioning

Based on this design, when the application needs to version the document, the following logic should happen:
  1. Get the current version of the document
  2. Increment the version number (for example using another key that maintains the version number for each document)
  3. Create the version with the new key  "mykey::v1"
  4. Save the document current version
Let's look at the code in Java

 Object obj = client.get(key);
 if (obj != null) {
 // get the next version, create or use the key: mykey_version
 long version = client.incr(key + "_version", 1, 1); 
 String keyForVersion = key + "::v" + version; // mykey::v1
 try {
 client.set(keyForVersion, obj).get();
 } catch (Exception e) {
 logger.severe("Cannot save version "+ version + " for key "+ key +" - Error:"+ e.getMessage() );
 }
 }
 client.set(key, value);

Quite simple isn't?

The application can access the document using the key, but also get one version or the list of all versions, this is one of the reasons why it is interesting to create a key (mykey_version), and use it also to delete documents and related versions.

Based on the previous comment, the delete operation looks like:

 Object obj = client.get(key);
 // need to delete all the version first
 Object vObject = this.get(key + "_version");
 if (vObject != null) {
 long biggerVersion = Long.parseLong((String) vObject);
 try {
 // delete all the versions
 for (int i = 1; i <= biggerVersion; i++) {
 String versionKey = key + "::v" + i;
 client.delete(versionKey).get();
 }
 // delete the counter
 client.delete(key + "_version").get();
 } catch (InterruptedException e) {
 e.printStackTrace();
 } catch (ExecutionException e) {
 e.printStackTrace();
 }
 }
 client.delete(key);

Use versioning

As an example, I have created a small library available on GitHub https://github.com/tgrall/couchbase-how-to-versioning, this library extends the Couchbase Client and overrides some of the operations : set, replace and delete. (the basic one: no TLL, no durability) As I said before this is just an example.


git clone https://github.com/tgrall/couchbase-how-to-versioning.git
cd how-to-versioning
mvn clean install

Then add this library to your project in addition to Couchbase Java Client, for example in your pom.xml
...
 
 

...



Create a document and version it:

 List

Quick explanation:
  • Line 5: instead of using the CouchbaseClient, the application uses the extended  CouchbaseClientWithVersioning class.
  • Line 7: create a new entry
  • Line 9: create a new version, the boolean value to "true" force the versioning of the document
  • The application use other methods such as get a specific version (line 11), get all versions (line 13), delete a specific version (line 14), and finally delete the key and all versions (line 16).
So using this approach the developer controls explicitly when to create a version, since he has to add the boolean parameter in the set operation. In this small sample library it is also possible to do auto versioning, in this case all set and replace calls will create a version, to achieve that the developer just needs to call the setAutoVersioning(true) method. Something like:

 client = new CouchbaseClientWithVersioning(uris, "default", "");
 client.setAutomaticVersionning(true);

With this approach you can provide versioning to your application with minimal code change. You can test it in the Beer Sample application, just do not forget to change the views as documenter above to only return current version of the documents.

Conclusion

As you can see doing versioning in Couchbase is not that complicated, but it is something that must be done by your application based on its requirements and constraints. You have many different solution and none of these options is perfect for all use cases.

In this specific sample code, I am working with a simple design where I create a copy of the documents for each version. With this approach also, it is interesting to mention that you can version "anything", not only JSON document but also any values.  As I said before, this is one possible approach, and like any design, it has some impact on the application or database, in this case most the database:
  • Increase the number of keys and documents
  • Double - or more- the number of operations, for example when updating a document, the application needs to get the current value, create a version, save the current version.
  • Consistency management when adding new version and incrementing the version number (need to deal with errors when creating a new version, deleting the versions and counter....)
Many features could be added to this easily, for example:
  • Limit to a specific number of version,
  • Enable the versioning only of replace() operation
  • Add specific attribute about versions in JSON document (for example date of the version)
  • ....

If you are using versioning in your Couchbase application feel free to comment or write a small article that describes the way your are doing it.

Posted by Tug Grall at 6:59 AM 0 comments 👁 Image

Labels: couchbase, java, nosql

Wednesday, July 3, 2013

SQL to NoSQL : Copy your data from MySQL to Couchbase


TL;DR: Look at the project on Github.

Introduction

During my last interactions with the Couchbase community, I had the question how can I easily import my data from my current database into Couchbase. And my answer was always the same:
  • Take an ETL such as Talend to do it
  • Just write a small program to copy the data from your RDBMS to Couchbase...
So I have written this small program that allows you to import the content of a RDBMS into Couchbase. This tools could be used as it is, or you can look at the code to adapt it to your application.



The Tool: Couchbase SQL Importer

The Couchbase SQL Importer, available here, allows you with a simple command line to copy all -or part of- your SQL schema into Couchbase. Before explaining how to run this command, let's see how the data are stored into Couchbase when they are imported:
  • Each table row is imported a single JSON document
    • where each table column becomes a JSON attribute
  • Each document as a key made of the name of the table and a counter (increment)
The following concrete example, based on the MySQL World sample database, will help you to understand how it works. This database contains 3 tables : City, Country, CountryLanguage. The City table looks like:
+-------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| CountryCode | char(3) | NO | | | |
| District | char(20) | NO | | | |
| Population | int(11) | NO | | 0 | |
+-------------+----------+------+-----+---------+----------------+

The JSON document that matches this table looks like the following:

city:3805
{ 
 "Name": "San Francisco",
 "District": "California",
 "ID": 3805,
 "Population": 776733,
 "CountryCode": "USA"
}


You see that here I am simply taking all the rows and "moving" them into Couchbase. This is a good first step to play with your dataset into Couchbase, but it is probably not the final model you want to use for your application; most of the time you will have to see when to use embedded documents, list of values, .. into your JSON documents.

In addition to the JSON document the tool create views based on the following logic:
  • a view that list all imported documents with the name of the "table" (aka type) as key
  • a view for each table with the primary key columns
View: all/by_type
{
 "rows": [
 {"key": "city", "value": 4079}, 
 {"key": "country", "value": 239}, 
 {"key": "countrylanguage", "value": 984}
 ]
}

As you can see this view allows you to get with a single Couchbase query the number of document by type. 

Also for each table/document type, a view is created where the key of the index is built from the table primary key. Let's for example query the "City" documents.

View: city/by_pk?reduce=false&limit=5
{
 "total_rows": 4079,
 "rows": [
 {"id": "city:1", "key": 1, "value": null}, 
 {"id": "city:2", "key": 2, "value": null}, 
 {"id": "city:3", "key": 3, "value": null}, 
 {"id": "city:4", "key": 4, "value": null},
 {"id": "city:5", "key": 5, "value": null}
 ]
}

The index key matches the value of the City.ID column.  When the primary key is made of multiple columns the key looks like:

View: CountryLanguage/by_pk?reduce=false&limit=5
{
 "total_rows": 984,
 "rows": [
 {"id": "countrylanguage:1", "key": ["ABW", "Dutch"], "value": null}, 
 {"id": "countrylanguage:2", "key": ["ABW", "English"], "value": null}, 
 {"id": "countrylanguage:3", "key": ["ABW", "Papiamento"], "value": null},
 {"id": "countrylanguage:4", "key": ["ABW", "Spanish"], "value": null},
 {"id": "countrylanguage:5", "key": ["AFG", "Balochi"], "value": null}
 ]
}


This view is built from the CountryLanguage table primary key made of CountryLanguage.CountryCode and CountryLanguage.Language columns.

+-------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| CountryCode | char(3) | NO | PRI | | |
| Language | char(30) | NO | PRI | | |
| IsOfficial | enum('T','F') | NO | | F | |
| Percentage | float(4,1) | NO | | 0.0 | |
+-------------+---------------+------+-----+---------+-------+


How to use Couchbase SQL Importer tool? 

The importer is a simple Java based command line utility, quite simple to use:

1. Download the CouchbaseSqlImporter.jar file from here. This file is contains all the dependencies to work with Couchbase: the Java Couchbase Client, and GSON.

2. Download the JDBC driver for the database you are using as data source. For this example I am using MySQL and I have download the driver for MySQL Site.

3. Configure the import using a properties file.
## SQL Information ##
sql.connection=jdbc:mysql://192.168.99.19:3306/world
sql.username=root
sql.password=password

## Couchbase Information ##
cb.uris=http://localhost:8091/pools
cb.bucket=default
cb.password=

## Import information
import.tables=ALL
import.createViews=true
import.typefield=type
import.fieldcase=lower

This sample properties file contains three sections :

  • The two first sections are used to configure the connections to your SQL database and Couchbase cluster (note that the bucket must be created first)
  • The third section allow you to configure the import itself
    • import.tables : ALL to import all tables, or a the list of tables you want to import, for example City, Country
    • import.createViews : true or false, to force the creation of the views.
    • import.typefield : this is use to add a new attribute in all documents that contains the "type".
    • import.fieldcase : null, lower, upper : this will force the case of the attributes name and the value of the type (City or city or CITY for example).
4. Run the tool !

java -cp "./CouchbaseSqlImporter.jar:./mysql-connector-java-5.1.25-bin.jar" com.couchbase.util.SqlImporter import.properties 

So you run the Java command with the proper classpath (-cp parameter).

And you are done, you can get your data from your SQL database into Couchbase.

If you are interested to see how it is working internally, you can take a look to the next paragraph.

The Code: How it works?


The main class of the tool is really simple  com.couchbase.util.SqlImporter, the process is:

1. Connect to the SQL database

2. Connect to Couchbase

3. Get the list of tables

4. For each tables execute a "select * from table"

  4.1. Analyze the ResultSetMetadata to get the list of columns
  4.2. Create a Java map for each rows where the key is the name of the columns and the value…is the value

  4.3. Serialize this Map into a GSON document and save it into Couchbase

The code is available in the ImportTable(String table) Java method.

One interesting point is that you can use and extend the code to deal with your application.

Conclusion

I have created this tool quickly to help some people in the community, if you are using it and need new features, let me know, using comment or pull request.


Posted by Tug Grall at 10:52 AM 2 comments 👁 Image

Labels: couchbase, java, json, nosql

Wednesday, February 13, 2013

Introduction to Collated Views with Couchbase 2.0


Most of the applications have to deal with "master/detail" type of data:

  • breweries and beer
  • department and employees
  • invoices and items 
  • ...
This is necessary for example to create application view like the following:
With Couchbase, and many of the document oriented databases you have different ways to deal with this, you can:
  • Create a single document for each master and embed all the children in it
  • Create a master and child documents and link them using an attribute.
In the first case when all the information are stored in a single document it is quite easy to use the entire set of data and for example create a screen that shows all the information, but what about the second case?

In this post I am explaining how it is possible to use Couchbase views to deal with that an make it easy to create master/detail views.

As an ex-Oracle employee, I am using the infamous SCOTT schema with the DEPT and EMP tables, as the first example. Then at the end I will extend this to the beer sample data provided with Couchbase.

The Data

Couchbase is a schema-less database, and you can store “anything you want” into it, but for this you need to use JSON documents and create 2 types of document : “department” and “employee”.

The way we usually do that is using a technical attribute to type the document. So the employee and department document will look as follow :

Department
{
 "type": "dept",
 "id": 10,
 "name": "Accounting",
 "city": "New York"
}
Employee
{
 "type": "emp",
 "id": 7782,
 "name": "Blake",
 "job": "Clark",
 "manager": 7839,
 "salary": 2450,
 "dept_id": "dept__10"
}

This shows just the document, in Couchbase you have to associate a document to a key. For this example I am using a simple pattern : type__id , for these documents the keys will look like the following:
  • dept__10
  • emp__20

You can use any pattern to create a key, for example for the employee you could chose to put an email.  

Note the “dept_id” attribute in the employee document. This is the key of the department; you can see that as the “foreign key”. But remember, the relationship between the department and employee documents are managed entirely by the application, Couchbase Server does not enforce it.

I have created a Zip file that contains all the data, you can download it from here; and import the data into Couchbase using the cbdocloader utility. To import the data run the following command from a terminal window:

./cbdocloader -n 127.0.0.1:8091 -u Administrator -p password -b default ~/Downloads/emp-dept.zip 

You can learn more about the cbdocloader tool in the documentation.

The View

Queries inside Couchbase are based on views; and views build indexes, so we have to create a view, a "collated view" to be exact.

The idea behing a collated view is to produce an index where the keys are ordered so that a parent id appears first followed by its children.  So we are generating an index that will look like:

DEPT_10, Accounting
DEPT_10, Blake
DEPT_10, Miller
DEPT_20, Research
DEPT_20, Adams
DEPT_20, Ford
...


This is in fact quite easy to do with Couchbase views. The only trick here is to control the order and be sure the master is always the first one, just before its children.

So to control this we can create an compound key that contains the department id, a "sorting" element and the name (beer or brewery)

So the map function of the view looks like the following:

The key is composed of:
  • the department id extracted from the department document itself or from the employee document depending of the type of document
  • an arbitrary number that is used to control the ordering. I put 0 for the department, 1 for the employee
  • the name of the department or the employee, this also allows to sort the result by name
In addition to the key, this view is used to emit some information about the salary of the employees. The salary is simply the sum of the salary plus the commission when exists. The result of the view looks like:

With this view you can now use the result of the view to build report for your application. It is also possible to use parameters in your query to see only a part of the data, for example by departement, using for example startkey=["dept__20",0]&endkey=["dept__20",2] to view only the data -Department and Employees- of the deparment 20-Research.


The Beer Sample Application

You can create an equivalent view for the beer sample application where you print all the breweries and beers in the same report. The view is called "all_with_beers" in the design document "brewery". The view looks like:


Once you have publish it in production you can use it in the Beer Sample application, for this example I have modified the Java sample application.

Create a servlet to handle user request and on the /all URI.

The "BreweryAndBeerServlet" that calls the view using the following code :


The result of the query is set into the HttpRequest and the all.jsp page is executed. The JSP uses JSTL to print the information using the following code:
The JSP gets the items from the HTTP Request and loops on each items, then based on the type of the item the information is printed. The final result looks like :



This extension to the Beer Sample application is available here : https://github.com/tgrall/beersample-java/tree/BreweriesAndBeers

Posted by Tug Grall at 3:38 AM 0 comments 👁 Image

Labels: couchbase, java, mapreduce, nosql, views

Sunday, December 30, 2012

Couchbase 101: Create views (MapReduce) from your Java application

When you are developing a new applications with Couchbase 2.0, you sometimes need to create view dynamically from your code. For example you may need this when you are installing your application, writing some test, or you can also use that when you are building frameworks, and wants to dynamically create views to query data. This post shows how to do it.

Prerequisites

If you are using Maven you can use the following information in your pom.xml to add the Java Client library:

 
 
 
See online at https://gist.github.com/4337172

Create and Manage Views From Java 

The full Maven project is available on Github.

Connect to Couchbase Cluster

The first thing to do when you want to create a view from Java is obviously to connect to the cluster.

import com.couchbase.client.CouchbaseClient;
...
...

 List

  1. Create a list of URIs to different nodes of the cluster - lines 5-6. (In this example I am working on a single node)
  2. Connect to the bucket, in our case beer-sample -line 9. You can include the password if the bucket is protected ( this is not the case here so I am sending an empty string)
If you are looking for more information about Couchbase and Java, you can read this article from DZone : Hello World with Couchbase and Java.

Let's now talk about Couchbase views. You use views/map-reduce functions to index and query data from Couchbase Server based on the content of the JSON document you store inside Couchbase. For more information about views you can look at the "view basics" chapter of the Couchbase Server Manual.

Create Views from Java

Creating a view from Java is really easy : the Java Client Library contains all the classes and methods to do it. As a concrete use case we will use the Application that is described in the Couchbase Java Tutorial.

When you follow this tutorial, you need to manually create some views, as you can see here. In this example, we will create our map function and directly in our Java code and then store it to Couchbase Server. The tutorial asks you to create the following artifacts:
  • a view named "by_name
  • in the design document named "dev_beer" (development mode)
  • and the map function which looks like the following :
 function (doc, meta) {
 if(doc.type && doc.type == "beer") {
 emit(doc.name, null);
 }
 }


The following code allows you to do it from Java:

import com.couchbase.client.protocol.views.DesignDocument;
import com.couchbase.client.protocol.views.ViewDesign;
...
 DesignDocument designDoc = new DesignDocument("dev_beer");

 String viewName = "by_name";
 String mapFunction =
 "function (doc, meta) {\n" +
 " if(doc.type && doc.type == \"beer\") {\n" +
 " emit(doc.name);\n" +
 " }\n" +
 "}";

 ViewDesign viewDesign = new ViewDesign(viewName,mapFunction);
 designDoc.getViews().add(viewDesign);
 client.createDesignDoc( designDoc );
...


  • Create a design document using the com.couchbase.client.protocol.views.DesignDocument class - line 4.
  • Create a view using com.couchbase.client.protocol.views.ViewDesign class with a name and the map function - line 14.
  • You can add this view to a design document - line 15
  • Finally save the document into the cluster using the CouchbaseClient.createDesignDoc method.
If you need to use a reduce function (built-in or custom) you just need to pass to the ViewDesign constructor as 3rd parameter.

When developing view, from Java or from any other tool/language be sure you understand what are the best practices, and the life cycle of the index. This is why I am inviting you to take a look to the following chapters in the Couchbase documentation:

Using the view

First of all, the view that you just created is in "development mode", and by default the Java client SDK will only access the view when it is in "production mode". This means that when you are calling a view from your application it will search it into the production environment. So before connecting to Couchbase cluster you need to setup the viewmode to development.

This is done using the viewmode environment variable from the Java SDK, that could be set using the following methods:
  • In your code, add this line before the client connects to the cluster : System.setProperty("viewmode", "development");
  • At the command line -Dviewmode=development
  • In a properties file viewmode=development
Once it is done you can call the view using the following code:
import import com.couchbase.client.protocol.views.*;

...
 System.setProperty("viewmode", "development"); // before the connection to Couchbase
...
 View view = client.getView("beer", "by_name");
 Query query = new Query();
 query.setIncludeDocs(true).setLimit(20);
 query.setStale( Stale.FALSE );
 ViewResponse result = client.query(view, query);
 for(ViewRow row : result) {
 row.getDocument(); // deal with the document/data
 }
...

This code queries the view you just created. This means Couchbase Server will generate an index based on your map function, will query the server for results. In this case, we specifically want to set a limit of 20 results and also get the most current results by setting Stale.FALSE.
  • Set the viewmode to development - line 4
  • Get the view using the CouchbaseClient.getView() method -line 6-. As you can see I just use the name beer for the design document (and not dev_beer, Couchbase will know where to search since I am in development mode)
  • Create a query and set a limit (20) and ask the SDK to return the document itself
    setIncludeDocs(true) -line 8- The document will be returned from Couchbase server in the most efficient way
  • Ask the system to update the index before returning the result using query.setStale( Stale.FALSE ); -line 9-. Once again be careful when you use setStale method. Just to be sure here is the documentation about it : Index Updates and the stale Parameter
  • Execute the query - line 10
  • And use the result - lines 11-13

Conclusion

In this article, you have learned:
  • How to create Couchbase views from Java
  • Call this view from Java
  • Configure development/production mode views from Couchbase Java Client Library
This example is limited to the creation of a view, you can take a look to the other methods related to design documents and views if you want to manage your design documents : getDesignDocument(), deleteDesignDocument(), ... .


Posted by Tug Grall at 10:42 AM 12 comments 👁 Image

Labels: couchbase, java, mapreduce, views

Sunday, November 20, 2011

Installing Memcached on Mac OS X and using it in Java


Introduction

In this article I will explain how you can:

  1. Install and Configure Memcached on Mac OS X
  2. Use Memcached in your Java Application

I won't go in too much detail about the benefits of using a distributed cache in your applications, but let's at least provide some use cases for applications that are running in the context of an enterprise portal, eXo Platform in my case - surprising isn't? And I will show this in another post.

We have many reasons to use a cache (distributed or not), in the context of enterprise portal, let's take a look to some of these reasons:

  • A portal is used to aggregate data in a single page. These data could come from different sources : Web Services, Database, ERP, ..... and accessing the data in real time could be costly. So it will be quite interesting to cache the result of the call when possible.
  • If the portal is used to aggregate many data from many sources, it is sometime necessary to jump into another application to continue some operation. A distributed and shared cache could be used to manage some context between different applications running in different processes (JVM or even technologies)
These are two example where a shared cache could be interesting for your portal based applications, we can find many other reason.


Note that the Portlet API (JSR-286) contains already a cache mechanism that cache the HTML fragment, and that eXo Platform also provide a low level cache, based on JBoss Cache.


Installation and Configuration

Installing Memcached from sources

You can find some information about Memcached installation on the Memcached Wiki. The following steps are the steps that I have used on my environment.

As far as I know, Memached is not available as package for Mac OS X. I am still on Snow Leopard (10.6.8), and I have installed XCode and all development tools. I have use the article "Installing memcached 1.4.1 on Mac OS X 10.6 Snow Leopard" from wincent.com. For simplicity reason I have duplicate the content and updated to the latest releases.

1. Create a working directory :

$ mkdir memcachedbuild
$ cd memcachebuild

 2. Install libevent that is mandatory for memcached

$ curl -O http://www.monkey.org/~provos/libevent-1.4.14-stable.tar.gz
$ tar xzvf libevent-1.4.14-stable.tar.gz
$ cd libevent-1.4.14-stable
$ ./configure
$ make
$ make verify
$ sudo make install  

3. Install memcached

Go back to your install directory (memcachedbuild)

$ curl -O http://memcached.googlecode.com/files/memcached-1.4.10.tar.gz
$ tar xzvf memcached-1.4.10.tar.gz
$ cd memcached-1.4.10
$ ./configure
$ make
$ make test
$ sudo make install 
You are now ready to use memcached that is available at /usr/local/bin/memcached

This allows you to avoid changing to the pre-installed memcached located in /usr/bin, if you want to replace it instead of having you own install, just run the configure command with the following parameter:  ./configure --prefix=/usr

Starting and testing Memcached

Start the memcached server, using the following command line:

$ /usr/local/bin/memcached -d -p 11211

This command starts the memcached server as demon (-d parameter), on the TCP port 11211 (this is the default value). You can find more about the memcached command using man memcached.

It is possible to connect and test your server using a telnet connection. Once connected you can set and get object in the cache, take a look to the following paragraph.

$ telnet 127.0.0.1 11211
Trying 127.0.0.1...
Connected to tgrall-server.
Escape character is '^]'.
set KEY 0 600 16
This is my value
STORED
get KEY
VALUE KEY 0 16
This is my value
END

 
The set command allows you to put a new value in the cache using the following syntax:

set <key>  <flags> <expiration_time>  <number_of_bytes> [noreply] \n\n

<value>
  • key : the key used to store the data in the cache
  • flags : a 32 bits unsigned integer that memcached stored with the data
  • expiration_time : expiration time in seconds, if you put 0 this means no delay
  • number_if_bytes : number of bytes in the data block
  • noreply : option to tell the server to not return any value
  • value : the value to store and associate to the key.
This is a short view of the documentation located in your source directory /memcachedbuild/memcached-1.4.10/doc/protocol.txt .


The get command allows you to access the value that is associated with the key.

You can check the version of memcahed you are running by calling the stats command in your telnet session.


Your memcached server is up and running, you can now start to use it inside your applications.


Simple Java Application with Memcached

The easiest way to use memcached from your Java applications is to use a client library. You can find many client libraries. In this example I am using spymemcached developped by the people from Couchbase.

1. Adding SpyMemcached to your Maven project

Add the repository to you pom.xml (or you setting.xml)

<repository>
 <id>spy</id>
 <name>Spy Repository</name>
 <layout>default</layout>
 <url>http://files.couchbase.com/maven2/</url>
</repository> 

then the dependency to your pom.xml

<dependency>
 <groupid>spy</groupid>
 <artifactid>spymemcached</artifactid>
 <version>2.7.3</version>
</dependency>



2. Use SpyMemcache client in your application

The following code is a simple Java class that allows you to enter the key and the value and set it in the cache.


package com.grallandco.blog;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Console;
import java.io.InputStreamReader;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.MemcachedClient;

public class Test {

 public static void main(String[] args) {
 try {
 
 System.out.print("Enter the new key : ");
 BufferedReader reader = new BufferedReader( new InputStreamReader(System.in));
 String key = null;
 key = reader.readLine();
 
 System.out.print("Enter the new value : ");
 String value = null;
 value = reader.readLine();
 
 MemcachedClient cache = new MemcachedClient(AddrUtil.getAddresses("127.0.0.1:11211"));
 
 // read the object from memory
 System.out.println("Get Object before set :"+ cache.get(key) );

 // set a new object 
 cache.set(key, 0, value );

 System.out.println("Get Object after set :"+ cache.get(key) );
 

 } catch (IOException ex) {
 Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
 System.exit(0);
 }

 
 System.exit(0);
 
 }
}



So when executing the application you will see something like :

Enter the new key : CITY
Enter the new value : Paris, France
2011-11-16 15:22:09.928 INFO net.spy.memcached.MemcachedConnection: Added {QA sa=/127.0.0.1:11211, #Rops=0, #Wops=0, #iq=0, topRop=null, topWop=null, toWrite=0, interested=0} to connect queue
2011-11-16 15:22:09.932 INFO net.spy.memcached.MemcachedConnection: Connection state changed for sun.nio.ch.SelectionKeyImpl@5b40c281
Get Object before set :null
Get Object after set :Paris, France

You can also access the object from a Telnet session:
get CITY
VALUE CITY 0 13
Paris, France
END


You can use any Java class in your application, the only thing to do is to make this class serializable.

This is it for the first post about memcached and Java,  I am currently working on a small example integrating Web Services call, Portlets and memcached.

Posted by Tug Grall at 7:12 AM 11 comments 👁 Image

Labels: Apple, cache, java, memcached, OSX

Friday, October 29, 2010

What Apple’s Announcement Really Means to Java Developers

Hey Steve, keep the bean in the Apple!

The news from last week that grabbed the attention of many Java developers was Apple’s announcement of its intentions to deprecate Java in the latest OS X 10.6 update. One sentence stood out in particular, “Developers should not rely on the Apple-supplied Java runtime being present in future versions of Mac OS X,” and raised the question: should Java developers (many of whom, like me, develop on Macs) freak out?

I don’t think so. (Though it prompted additional speculation and follow-on news stories.)

Let’s be realistic. Most applications run on the server side, on Unix/Linux and/or Windows Server – which has nothing to do with Apple or Mac OS X. And more and more applications are running on the cloud, where the language isn’t necessarily irrelevant, but certainly less important than the services that the application exposes. And I’m sure Java will have a big role in ‘development in the cloud,’ as we can already see with Google AppEngine and the VMWare/SpringSource effort.

I think the more interesting question to ask is “Why did Apple do this?”

I believe this is related Apple’s other big news last week: the new “Mac App Store,” which looks like an effort to have one single technology and language to develop “official” applications for Mac. In fact, for all Apple platforms running OS X and iOS, developers should use X Code and Objective C. That’s fine with me, as I enjoy developing small apps for my iPhone and iPad in my spare time, using these tools. But at eXo, many of our developers are using Java, often on Macs, to build our software.

We’re not talking about the same kind of applications. If, in the future, Java does not exist on Macs, it will not cause enterprise developers to abandon Java, but simply force them to move away from their Macs. Personally, I don’t want that to happen. I switched to Mac in 2001, and I’ve been a big fan of all Apple products ever since (most of my extended family are now also on Macs, and they couldn’t care less about Java).

As a Java developer, do I switch back to PC now? Unlikely. I am very confident (overconfident?) that Java will still be present on OS X. The difference is that Apple will simply stop caring about it -- the same way that Microsoft doesn’t care now. I cannot believe that Apple will stop/block Java on their platform. So the future of Java in general, and now on Mac, is fully under the control of the Java community, driven by Oracle and OpenJDK. I am sure we will find many skilled “MacAddicts” to maintain and improve Java on OS X, to at least allow Java developers to run their favorite IDE and test their applications before deploying them on the servers -- keeping the “Write Once, Run Anywhere” a reality (almost...). The only “bad” part is the fact that “Java Desktop” will not borrow any of the cool features of Apple Mac OS X. Not a big deal, since Java Desktop has never been that successful anyway.

So my advice to fellow Java developers is this: if you care, be vocal. Let’s make sure Apple lets the community drive the future of Java on Mac, since the future of the Java platform is still very exciting for many of us.

Original Post on eXo Blog.

Posted by Tug Grall at 11:36 PM 5 comments 👁 Image

Labels: Apple, java

Tuesday, February 17, 2009

JAX-WS: How to configure the service end point at runtime?


When deploying your Web Service client you often need to change the endpoint of the service that  has been set during the code generation. This short post explains how you can set change it at runtime in the client code.

You have two approaches to do that:

  • set the endpoint in the Port using the BindingProvider
  • get the endpoint URL from the WSDL itself at runtime

Use the Binding Provider to set the endpoint URL

The first approach is to change the BindingProvider.ENDPOINT_ADDRESS_PROPERTY property value of the BindingProvider (Port) using the following code:
try { 
           
EmployeeServiceService service = new EmployeeServiceService();
           
EmployeeService port = service.getEmployeeServicePort();

           
BindingProvider bp = (BindingProvider)port;
           
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://server1.grallandco.com:8282/HumanRessources/EmployeeServiceService");

           
Employee emp = port.getEmployee(123);



           
System.out.println("Result = "+ emp);
       
} catch (Exception ex) {...

          

Use the WSDL to get the endpoint URL

Another part is to set the WSDL when you are creating the Service. The service will be using the value that is located in the WSDL port -SOAP Endpoint-. This is simply done using the following code:
try { 
          
EmployeeServiceService service =
          
new org.demo.service.EmployeeServiceService
               
(new URL("http://server1.grallandco.com:8282/HumanRessources/EmployeeServiceService?wsdl"),
               
new QName("http://service.demo.org/","EmployeeServiceService"));

           
EmployeeService port = service.getEmployeeServicePort();

           
Employee emp = port.getEmployee(123);

System.out.println("Result = "+ emp);
       
} catch (Exception ex) {

Note that, in Glassfish, like lot of Web Service environments the WSDL can generate dynamically the Endpoint URL based on the URL used  to get the WSDL. With this approach you can also dynamically change the Soap endpoint. (If compatible with the network configuration of the production environment.)

Posted by Tug Grall at 3:11 PM 11 comments 👁 Image

Labels: java, javaEE, jax-ws, Web Services

Thursday, May 1, 2008

JavaOne 2008: my sessions choice...

I have attended or presented at JavaOne for the last 6 years when I was living in the SF Bay Area... But this year I won't be in San Francisco for JavaOne. As you can guess, I am sad about that... However, I still look at the schedule and events, and here what I would like to do:

  • Groovy/Grails meetup organized by G2One and NFJS
  • Sun and Oracle General Sessions: Tuesday, Wednesday and Friday at 8:30am. I am particularly interested to see the Oracle's one  talk about the Oracle/BEA deal... May be we will be able to learn more about the products roadmap
  • TS-6050 - Comparing JRuby and Groovy
  • TS-5274 - Groovy on a Cloud: Testing Java EE Platform Applications on Amazon EC2
  • BOF-5102 - Cooking Your Own Groovy Builder: A Step Forward into Domain-Specific Languages
  • TS-5793 - Groovy and Grails: Changing the Landscape of Java EE Platform Patterns
  • BOF-5101 - Boosting Your Testing Productivity with Groovy
  • TS-5764 - Grails in Depth
  • TS-6298 - Designing Graphical Model-Driven Applications: Lego MindStorm ... long time that I have not programmed/designed with my Legos...
  • BOF-4888 - Taming the Leopard: Extending OS X the Java Technology Way: would be great to see my ex-coworker talking about OS X and Java.. John and Tim are terrific developers
  • BOF-6400 - The Future of Guice. even if I have not used (yet) this API from Google I have been a big fan of Bob's work
  • TS-5657 - JavaFX Technology: Bring the Web with You--Multiple Interfaces to Games, Chat, and More
  • TS-4817 - The Java Platform Portlet Specification 2.0 (JSR 286)
  • TS-5343 - Enterprise JavaBeans (EJB) 3.1 Technology. As I am pushing more and more customer to use the standard JPA.. would be great to learn more about the next release of EJB
  • TS-6169 - Spring Framework 2.5: New and Notable... would like to see what will be said about SpringAppServer
  • TS-6072 - Advanced Enterprise Debugging Techniques
  • BOF-5634 - Java EE Platform Connector Architecture 1.6 Overview. I have been using J2CA a lot lately when dealing with SOA in large IT department... So quite cool to have an update on this spec.
  • TS-5318 - Dealing with Asynchronicity in Java Technology-Based Web Services. A feature in the WS Stack that I have been pushing a lot...
  • TS-5616 - JSR 303: From a World of Constraints to Constrain the World
  • TS-6339 - Top 10 Patterns for Scaling Out Java Technology-Based Applications
  • TS-5706 - SCA and Java Platform, Enterprise Edition (Java EE Platform): Integration Inside
  • BOF-5495 - Untangling the Asynchronous Web
  • TS-5425 - JAX-RS: The Java API for RESTful Web Services
  • LAB-4500LT - Develop AJAX Based Portlets With OpenPortal and GWT
  • TS-6574 - How to Implement Your Own OpenSocial Container on the Java Platform
  • TS-6807 - What’s New in Ajax
  • BOF-5661 - Comet: The Rise of Highly Interactive Web Sites
  • BOF-4922 - Writing Real-Time Web Applications, Using Google Web Toolkit and Comet
  • TS-5870 - The Best of Both Worlds with Java™ Business Integration and Service Component Architecture
  • TS-5152 - Overview of the JavaFX Script Programming Language
  • TS-5572 - Groovy, the Red Pill: Metaprogramming--How to Blow the Mind of Developers on the Java Platform
  • TS-5815 - Going Mobile with JavaFX Script Technology, Groovy, and Google Android
  • TS-5535 - Tying Java Technologies Together the RESTful Way
I have probably selected many conflicting sessions, not really an issue since I am not going there. That said, this year again JavaOne looks quite exciting and a lot of content again around Scripting Languages and Framework; Web2.0 related technologies and SOA. 
I hope that I will be there for the 2009 one ;)

Friday, January 18, 2008

Infoq news: "Request: Sun, Drop Support for JRuby"

With the latest big news around Oracle-BEA and SUN-MySQL deals I have missed an interesting article on Infoq with the following title:
- Request: Sun, Drop Support for JRuby
I have to say that I do agree with Craig Wickesser asking Sun to Drop Support for JRuby.

Syntax Matters?
Yes syntax matters, not only for the "beauty" of it, but also because of the investment that enterprises have made into it. We should not force people to completely remodel their brain all the time, for no gain. 

I love Groovy language, and one of the main reason is because it gives me the most bang for my buck. Java people can immediately catchup with the syntax, and step by step leverage powerful features available by dynamic languages and domain specific languages. I was hoping to see a great adoption by SUN... It is one thing to support scripting with the JSR-223, but SUN has to "endorse" a scripting, and from what could be seen today it is not Groovy nor Javascript. When we see all the marketing noise it is Ruby with JRuby... And I do not think that is necessary good for the Java platform. 
Do not get me wrong, I think that is a great idea, and need for Java to be able to execute many languages, for example we see a lot of IBM WAS and BEA WL administrator using Python to administer their application server instance with Jython. But once again the "default" one should be close to Java and integrate with it as close as possible to reduce the impact on scalability and performances, and I do think that Groovy did a great job on these topics.

What about RubyOnRails?
I am not a RoR expert, far far away from it, but I have learned it, and developed small applications with it, and I have to say that I love this framework.  And I am sure that like many Java developers that used RoR, I was thinking:  "If only I had the same productivity in my favorite platform: J2EE...".

I was not expecting to run RoR application as-it-is, but more hoping that JavaEE will learn from RoR to simplify development...  And... somebody did it, with Grails. Grails takes inspiration from RoR, but in a "real" JavaEE environment, since it leverages key pieces of the current Java applications such as Hibernate and Spring, using the power of Groovy to glue all this together.

In conclusion...
I do not know for you but yes I do think that SUN should drop support for JRuby, and in place push a language more natural for existing Java Developers, I vote for Groovy. In addition to the language itself, I also expect the JavaEE EG to provide a more productive way of developing "simple" Web applications. This is where I see Grails coming in the picture, but many other framework could do the job, taking advantage of some interesting concepts of RoR...

As Rick says, I (we?) am not looking for a Revolution but for an Evolution.

Posted by Tug Grall at 6:46 AM 3 comments 👁 Image

Labels: groovy, java, javaEE, Rails, Scripting

Tuesday, September 25, 2007

Derek Sivers's blog: 7 reasons I switched back to PHP after 2 years on Rails

The new post on the Ruby section of O'Reilly authored by Derek Sivers is quite interesting, starting with the title:

I am far away of being a PHP expert, or even a Ruby one, but I have the impression that I could post a similar title with Java instead of PHP. If this is true that Java EE could look a little complex for a start -this is probably less true today with the new JavaEE simplifications-. Yes... when you compare Rails and Java alone it is more complex but we should not forget that Java is now more a platform than a simple programming language. And many developers and companies have built very productive solution on this platform.

Since I am talking about Ruby on Rails here, it is important to mention again Grails and Groovy that provide on the Java platform a simple and productive way to develop applications, and time to get back to the different reasons mentioned by Derek in his post:

#1 - “IS THERE ANYTHING RAILS/RUBY CAN DO THAT JAVA CAN’T DO? … (thinking)… NO.”
I believe that we will all agree on the fact that you can do anything you want in Java; Web applications, mobile applications, operating systems, rdbms, ... the only limit is your brain! -and your skills ;) -

#2 - OUR ENTIRE COMPANY’S STUFF WAS IN JAVA: DON’T UNDERESTIMATE INTEGRATION
I think this is one of the key point here. Enterprise is using JavaEE a lot and it is part of the IT, moving to another technology will be expensive even if development is faster. In addition, the developers, administrators are used to develop and manage Java based applications.

And I do not want to talk about how complex it could be when you are building a Rails application on an existing database, designed from a pure Entity/Relation methodology....

#3, #4 #5 - I have nothing special to say here...

#6 - I LOVE SQL
I still see a lot of developers using SQL directly in Java programs. The nice thing about Java is the fact that based on your skills and what you like to do you can choose the way you want to access the database, simple SQL, powerful O-R Mappings, ...

#7 - PROGRAMMING LANGUAGES ARE LIKE GIRLFRIENDS: THE NEW ONE IS BETTER BECAUSE *YOU* ARE BETTER
I love this reason, but nothing special to say, I let you read the original post.

As you can see from the number of comments in Derek's blog -no times to read all of them- this entry generates lot of reactions.

Posted by Tug Grall at 12:20 AM 5 comments 👁 Image

Labels: Grails, groovy, java, javaEE, Rails

Tuesday, August 7, 2007

Java 101: Generate a unique identifier with java.util.UUID

A friend of mine was asking me how to generate a unique ID for his application... As you probably already know Java SE 5 has introduced the java.util.UUID class to easily generate Universally Unique Identifier (UUID). As usual Wikipedia is a great starting point to learn more about UUID.
Generating the unique ID is as simple as calling the method UUID.randomUUID() in the class. This will give a new instance of UUID that you can now manipulate; for example do a toString() to get the UUID string representation as describe in the specifications; for example 5462dc18-4653-42d1-b4e4-22fc970a6ce5

Resources:

Posted by Tug Grall at 2:13 AM 3 comments 👁 Image

Labels: java, javaEE
Subscribe to: Posts (Atom)