All Posts in the ‘Software-Development’ Category

How to create a valid SAML 2.0 Assertion with OpenSAML for JAVA

Juli 27th, 2010 | By Christoph in Software-Development | No Comments »

Recently I had to implement SAML 2.0 for a client project for a Single Sign On (SSO) process.
For this purpose our system needed to create a SAML Assertion containing all the information of the user who is currently logging in.

I was using the OpenSAML classes for JAVA.
Initially I had some issues because I couldn’t find good documentation / examples about what how such an Assertion is to be created using OpenSAML.

I had to do lots of googling and trial & error and finally I got it working.
The following sites were useful and led to my solution.
- http://blogs.sun.com/JoachimAndres/entry/creating_a_saml_assertion_with1
- http://www.capcourse.com/Library/OpenSAML/index.html
- http://ekschi.com/technology/2009/09/01/creating-a-saml-assertion-with-opensaml-part-2/

Though I had to make modifications to some of the solutions above.

To save you this pain, I am posting my final example here. The class below is only for demonstration purposes of this blog entry, and I have stripped out lots of other stuff (e.g. error handling, client specific stuff, encryption via EncryptedAssertion). The only purpose is to give you some kind of template and idea how to start.

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
 
import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SAMLObjectBuilder;
import org.opensaml.common.SAMLVersion;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.AttributeValue;
import org.opensaml.saml2.core.AuthnContext;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnStatement;
import org.opensaml.saml2.core.Condition;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.OneTimeUse;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.core.SubjectConfirmation;
import org.opensaml.saml2.core.SubjectConfirmationData;
import org.opensaml.saml2.core.impl.AssertionMarshaller;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObjectBuilder;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.schema.XSString;
import org.opensaml.xml.util.XMLHelper;
import org.w3c.dom.Element;
 
/**
 * This is a demo class which creates a valid SAML 2.0 Assertion.
 */
public class SAMLWriter
{
 
	public static void main(String[] args) {
    	try {
			SAMLInputContainer input = new SAMLInputContainer();
			input.strIssuer = "http://synesty.com";
			input.strNameID = "UserJohnSmith";
			input.strNameQualifier = "My Website";
			input.sessionId = "abcdedf1234567";
 
			Map customAttributes = new HashMap();
			customAttributes.put("FirstName", "John");
			customAttributes.put("LastName", "Smith");
 
			input.attributes = customAttributes;
 
			Assertion assertion = SAMLWriter.buildDefaultAssertion(input);
			AssertionMarshaller marshaller = new AssertionMarshaller();
			Element plaintextElement = marshaller.marshall(assertion);
			String originalAssertionString = XMLHelper.nodeToString(plaintextElement);
 
			System.out.println("Assertion String: " + originalAssertionString);
 
			// TODO: now you can also add encryption....
 
		} catch (MarshallingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
 
	}
 
	private static XMLObjectBuilderFactory builderFactory;
 
	public static XMLObjectBuilderFactory getSAMLBuilder() throws ConfigurationException{
 
		if(builderFactory == null){
			// OpenSAML 2.3
			 DefaultBootstrap.bootstrap();
	         builderFactory = Configuration.getBuilderFactory();
		}
 
		return builderFactory;
	}
 
	/**
	 * Builds a SAML Attribute of type String
	 * @param name
	 * @param value
	 * @param builderFactory
	 * @return
	 * @throws ConfigurationException
	 */
	public static Attribute buildStringAttribute(String name, String value, XMLObjectBuilderFactory builderFactory) throws ConfigurationException
	{
		SAMLObjectBuilder attrBuilder = (SAMLObjectBuilder) getSAMLBuilder().getBuilder(Attribute.DEFAULT_ELEMENT_NAME);
		 Attribute attrFirstName = (Attribute) attrBuilder.buildObject();
		 attrFirstName.setName(name);
 
		 // Set custom Attributes
		 XMLObjectBuilder stringBuilder = getSAMLBuilder().getBuilder(XSString.TYPE_NAME);
		 XSString attrValueFirstName = (XSString) stringBuilder.buildObject(AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
		 attrValueFirstName.setValue(value);
 
		 attrFirstName.getAttributeValues().add(attrValueFirstName);
		return attrFirstName;
	}
 
	/**
	 * Helper method which includes some basic SAML fields which are part of almost every SAML Assertion.
	 *
	 * @param input
	 * @return
	 */
	public static Assertion buildDefaultAssertion(SAMLInputContainer input)
	{
		try
		{
	         // Create the NameIdentifier
	         SAMLObjectBuilder nameIdBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(NameID.DEFAULT_ELEMENT_NAME);
	         NameID nameId = (NameID) nameIdBuilder.buildObject();
	         nameId.setValue(input.getStrNameID());
	         nameId.setNameQualifier(input.getStrNameQualifier());
	         nameId.setFormat(NameID.UNSPECIFIED);
 
	         // Create the SubjectConfirmation
 
	         SAMLObjectBuilder confirmationMethodBuilder = (SAMLObjectBuilder)  SAMLWriter.getSAMLBuilder().getBuilder(SubjectConfirmationData.DEFAULT_ELEMENT_NAME);
	         SubjectConfirmationData confirmationMethod = (SubjectConfirmationData) confirmationMethodBuilder.buildObject();
	         DateTime now = new DateTime();
	         confirmationMethod.setNotBefore(now);
	         confirmationMethod.setNotOnOrAfter(now.plusMinutes(2));
 
	         SAMLObjectBuilder subjectConfirmationBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(SubjectConfirmation.DEFAULT_ELEMENT_NAME);
	         SubjectConfirmation subjectConfirmation = (SubjectConfirmation) subjectConfirmationBuilder.buildObject();
	         subjectConfirmation.setSubjectConfirmationData(confirmationMethod);
 
	         // Create the Subject
	         SAMLObjectBuilder subjectBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(Subject.DEFAULT_ELEMENT_NAME);
	         Subject subject = (Subject) subjectBuilder.buildObject();
 
	         subject.setNameID(nameId);
	         subject.getSubjectConfirmations().add(subjectConfirmation);
 
	         // Create Authentication Statement
	         SAMLObjectBuilder authStatementBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(AuthnStatement.DEFAULT_ELEMENT_NAME);
	         AuthnStatement authnStatement = (AuthnStatement) authStatementBuilder.buildObject();
	         //authnStatement.setSubject(subject);
	         //authnStatement.setAuthenticationMethod(strAuthMethod);
	         DateTime now2 = new DateTime();
	         authnStatement.setAuthnInstant(now2);
	         authnStatement.setSessionIndex(input.getSessionId());
	         authnStatement.setSessionNotOnOrAfter(now2.plus(input.getMaxSessionTimeoutInMinutes()));
 
	         SAMLObjectBuilder authContextBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(AuthnContext.DEFAULT_ELEMENT_NAME);
	         AuthnContext authnContext = (AuthnContext) authContextBuilder.buildObject();
 
	         SAMLObjectBuilder authContextClassRefBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
	         AuthnContextClassRef authnContextClassRef = (AuthnContextClassRef) authContextClassRefBuilder.buildObject();
	         authnContextClassRef.setAuthnContextClassRef("urn:oasis:names:tc:SAML:2.0:ac:classes:Password"); // TODO not sure exactly about this
 
			authnContext.setAuthnContextClassRef(authnContextClassRef);
	        authnStatement.setAuthnContext(authnContext);
 
	        // Builder Attributes
	         SAMLObjectBuilder attrStatementBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(AttributeStatement.DEFAULT_ELEMENT_NAME);
	         AttributeStatement attrStatement = (AttributeStatement) attrStatementBuilder.buildObject();
 
	      // Create the attribute statement
	         Map attributes = input.getAttributes();
	         if(attributes != null){
	        	 Set keySet = attributes.keySet();
	        	 for (String key : keySet)
				{
	        		 Attribute attrFirstName = buildStringAttribute(key, attributes.get(key), getSAMLBuilder());
	        		 attrStatement.getAttributes().add(attrFirstName);
				}
	         }
 
	         // Create the do-not-cache condition
	         SAMLObjectBuilder doNotCacheConditionBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(OneTimeUse.DEFAULT_ELEMENT_NAME);
	         Condition condition = (Condition) doNotCacheConditionBuilder.buildObject();
 
	         SAMLObjectBuilder conditionsBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(Conditions.DEFAULT_ELEMENT_NAME);
	         Conditions conditions = (Conditions) conditionsBuilder.buildObject();
	         conditions.getConditions().add(condition);
 
	         // Create Issuer
	         SAMLObjectBuilder issuerBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(Issuer.DEFAULT_ELEMENT_NAME);
	         Issuer issuer = (Issuer) issuerBuilder.buildObject();
	         issuer.setValue(input.getStrIssuer());
 
	         // Create the assertion
	         SAMLObjectBuilder assertionBuilder = (SAMLObjectBuilder) SAMLWriter.getSAMLBuilder().getBuilder(Assertion.DEFAULT_ELEMENT_NAME);
	         Assertion assertion = (Assertion) assertionBuilder.buildObject();
	         assertion.setIssuer(issuer);
	         assertion.setIssueInstant(now);
	         assertion.setVersion(SAMLVersion.VERSION_20);
 
	         assertion.getAuthnStatements().add(authnStatement);
	         assertion.getAttributeStatements().add(attrStatement);
	         assertion.setConditions(conditions);
 
			return assertion;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
 
	public static class SAMLInputContainer
	{
 
		private String strIssuer;
		private String strNameID;
		private String strNameQualifier;
		private String sessionId;
		private int maxSessionTimeoutInMinutes = 15; // default is 15 minutes
 
		private Map attributes;
 
		/**
		 * Returns the strIssuer.
		 *
		 * @return the strIssuer
		 */
		public String getStrIssuer()
		{
			return strIssuer;
		}
 
		/**
		 * Sets the strIssuer.
		 *
		 * @param strIssuer
		 *            the strIssuer to set
		 */
		public void setStrIssuer(String strIssuer)
		{
			this.strIssuer = strIssuer;
		}
 
		/**
		 * Returns the strNameID.
		 *
		 * @return the strNameID
		 */
		public String getStrNameID()
		{
			return strNameID;
		}
 
		/**
		 * Sets the strNameID.
		 *
		 * @param strNameID
		 *            the strNameID to set
		 */
		public void setStrNameID(String strNameID)
		{
			this.strNameID = strNameID;
		}
 
		/**
		 * Returns the strNameQualifier.
		 *
		 * @return the strNameQualifier
		 */
		public String getStrNameQualifier()
		{
			return strNameQualifier;
		}
 
		/**
		 * Sets the strNameQualifier.
		 *
		 * @param strNameQualifier
		 *            the strNameQualifier to set
		 */
		public void setStrNameQualifier(String strNameQualifier)
		{
			this.strNameQualifier = strNameQualifier;
		}
 
		/**
		 * Sets the attributes.
		 *
		 * @param attributes
		 *            the attributes to set
		 */
		public void setAttributes(Map attributes)
		{
			this.attributes = attributes;
		}
 
		/**
		 * Returns the attributes.
		 *
		 * @return the attributes
		 */
		public Map getAttributes()
		{
			return attributes;
		}
 
		/**
		 * Sets the sessionId.
		 * @param sessionId the sessionId to set
		 */
		public void setSessionId(String sessionId)
		{
			this.sessionId = sessionId;
		}
 
		/**
		 * Returns the sessionId.
		 * @return the sessionId
		 */
		public String getSessionId()
		{
			return sessionId;
		}
 
		/**
		 * Sets the maxSessionTimeoutInMinutes.
		 * @param maxSessionTimeoutInMinutes the maxSessionTimeoutInMinutes to set
		 */
		public void setMaxSessionTimeoutInMinutes(int maxSessionTimeoutInMinutes)
		{
			this.maxSessionTimeoutInMinutes = maxSessionTimeoutInMinutes;
		}
 
		/**
		 * Returns the maxSessionTimeoutInMinutes.
		 * @return the maxSessionTimeoutInMinutes
		 */
		public int getMaxSessionTimeoutInMinutes()
		{
			return maxSessionTimeoutInMinutes;
		}
 
	}
 
}

HTML Snippet: IE specific CSS classes for body tag

Juli 20th, 2010 | By Christoph in Software-Development | No Comments »

A colleque just showed me today how you can give the body tag a specific CSS class depending on the versions of Internet Explorer. With this you can avoid special css files for IE specific styling and handle it inside a single CSS file.
A colleque just showed me today how you can give the body tag a specific CSS class depending on the versions of Internet Explorer. With this you can avoid special css files for IE specific styling and handle it inside a single CSS file.

My Notes taken at Berlin Buzzwords

Juni 30th, 2010 | By Christoph in Software-Development | No Comments »

BerlinBuzzwords

http://berlinbuzzwords.de

Keynote – Grant Ingersoll – Lucid Imagination about Lucene

  • @gsingers
  • grant@lucidimagination.com
  • http://www.manning.com/ingersoll
  • SolrCloud == ZooKeeper + Solr
  • http://wiki.apache.org/solr/SolrCloud
  • http://en.wikipedia.org/wiki/Sentiment_analysis
  • Map/Reduce Ready recommenders available
  • Identify Topics
  • Latent Dirichlet Allocation ==> http://de.wikipedia.org/wiki/Latent_Dirichlet_Allocation
  • Frequent Pattern Mining
  • Clustering
  • K-Means, Dirichlet, Canopy, etc
  • Carrot^2 Document and Search Result Clustering => http://project.carrot2.org/
  • Eigent Cuts (spectral Clustering) => http://www.google.de/search?hl=de&q=eigen+cuts+clustering&aq=f&aqi=&aql=&oq=&gs_rfai=
  • http://cwiki.apache.org/MAHOUT/algorithms.html
  • Location Aware Search results
  • Query Parsing
  • Filtering
  • Boosting
  • Sorting
  • Singular Value Decomposition (SVD) => http://en.wikipedia.org/wiki/Singular_value_decomposition
  • technique for reducing the dimensionaltity of large matrices while retaining the core features of the larger space
  • Latent Semantic Analysis uses SVD to provide search over the reduced space => http://github.com/algoriffic/lsa4solr
  • Named Entity Recognition => http://en.wikipedia.org/wiki/Named_entity_recognition
    *
  • Finite-State Queries in Lucene http://lingpipe-blog.com/2010/03/25/finite-state-queries-in-lucene/

Lucene Forecast – Version, Unicode, Flex, Modules by Simon Willnauer

  • switched to Kino 10

Making Software for Humans: CouchDB

  • Jan Lehnardt
  • a one-size-fits-all solution for scaling out is not really possible at all @janl #berlinbuzzwords

“Text and Metadata extraction with Apache Tika

  • http://tika.apache.org/
  • switched to Riak Talk

METACARTA GEOSEARCH TOOLKIT FOR SOLR

  • http://berlinbuzzwords.de/content/metacarta-geosearch-toolkit-solr

LEARNING LESSONS: BUILDING A CMS ON TOP OF NOSQL TECHNOLOGIES

  • http://berlinbuzzwords.de/content/learning-lessons-building-cms-top-nosql-technologies
  • best talk so far

Elastic Search

  • http://berlinbuzzwords.de/content/elasticsearch-you-know-search
  • distributed
  • completly HTTP based
  • range queries possible
  • json based
  • lucene based
  • filters: faster than queries (cachable)
  • Near Realtime Search available
    *

    NeoJ – Peter Neubauer

  • Nodes
  • Relationsships between nodes
  • properties on Nodes and props
  • Traversal Framework
  • Lucene integrated (indexing done on commit)
  • http://www.google.de/search?hl=de&q=rdf+reasoning&aq=f&aqi=&aql=&oq=&gs_rfai=

Riak Search

  • http://berlinbuzzwords.de/content/basho-search
  • different query type patterns – keybased
  • Consistent Hashing and Partitions
  • Optimizations (to avoid “Obama Problem = Hotspots in the ring e.g. many documents containing the word Obama all going to the same node”)
  • Bloom Filters & Caching
  • Batching to sae query-time & index-time bandwith
    *

Day2

Keynote

  • ZeroMQ – 0MQ – http://www.zeromq.org/
  • http://www.zeromq.org/blog:multithreading-magic
  • “the fewest possible moving pieces” -> no service discovery.
  • No Broker

Hypertable – http://berlinbuzzwords.de/content/hypertable-ultimate-scaling-machine

  • used by Baidu search engine
  • Dynamo – used by Amazon for Shopping Cart (uses Read-Repair and Consistent Hashing)
  • during periods of failure there can be latency spikes, because of single machine handling the ranges / machines
  • LSM – Log Structured Merge Tre
  • eleminates random I/O => holding a log tree strucutre in memory which will be written to disk asynchronously (compaction)
  • uses Bloom Filters => helps to avoid disk seeks by running every key through bloom filter to determine in which file the k/v is in
  • Dynamic Memeory Adjustment based on Workload
  • Hypertable vs. HBase
  • 70% faster than hBase (seq. write / seq. read)
  • one of the reasons: Dynamic Memory Adjustment
  • You can run Map/Reduce (Hadoop) and it is Data Locality Aware
  • Query types: timestamp ranges, versions of the cell possible, but mainly primary key access
  • No delete operation currenlty (but each column family has a TTL)

HDFS Deep Dive

  • http://berlinbuzzwords.de/content/hdfs-deep-dive
  • one name node, multiple data nodes
  • use 0.20.2-append branch
  • NameNode SPOF in theory, but not in practise

Cassandra Talk – Eric Evans

  • http://www.slideshare.net/jericevans/cassandra-explained
  • Vectorclocks => http://en.wikipedia.org/wiki/Vector_clock

Massivly Parallel Analytics beyond Map/Reduce

  • Context: StratoSphere Project

Colaborative Filtering Mahout – Frank Scholten

  • is a machine learning lib for java
  • run on hadoop
  • Similarity Algorithms
  • TanimotoCoefficintSimilarity
  • LoglikelihoodSimilarity

Sqoop Database import/export for hadoop

  • wish every speaker would have had logically structured their talks as Aaron Kimball did with his Hadoop talks

Hive

  • parser/optimizer/compiler that translates HiveQL into MapReduce code
  • metastore that stores “schema” information (e.g. table name, column names, data types)
  • schema on read, not write
  • unbedingt anschauen!!!
  • WHERE => map
  • GROUP BY/ORDER BY => reduce
  • JOIN => map or reduce depending on optimizer
  • there is an HiveQL EXPLAIN command
  • python lernen

I’m going to Berlin Buzzwords

Mai 21st, 2010 | By Christoph in Software-Development | No Comments »

On June 7th and 8th, I am going to Berlin to attend the Berlin Buzzwords conference.

This is what they write about themselves:

Berlin Buzzwords 2010 is a conference for developers and users of open source software projects, focussing on the issues of scalable search, data-analysis in the cloud and NoSQL-databases. Berlin Buzzwords presents more than 30 talks and presentations of international speakers specific to the three tags “search”, “store” and “scale”.

I'm going to Berlin Buzzwords - the conference on searching, processing and storing data.

“real time” still hasn’t made it into corporate IT

Mai 10th, 2010 | By Christoph in Software-Development | No Comments »

today, when I requested a password reset for my account (I forgot the password)

oh you want this to work immediately ???…:) sorry [name removed] you have to wait 45 min for the account to propogate through the network….not my fault there….just the way things work here at [name removed] …:)
and sorry I can’t make it work any faster just the way the network is setup

this proves that “real time” still hasn’t made it into corporate IT….

Eclipse PDE Build: Unable to find plugin XYZ

April 22nd, 2010 | By Christoph in Software-Development | No Comments »

Today I had the problem that suddenly my headless Eclipse PDE Build process wasn’t working anymore as soon as I added a new Bundle project to my feature.xml.

[java] /Applications/eclipse_3.5RC3/plugins/org.eclipse.pde.build_3.5.0.v20090527-1800/scripts/genericTargets.xml:106: Unable to find plug-in: bundlexyz

I first thought there is something wrong with the plugins MANIFEST.MF, but everything was ok.
It turned out that the new project I have created was in the wrong folder.

All my other bundle projects are inside a folder locally under /development/repo/myproject/plugins/bundle123 there is also my main ant build.xml.
and my Eclipse is under /development/workspace/ and
links to the repo folder.
Now, when I had created my new bundle project (which PDE Build complains about now) by accident I had forgotton to change the the location. I should have unchecked the checkbox “Use default location” put the new plugin into /development/repo/myproject/plugins/bundlexyz instead of under my workspace folder.

Solution:
1. Right click on your project and choose “Refactor > Move”
2. Choose the folder  /development/repo/myproject/plugins/bundle

After that change PDE Build stoppped complaining.

Remember: When using headless PDE Build, you have to put new plugins into the same location as all your other plugins. In Eclipse UI it will work, but in headless mode on the command line it will not work.

Rails-like configuration of different environments in JAVA – YAML instead of properties file

April 21st, 2010 | By Christoph in Software-Development | No Comments »

This article shows a simple code example how you can replace a standard JAVA properties file (.ini) with a more flexible .yml (YAML) file using the JYAML library.
I used this to store configuration parameters for an application for different environments (e.g. development vs. production) in one central file. This is how the RubyOnRails guys are doing this e.g. in the database.yml.

1. See how the usual standard config files look like.

# config.ini file
# Database
dbconnectionurl=jdbc:mysql://localhost:3306/mydb
dbuser=dbuser
dbpass=dbpasswd

As you see it just has key/value pairs. There is also no notion of an “environement” which means I could use a separate file to store information for different environments. But I want everything centralized.

And here the new yaml file:

# config.yml
development:
    # Database
    dbconnectionurl: jdbc:mysql://localhost:3306/mydevelopmentdb
    dbuser: dbuserdevelopment
    dbpass: dbpasswddevelopment

production:
    # Database
    dbconnectionurl: jdbc:mysql://localhost:3306/myproductiondb
    dbuser: dbuserproduction
    dbpass: dbpasswdproduction

As you can see the config.yml contains two sections. The first section is the configuration for the development environment, which is the default per my convention. The second section contains the configuration for the production environment.

2. Now here is the JAVA code which first loads the config.ini file using the standard approach and second loads the config.yml using the JYAML library and puts them into properties as well. Using that approach we almost don’t have to change any application code, because our application still uses a Java Properties object.

public static void main(String[] args) {
 
		/***
		 * 1. Load Properties using traditional approach
		 * from config.ini
		 */
		try {
			Properties props = new Properties();
			props.load(new FileReader(new File("config.ini")));
			System.out.println(props.toString());
 
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
 
		/***
		 * 2. Try to do the same based on
		 */
		try {
			Properties props = new Properties();
 
			HashMap yamlConfig = (HashMap) Yaml.load(new File("config.yml"));
 
			// now check which environment to load (production or development)
			// development is default
			String environment = System.getProperty("MYENVIRONMENT","development");
			HashMap propertiesFromYamlForEnvironment = yamlConfig.get(environment);
			props.putAll(propertiesFromYamlForEnvironment);
			System.out.println(props.toString());
 
		} catch (FileNotFoundException e) {
		} catch (IOException e) {
		}
	}

As you can see the line
String environment = System.getProperty("MYENVIRONMENT","development");
is responsible to read the environment from a system property. you can set this by setting the usual -DMYENVIRONMENT=”production” when you start you java program.

That’s it. Pretty simple but powerful.
You can read more about JYAML in their tutorial.

Initializing Hibernate without XML

April 13th, 2010 | By Christoph in Software-Development | No Comments »

This article just shows a code snippet I have used for initializing Hibernate in pure JAVA code without the hibernate.xml which you would normally use.

public void start(BundleContext context) throws Exception {
      initHibernate(context);
}
 
private void initHibernate(BundleContext context) {
	try {
		final AnnotationConfiguration cfg = new AnnotationConfiguration();
		cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect");
    cfg.setProperty("hibernate.connection.driver_class", "com.mysql.jdbc.Driver");
    cfg.setProperty("hibernate.connection.url", applicationRegistry.getAppProperties().getDbConnectionUrl()); // e.g. "jdbc:mysql://localhost:3306/mydatabase"
    cfg.setProperty("hibernate.connection.username", applicationRegistry.getAppProperties().getDbUser());
    cfg.setProperty("hibernate.connection.password", applicationRegistry.getAppProperties().getDbPassword());
    cfg.setProperty("hibernate.connection.pool_size", "5");
    cfg.setProperty("hibernate.connection.autocommit", "false");
    cfg.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
    //cfg.setProperty("hibernate.hbm2ddl.auto", "create-drop");
    cfg.setProperty("hibernate.show_sql", "true");
    cfg.setProperty("hibernate.format_sql","true");
    cfg.setProperty("hibernate.use_sql_comments","true");
    cfg.setProperty("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
    cfg.setProperty("hibernate.current_session_context_class", "thread");
    cfg.setProperty("org.hibernate.flushMode", "COMMIT");
    cfg.setProperty("hibernate.generate_statistics", "true");
 
    // Hibernate entities
    cfg.addAnnotatedClass(com.myproject.model.entities.Project.class);
    cfg.addAnnotatedClass(com.myproject.model.entities.Customer.class);
		// ... and so on...
 
		sessionFactory = cfg.buildSessionFactory();
 
		org.springframework.orm.hibernate3.HibernateTransactionManager transactionManager = new HibernateTransactionManager(sessionFactory);
		applicationRegistry.setTransactionHelper(new TransactionHelper(transactionManager));
 
	} catch (Exception e) {
		LOGGER.error("Error", e.getMessage(), e);
	}
}

That’s it. I am using this code with Hibernate 3 using Annotations and so far it does what I want and it is not more ugly than the hibernate.xml (although that is in the eye of the observer ;) )

Cassandra Distributed Database – a link list for beginners

April 12th, 2010 | By Christoph in Software-Development | 3 Comments »

I am currently playing around with Apache Cassandra (distributed database) and this article is to store all the links I have used before I close my browser with trillions of open tabs :)

http://wiki.apache.org/cassandra/GettingStarted
http://wiki.apache.org/cassandra/ClientOptions
http://prettyprint.me/2010/02/23/hector-a-java-cassandra-client/

http://wiki.apache.org/cassandra/DataModel

Installing and using Apache Cassandra With Java Part 5 Parts (very good article series!!!)
http://www.sodeso.nl/?p=80
http://www.sodeso.nl/?p=108
http://www.sodeso.nl/?p=207
http://www.sodeso.nl/?p=251
http://www.sodeso.nl/?p=354
Update 2010/04/13: Ronald Mathies commented that he has two new articles. Thanks!
About importing / exporting data from a Cassandra Database: http://www.sodeso.nl/?p=448
Creating custom sorting types for Cassandra: http://www.sodeso.nl/?p=421

WTF is a SuperColumn? An Intro to the Cassandra Data Model

http://stackoverflow.com/questions/1502735/whats-the-best-practice-in-designing-a-cassandra-data-model

https://www.cloudkick.com/blog/2010/mar/02/4_months_with_cassandra/

Building a small Cassandra Cluster for Development and Testing

Cassandra: RandomPartitioner vs OrderPreservingPartitioner

http://about.digg.com/blog/looking-future-cassandra

http://blog.evanweaver.com/articles/2009/07/06/up-and-running-with-cassandra/

http://emmanuelpozo.com/post/317479418/cassandra-messaging-1

Time Series-Data Model

If somebody has some more links on examples and best practices forCassandra data models, then please comment. Thanks.

SVN ignores file extension .so by default – which corrupted my build

März 1st, 2010 | By Christoph in Software-Development | 3 Comments »

I was just working on my currently OSGI project which is build with Eclipse PDE headless for multiple platforms.
The Eclipse Deltapack contains a launcher bundle (directory) called org.eclipse.equinox.launcher.gtk.linux.x86_1.0.200.v20090520 which contains a file called eclipse_1206.so.
This launcher bundle I also committed to my SVN repository for my headless build from the build machine.

I was wondering why my build was always broken and corrupt and I found out that in my SVN repository the eclipse_1206.so file was missing…and indeed it was NOT committed.
I first thought I made a mistake, so I removed and recommitted everything. And again, the eclipse_1206.so wasn’t there.

So I started googling and I found this which directed me to this. Apparently *.so files are igored by SVN by default even though there is no svn:ignore property set.

Solution:
In order to solve this I did the following:

  1. Open the file ~/.subversion/config
  2. Remove the comment from the line which starts with # global-ignores
  3. The line looks like this now: global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store

As you can see the .so file extension is not defined anymore and suddenly .so files also show up in my SVN Commit Dialog (I am using svnX on MaxOSX).

This also explains a bit my most recent issue I was having with a broken Eclipse build.

I am not too sure if this is a good default by SVN to ignore .so files as those are shared objects in Unix Environments which are important for Multi Platform builds in my case. Anyway I found this out and solved the problem.