<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0"><channel><title>A Developer's Scrappad »  – A Developer’s ScrapPad</title> <link>http://www.developerscrappad.com</link> <description>Articles and Tutorials for Java EE, Oracle, DB2, MySQL and others...</description> <lastBuildDate>Fri, 07 Dec 2012 03:44:30 +0000</lastBuildDate> <language>en-US</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/developerscrappad" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="developerscrappad" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Building and Deploying Java EE EAR with Maven to Java EE Application Server (Part 1) – Project Directory Structure &amp; Module Generation Through archetype:generate</title><link>http://www.developerscrappad.com/1177/java/java-ee/maven/building-and-deploying-java-ee-ear-with-maven-to-java-ee-application-server-part-1-project-directory-structure-amp-module-generation-through-archetype-generate/</link> <comments>http://www.developerscrappad.com/1177/java/java-ee/maven/building-and-deploying-java-ee-ear-with-maven-to-java-ee-application-server-part-1-project-directory-structure-amp-module-generation-through-archetype-generate/#comments</comments> <pubDate>Sat, 01 Dec 2012 13:12:26 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[Maven]]></category> <category><![CDATA[Java EE]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=1177</guid> <description><![CDATA[Maven wasn’t very popular and wide used when it was first released, but after version 2, it had gain lots of traction amount Java developers and it then became widely used as a project build and management tool not only for private projects, but we can also see that there are a tremendously large amount [...]]]></description> <content:encoded><![CDATA[<p>Maven wasn’t very popular and wide used when it was first released, but after version 2, it had gain lots of traction amount Java developers and it then became widely used as a project build and management tool not only for private projects, but we can also see that there are a tremendously large amount of open source projects being managed, maintained and build by Maven.<br /> <span id="more-1177"></span><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/12/156596_5192.jpg?e83a2c" style="display: none;"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/12/156596_5192-150x150.jpg?e83a2c" alt="" title="156596_5192" width="150" height="150" class="alignnone size-thumbnail wp-image-1250" /></a><br /> As popular as it may seem, but unfortunately, it might not be easily learned as certain concepts are definitely foreign (if I may use this word) especially for folks migrating from Apache Ant, because Maven is not only just a build tool, but it is termed as a software project management tool as some may say. Yes, I’ve been through the pain of migration from Ant to Maven…painful to just clear the fog of just understanding what Maven truly is about, had spent lots and lots of hours understanding its concepts and directory structure; getting it to build my Java project properly and let’s not mentioned about getting it deploy (install in Maven’s terminology) SUCCESSFULLY to the targeted Application Server, solving dependency issues and using the right plugin…Phew! That is the very core reason of my motivation to write this article and hopefully it could save someone&#8217;s time that happened to be going through the pain of Maven.</p><p>Let’s not be negative, Maven when done right, is a beauty of its own and there are many advantages to it.</p><h2>Objective &amp; Targeted Readers</h2><p>This series &#8220;Building and Deploying Java EE EAR with Maven to Java EE Application Server&#8221; will be written in parts. I’ll just begin with getting the build directory structure right (only for the Java EE EAR file for now), the next other parts will be about where to place the source codes and the deployment to major Application Servers like Glassfish, JBoss, WebLogic and any other major Application Server in the market that I can find a solution to deploy the EAR through Maven. I’ll try to document as much as short but precise as possible.</p><p>I’m writing this specifically for readers who are struggling with the migration from Ant to Maven. But having said that, this series will not be the introduction of Maven and what is it used for as there are already many documentations and web sites about that. But if you are a Java EE developer, have read and knew what Maven is, had at least seen what’s inside a pom.xml file but no idea how to meddle with it, or had at least explored its commands but having a hard time to just find a workable directory structure or ways to lay the proper foundation for your project (with unit tests and integration tests) and find it difficult to even deploy your project to a specific App Server, the articles in this series is definitely for you. Let’s begin.</p><h2>Introduction to Maven’s Java EE EAR Directory Structure</h2><h3>Aligning Expectations</h3><p>Unlike Ant, where by you could freely script the build.xml file to accommodate your development and deployment requirements &#8211; asking it to pick up and pack your files from whichever source directories, resource directories or other facilitating file directories that you’ve made and specified; Maven on the other hand works with predefined directory structure specified by Maven as it goes along with the song &#8220;convention over configuration&#8221;. The POM.xml file in Maven pretty much defines the project structure, which dependency (external jar(s)/libraries from other projects including open source ones) from the local or remote repository that it needs, plus plugins that the project would require. A Maven project will include modules and sub-modules. As I have mentioned earlier, Maven is more than a build tool, it’s a project build, maintenance and management tool.</p><h3>Maven’s Java EE EAR Directory Structure</h3><p>Maven works with predefined directory structure for your source codes, application resource files, unit test(s), integration-test and even reports. This is a good thing considering that it standardizes the directory path and naming convention so that other developers who are currently or in future maintain the software project will know where to look for the files when they are involve with the project.</p><p>To give you an idea, I will build a demo project for this tutorial, let&#8217;s call it <strong>DummyDemoJavaEE5</strong> (you may use this for your Java EE 6 application as well). In this demo project, it will include the following modules:</p><ul><li><strong>DummyDemo-ejb </strong>- a module where you put your EJBs (codes and unit tests)</li><li><strong>DummyDemo-web</strong> &#8211; a module for web presto files like html, css, javascripts and front controller classes (codes and unit tests)</li><li><strong>DummyDemo-api</strong> &#8211; a module for common used codes such as utilities, helpers, tools etc. specifically for the project (codes and unit tests)</li><li><strong>DummyDemo-appclient</strong> &#8211; a module for Enterprise App Client (codes and unit tests)<li><strong>DummyDemo-ear</strong> &#8211; a module specifically to package everything to an EAR file for deployment and to access the app server</li><li><strong>integration-test</strong> &#8211; Lastly, a module solely existed for integration tests (not unit tests). This is where you place all of the integration test codes in this module.</li></ul><p>You may not use every module in your project as describe as the above, for example, some projects will not need the Enterprise App Client. You may exclude any of them in your actual project. But for now, this is quite a good repertoire of modules for a Java EE project. The below shows the directory structure for the mentioned modules. Do take note on the folders for your source codes, unit tests and integration tests, at the same time, where to place the pom.xml for their respective modules&#8230;this is how it works in Maven. You may create them manually or you can use one of the handy command in Maven call archetype:generate, which we&#8217;ll go through it later.</p><p><em>** Directories are highlighted in <b>BOLD</b></em></p><p><pre>
<b>DummyDemoJavaEE5</b> (The root folder)
	|
	|---<b>project</b> (contains the core enterprise application codes with the below modules)
	|		|
	|		|---<b>DummyDemo-ear</b> (used for producing the EAR file - no codes here please...)
	|		|		|
	|		|		|---pom.xml (The pom file that defines what is to be included in the EAR)
	|		|
	|		|---<b>DummyDemo-ejb</b> (contains codes for EJBs)
	|		|		|---<b>src</b>
	|		|		|	|---<b>main</b>
	|		|		|	|	|---<b>java</b> (this is the folder where you should put your
	|		|		|	|			  EJB codes - with package folders)
	|		|		|	|---<b>test</b>
	|		|		|		|---<b>java</b> (this is the folder where you should put your
	|		|		|				  unit test that has to do with DummyDemo-ejb
	|		|		|				  - with package folders)
	|		|		|
	|		|		|---pom.xml (The pom file that defines the DummyDemo-ejb module as packaging
	|		|					 type "ejb" with the needed maven dependencies)
	|		|
	|		|---<b>DummyDemo-web</b> (contains web presto stuff like JSP, JSF, CSS, JS, etc.)
	|		|		|---<b>src</b>
	|		|		|	|---<b>main</b>
	|		|		|	|	|---<b>java</b> (this is the folder where you should put your
	|		|		|	|	|		  servlet, JSF or MVC related codes - with package folders)
	|		|		|	|	|
	|		|		|	|	|---<b>webapp</b> (this is the folder for the JSPs, xhtml, css, javascripts, etc.)
	|		|		|	|			|---WEB-INF
	|		|		|	|					|---web.xml (here's you should define your web.xml file)
	|		|		|	|
	|		|		|	|---<b>test</b>
	|		|		|		|---<b>java</b> (this is the folder where you should put your
	|		|		|				  unit test that has to do with the classes in DummyDemo-web
	|		|		|				  - with package folders)
	|		|		|
	|		|		|---pom.xml (The pom file that defines the DummyDemo-web module as packaging
	|		|					 type "war" with the needed maven dependencies)
	|		|
	|		|---<b>DummyDemo-api</b> (contains commonly used classes as part of the library)
	|		|		|---<b>src</b>
	|		|		|	|---<b>main</b>
	|		|		|	|	|---<b>java</b> (this is the folder where you should put your
	|		|		|	|			  codes e.g. utility codes, parsers, etc. - with package folders)
	|		|		|	|---<b>test</b>
	|		|		|		|---<b>java</b> (this is the folder where you should put your unit test
	|		|		|				  that has to do with DummyDemo-api - with package folders)
	|		|		|
	|		|		|---pom.xml (The pom file that defines the DummyDemo-api module
	|		|					 with the needed maven dependencies)
	|		|
	|		|---<b>DummyDemo-appclient</b> (contains codes for Enterprise Application Client)
	|		|		|---<b>src</b>
	|		|		|	|---<b>main</b>
	|		|		|	|	|---<b>java</b> (this is the folder where you should put your
	|		|		|	|			  codes for the Enterprise Application Client - with package folders)
	|		|		|	|---<b>test</b>
	|		|		|		|---<b>java</b> (this is the folder where you should put your unit test
	|		|		|				  that has to do with DummyDemo-apiclient - with package folders)
	|		|		|
	|		|		|---pom.xml (The pom file that defines the DummyDemo-appclient module as
	|		|					 packaging type "app-client" with the needed maven depencencies)
	|		|
	|		|---pom.xml (pom file for project folder)
	|		
	|---<b>integration-test</b> (contains only integration test classes)
	|		|---<b>src</b>
	|		|	|---<b>test</b>
	|		|		|---<b>java</b> (this is the folder where you should put your
	|		|				  integration tests - with package folders)
	|		|
	|		|---pom.xml (The pom file that defines the integration-test module as
	|					 with the needed maven dependencies for running integration tests)
	|
	|---pom.xml (root pom file)
</pre></p><p>These directories are what you should expect from a decent Java EE project being packaged in an EAR as a target deployment file format later. Since the name of the project is <strong>DummyDemoJavaEE5</strong>, let&#8217;s make DummyProbeJavaEE5 as the root folder for the rest of the sub-modules. Next, under the DummyProbeJavaEE5 root project folder, what we could do is to have two separated folders, one is called <strong>project</strong>, which consists of the core contents of the modules (that includes source codes, resource files and unit tests – yes, only unit tests, <strong><em>not integration tests</em></strong>) and the other folder is called <strong>integration-test</strong>, which only host integration test codes as the name implies.</p><p>This is a clean separation and why do we do that? Because we would not want the integration test codes to be part of the build life cycle of the core project modules every time when we need to compile and deploy to the app servers; but, when the need arise for integration tests to be executed, it could be invoked independently. Even though it is separated, the project codes&#8217; dependency for the integration test is not broken as we can define that in the pom.xml file. I’ll leave the discussion of the contents of the pom.xml files to the next part of the series.</p><h2>Creating The Directories Through Maven archetype:generate Command</h2><p>The Maven&#8217;s <strong><em>archetype:generate</em></strong> command will pre-generate the directory modules, sub-modules and their respective pom.xml files. This will save you time and reduce much error against manual creation. Of course, this is not fool proof as the pom.xml files will have to be edited later to include dependencies and other plugins that are necessary.</p><p>To use Maven&#8217;s <strong><em>archetype:generate</em></strong> command for creating the project structure above, follow the below steps. Before you start, just make sure that the maven&#8217;s <strong><em>mvn </em></strong>command is in the path. Use the command prompt or terminal to carry out the below steps.</p><h3>Creating the &#8220;DummyDemoJavaEE5&#8243; project root directory</h3><ol><li>Since the demo project name is <strong>DummyDemoJavaEE5</strong>, log onto the terminal and type &#8220;<strong>mvn archetype:generate</strong>&#8220;. This command will list all of the archetypes available in Maven and from version 3 onwards, it has more than 600 archetypes to choose from.<p>What you need to do now is to filter the archetype for root directory, to do this, just type: &#8220;<strong><em>org.codehaus.mojo.archetypes:pom-root</em></strong>&#8221; at the prompt, it shall filter only one archetype which is <strong>org.codehaus.mojo.archetypes:pom-root</strong>. It will return something like this:<br /><pre>
1: remote -> org.codehaus.mojo.archetypes:pom-root (Root project archetype for creating multi module
projects)
</pre></p><p>type &#8220;1&#8243; to to proceed.</li><li>Next, it will ask you to choose the version of the archetype, just accept, the default, which will always refer to the latest version.</li><li>Next, it will ask you to enter the <strong>groupId</strong>. The <strong>groupId </strong>is a unique name that identifies your project across all projects that all modules within this project should share as common. I&#8217;m going to use &#8220;<strong><em>com.developerscrappad</em></strong>&#8221; here as an example, you may use your company&#8217;s package name such as com.mycompany, etc. as the groupId. Once you&#8217;ve decided on this, it has to be the same across the any modules that you want to have in this project.</li><li>After keying in the groupId, it will then ask you for the <strong>artifactId</strong>. The <strong>artifactId </strong>is the name of the project/module, if not, it is commonly use as the name of the jar file, the war file or the ear file. Since we are creating the root directory for a new project, just enter the name of the project &#8220;DummyDemoJavaEE5&#8243; as the artifactId.</li><li>Next, it will ask for version number, follow by the package name defaulted to the groupId as you have entered, just accept them by default and the root directory structure will be created. Once done, you should be able to see the &#8220;DummyDemoJavaEE5&#8243; directory and within it, it will have a pom.xml file.</li></ol><p>The archetype that you&#8217;ve used just now is to create the root pom (Project Object Model). The root pom is always used to encapsulate any modules within it and make it look as a whole. A root pom can consists of other root pom(s) and other modules within the directory.</p><h3>Creating the &#8220;project&#8221; directory</h3><p>Now that you know how to use the <strong>archetype:generate</strong> command, we still need to create the rest of the directories and modules. Next, we need to create the <strong>project</strong> directory, which is where you put all of the module codes in it. Please change your working directory into <strong>DummyDemoJavaEE5</strong> ( <em>&lt;path&gt;/DummyDemoJavaEE5/</em> ) and do the same like what you did to create the root project directory DummyDemoJavaEE5. Do use the same archetype as you did and follow the below parameters:</p><ul><li>archetype: <strong>org.codehaus.mojo.archetypes:pom-root</strong></li><li>groupId: com.developerscrappad</li><li>artifactId: <strong>project</strong></li><li>Version &amp; package: accept the default values</li></ul><p>Once done, you should be able to see a generated pom.xml within the <strong>project</strong> directory.</p><h3>Creating the &#8220;DummyDemo-ejb&#8221; module directory for EJBs and other back-end codes</h3><p>Next, change the working directory into <strong>project</strong> directory ( <em>&lt;path&gt;/DummyDemoJavaEE5/project/</em> ). Now, we&#8217;ll make a module specifically for your EJBs. This module is specifically used to place your entity classes, session beans, message-driven beans and other back-end related codes. To achieve this, we&#8217;ll have to use another archetype call <strong>org.codehaus.mojo.archetypes:ejb-jee5</strong> instead of pom-root (yes, you can use this for Java EE 6). Follow the below:</p><ol><li>Once you are in the <em>&lt;path&gt;/DummyDemoJavaEE5/project/</em> directory, type &#8220;<strong>mvn archetype:generate</strong>&#8221; and type the filter &#8220;<strong>org.codehaus.mojo.archetypes:ejb-jee5</strong>&#8220;:<br /><pre>
1: remote -> org.codehaus.mojo.archetypes:ejb-jee5 (-)
</pre></p><p>Just type &#8220;1&#8243;, the number of the selection.</li><li>For the rest of the parameters, just follow the below:<ul><li>groupId: com.developerscrappad</li><li>artifactId: <strong>DummyDemo-ejb</strong></li><li>Version &amp; package: accept the default values</li></ul></li></ol><p>Once done, you should be able to see the <strong>DummuDemo-ejb</strong> directory ( <em>&lt;path&gt;/DummyDemoJavaEE5/project/DummyDemo-ejb/</em> ) and within it, the pom.xml file will be created as well. You may have multiple EJB modules using the same way to generate them if you decide to introduce separation of business process instead of lumping all EJBs into one module in your future project.</p><h3>Creating the &#8220;DummyDemo-api&#8221; module directory for commonly used classes that pack as a jar/library</h3><p>Sometimes, you may have some commonly used classes through out the project such as utility classes, helpers, tools or parsers that you want to put them into a jar file so that other modules could use it. Just follow the below:</p><ol><li>In the working directory of <strong>project</strong> ( <em>&lt;path&gt;/DummyDemoJavaEE5/project/</em> ) perform the &#8220;<strong>mvn archetype:generate</strong>&#8221; command.</li><li>When ask to filter the archetype, type: &#8220;<strong>org.apache.maven.archetypes:maven-archetype-quickstart</strong>&#8220;, you should get something like:<br /><pre>
1: remote -> org.apache.maven.archetypes:maven-archetype-quickstart (An archetype which contains
a sample Maven project.)
</pre></p><p>just select it.</li><li>For the rest of the parameters, just key in the below:<ul><li>groupId: com.developerscrappad</li><li>artifactId: <strong>DummyDemo-api</strong></li><li>Version &#038; package: accept the default values</li></ul></li></ol><p>Once done, the module directory <strong>DummyDemo-api</strong> will be created with the pom.xml file inside of it. This is the place where you put your commonly used codes.</p><h3>Creating the &#8220;DummyDemo-web&#8221; module directory for JSFs, JSPs, MVCs and other web presentation related files</h3><p>The <strong>DummyDemo-web</strong> is the web application module for the project. To create this, please make sure that the working directory is still on <strong>project</strong> ( <em>&lt;path&gt;/DummyDemoJavaEE5/project/</em> ). We need to use the <strong>org.codehaus.mojo.archetypes:webapp-jee5</strong> archetype. Just create this with the archetype:generate command, filter the archetype and you should see something like:<br /><pre>
1: remote -> org.codehaus.mojo.archetypes:webapp-jee5 (-)
</pre><br /> just create the module with like what you&#8217;ve done in the previous steps with the below details:</p><ul><li>archetype: <strong>org.codehaus.mojo.archetypes:webapp-jee5</strong></li><li>groupId: com.developerscrappad</li><li>artifactId: <strong>DummyDemo-web</strong></li><li>Version &#038; package: accept the default values</li></ul><p>Once the module was created, the pom.xml file will be generated and the rest of the module directory structure specifically for JEE webapp, that includes the WEB-INF directory, the sample web.xml and a sample index.jsp file.</p><h3>Creating the &#8220;DummyDemo-appclient&#8221; module directory for Enterprise Application Client</h3><p>Not many enterprise application will need an Application Client, but if you need it in your project, these are the steps to create the Enterprise Application Client module. Here, let&#8217;s call it <strong>DummyDemo-appclient</strong>. Do this in the <strong>project</strong> ( <em>&lt;path&gt;/DummyDemoJavaEE5/project/</em> ) working directory, we need to use the archetype call &#8220;<strong>org.codehaus.mojo.archetypes:appclient-jee5</strong>&#8220;. Just use the archetype:generate command the same way with the details below:</p><ul><li>archetype: <strong>org.codehaus.mojo.archetypes:appclient-jee5</strong></li><li>groupId: com.developerscrappad</li><li>artifactId: <strong>DummyDemo-appclient</strong></li><li>Version &#038; package: accept the default values</li></ul><p>Once completed, not only that the pom.xml file will be generated, but this module includes a sample Main.java file as the main class for the Enterprise Application Client.</p><h3>Creating the &#8220;DummyDemo-ear&#8221; module for packing the EAR file</h3><p>Now that we have the rest of the Java EE core modules, it is time to create the <strong>DummyDemo-ear</strong> module solely for packaging the EAR file and it is also in this module that we will define the deployment instructions in the pom.xml file. I&#8217;ll leave the discussion in the later part of the series, because different app server will require different configuration.</p><p>Anyway, to create the <strong>DummyDemo-ear</strong> module, we need to use the <strong>org.codehaus.mojo.archetypes:ear-jee5</strong> archetype. In the working directory of <strong>project</strong> ( <em>&lt;path&gt;/DummyDemoJavaEE5/project/</em> ), just use the &#8220;<strong>mvn archetype:generate</strong>&#8221; command with the below details:</p><ul><li>archetype: <strong>org.codehaus.mojo.archetypes:ear-jee5</strong></li><li>groupId: com.developerscrappad</li><li>artifactId: <strong>DummyDemo-ear</strong></li><li>Version &#038; package: accept the default values</li></ul><p>There is nothing much to explore inside the <strong>DummyDemo-ear</strong> module directory for now after creating. But nevertheless, this module is important for deployment later on.</p><h3>Creating the &#8220;integration-test&#8221; module for, well&#8230;integration tests</h3><p>Lastly, we&#8217;ll now create the <strong>integration-test</strong> module, which is solely for any integration tests classes. You may place your unit tests files in the previously created modules, but as time passes, I find that having a separate module solely for integration tests will be much better as tests could be run independently without having to induce skip flags to maven and will not run prematurely before the the EAR is being deployed to the application server.</p><p>Creating the <strong>integration-test</strong> module is easy. Just change the working directory out from the <strong>project </strong>directory and back to the <strong>DummyDemoJavaEE5 </strong>root folder ( <em>&lt;path&gt;/DummyDemoJavaEE5/</em> ), use the &#8220;<strong>org.apache.maven.archetypes:maven-archetype-quickstart</strong>&#8221; archetype as you execute the &#8220;<strong>mvn archetype:generate</strong>&#8221; command. As for the rest of the parameters, the details are below:</p><ul><li>archetype: <strong>org.apache.maven.archetypes:maven-archetype-quickstart</strong></li><li>groupId: com.developerscrappad</li><li>artifactId: <strong>integration-test</strong></li><li>Version &#038; package: accept the default values</li></ul><p>Once complete, you have a separate <strong>integration-test</strong> module solely for your integration test classes. In fact, you may use the same approach to create a functional test module to run <a target="_blank" href="http://seleniumhq.org/">Selenium</a> related tests if you wish for your future projects.</p><h2>To Be Continued&#8230;</h2><p>If you have followed through the above steps, you should be able to produce all of the module layout of the project, plus the module for integration-test. In my opinion, using Maven&#8217;s archetype:generate command to generate the project and module layout is very much faster than by doing it manually. It generates the pom.xml file, although it is not complete, still it is much faster and less error than crafting it by your own.</p><p>We are far from finish. I will leave the discussion of what contents to be included in the pom.xml file in the next part of the series. As for the next part, I&#8217;ll be writing about where to put the codes and what are the necessary plugins and dependency that is to be included in the pom.xml files. So, stay tuned.</p> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/1177/java/java-ee/maven/building-and-deploying-java-ee-ear-with-maven-to-java-ee-application-server-part-1-project-directory-structure-amp-module-generation-through-archetype-generate/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory</title><link>http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/</link> <comments>http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/#comments</comments> <pubDate>Sat, 13 Oct 2012 09:37:51 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[Active Directory]]></category> <category><![CDATA[JNDI]]></category> <category><![CDATA[LDAP]]></category> <category><![CDATA[Java]]></category> <category><![CDATA[Java EE]]></category> <category><![CDATA[objectGUID]]></category> <category><![CDATA[Windows Active Directory]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=1109</guid> <description><![CDATA[Windows Active Directory is a good way for many corporations to be used as a means of user management. To a further extend, custom software application are being developed to leverage its capabilities as a directory server and marshaling of certain user information to be stored back to the custom developed application’s database is quite [...]]]></description> <content:encoded><![CDATA[<p>Windows Active Directory is a good way for many corporations to be used as a means of user management. To a further extend, custom software application are being developed to leverage its capabilities as a directory server and marshaling of certain user information to be stored back to the custom developed application’s database is quite common. In order to <em>uniquely </em>identify the objects in the directory (objects include person, group, OUs, etc.) these objects carry an attribute call <strong>objectGUID</strong>. If you are writing a Java or Java EE app that requires access to this, it might not be straight forward to read it as it is because it is stored in binary form. This article will guide you through what is <strong>objectGUID</strong>, what can it be used and more importantly here, it will show you 2 ways of decoding it.<br /> <span id="more-1109"></span><br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/idTag.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/idTag-150x150.jpg?e83a2c" alt="" title="idTag" width="150" height="150" class="alignnone size-thumbnail wp-image-1111" style="display: none;" /></a></p><h2>What is Object-GUID</h2><p>The <strong>objectGUID </strong>is the attribute that holds the Global Unique Identity Code of the object that resides in the Active Directory. According to Microsoft Technet’s documentation, the uniqueness of the ID does not only limits itself across the enterprise but it is unique throughout the entire globe. It is a 128-bit value, so expect nothing less. Nevertheless, Object-GUID is how Active Directory uses to identify the object, whether it is of user/person or group or others. For this entire article, we&#8217;ll be dealing with Object-GUID specifically for a User/INetPerson.</p><h2>What is the Purpose of Object-GUID?</h2><p>As mentioned, the Object-GUID is a unique identity for a user/person or a group and other objects in the Active Directory. Not only that it is unique, it is unchangeable and non-volatile throughout the environment. This is something good. Why? Let’s say if the Active Directory has a user by the name (CN) of “<strong><em>Adam Bristol</em></strong>” with the <strong>userPrincipalName </strong>as “<strong><em>adambristol@developerscrappad.com</em></strong>”; if on one fine day the Adaministrator decides to change the logon name (userPrincipalName) to “<strong><em>adambristol-20110908@developerscrappad.com</em></strong>”, even the object is the same but if you have an application that uses the previous <strong>userPrincipalName </strong>to locate the same user record, it will yield nothing. So therefore, GUID is the way to go to use to locate and bind an object, because it is permanent and non-changeable; it is like the primary key used in databases, likewise GUID serves as the &#8220;primary key&#8221; in analogy in the Active Directory.</p><h2>Where Can We Use Object-GUID?</h2><p>If your application is tightly coupled with Active Directory as a means to gain access to user information, you can use GUID to directly locate the user without going through the LDAP queries with search filter; even at times when LDAP search is necessary, you may skip the lengthy query syntax just by querying the GUID alone, you should be able to object the specific user object right on the dot.</p><p>If you ever need some sort of key data or unique identifier to represent a user as a form of primary key to be kept in the database so that other tables could reference it as a foreign key, GUID is the best fitted value to be used for this purpose. Like wise, in my opinion, it is not recommended to have <strong>sAMAccountName </strong>or <strong>userPrincipalName </strong>as the identifier of user in both the context of LDAP lookup and database primary/foreign key referential when it comes to developing custom application with Active Directory &amp; database pairing.</p><h2>How To Obtain A User&#8217;s objectGUID From Windows Active Directory</h2><p>Now, assuming that in the Active Directory, we have a fictional user with the logon name “adambristol” under the domain name of “developerscrappad.com”; you may obtain the <strong>objectGUID </strong>attribute value shown below:</p><p><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://10.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>&nbsp;&nbsp; <span style="color: #666666; font-style: italic;">//Just change this to the actual IP and Port</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;java.naming.ldap.attributes.binary&quot;</span>, <span style="color: #0000ff;">&quot;objectGUID&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Important!</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;adambristol@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Start checking if the user is within the organization unit(s)</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchFilter = <span style="color: #0000ff;">&quot;(&amp;(objectClass=person)(userPrincipalName=adambristol@developerscrappad.com))&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> returningAttrs = <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;objectGUID&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">SUBTREE_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setReturningAttributes</span><span style="color: #009900;">&#40;</span>returningAttrs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">SearchResult</span><span style="color: #339933;">&gt;</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchResult</span> sr = answer.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> guid = <span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span> sr.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;objectGUID&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Do something with guid</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Do something with the exception...</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p>Notice that when we define the environment &#8220;<strong>env</strong>&#8221; variable, which is an instance of java.util.Hastable, besides all the regular properties and value that you need to put into the Hashtable, do remember to have this as well:<br /><pre>
env.put("java.naming.ldap.attributes.binary", "objectGUID");
</pre></p><p>This property value is important because usually when we traverse the directory tree, attribute value objects will be returned as an instance of java.lang.String. Buy having the line above, it will return the attribute value object specifically for attribute &#8220;objectGUID&#8221; as an instance of byte [] instead (the rest of the attribute values will still remain as java.lang.String).</p><p><pre>
<strong>IMPORTANT Note:</strong>
For line 27, <strong>PLEASE DO NOTE CODE THE BELOW</strong>:

<em>byte[] guid = sr.getAttributes().get("objectGUID").get().toString().getBytes();</em>

as turning it to String then to bytes again will adulterate the original byte values.
</pre></p><p>Now, if you check the <strong>guid[]</strong> array&#8217;s size, you&#8217;ll realized that the length value is <strong>16</strong> (128-bits). Every GUID will have this fix amount of byte array size. Let&#8217;s move on to the below and see what we can do with the chunk of bytes drawn. From here on, we&#8217;ll have to deal with the <strong>guid </strong>from byte to byte (8-bit).</p><h2>Decoding Method 1: Binding String &#8211; What Is It and Where To Use It?</h2><p>The Binding String is a string with specific format which is being use to immediately bind the user object and gain direct access to the attributes of it without going through the tedious nitty-gritty task of defining the LDAP searchBase and searchFilter value to specifying the SearchControl and other processing resources of searching through the Active Directory tree.</p><p>The format of a Binding GUID String will look something like the below:<br /><pre>
&lt;GUID=ac642e6e-6ab5-425a-bcc9-9f5067d46e3f&gt;
</pre></p><p>Notice that after the prefix &#8220;&lt;GUID=&#8221;, what follows is a series of double digit Hex values with dashes &#8220;-&#8221; in between. Some folks call it <strong>Dashed String</strong> to simplify things. Nevertheless, the Dashed String is what we desire to construct so that we could form the the Binding String later.</p><h3>How To Decode objectGUID To Dashed String?</h3><p>To decode raw binary data from GUID to Dashed String, we should arrange the individual specific byte array slot to the below format and <strong>TURN EACH array value to double digit Hex representation from the unsigned value of the byte</strong>.</p><h4>Dashed String Format Sequence:</h4><p><pre>
The below are the byte array index sequence (no space):

[3] [2] [1] [0] - [5] [4] - [7] [6] - [8] [9] - [10] [11] [12] [13] [14] [15]
</pre></p><h4>Introducing Bit Masking</h4><p>It is tempting to convert the byte directly to Hex string by invoking e.g. Integer.toHexString((int)guid[0]), unfortunately, by the nature of Java, this might not produce the right represented value as you have to remember that the byte data type in Java is a signed data type, therefore, there is a possibility that output may be a negative integer value. In order to prevent that, we need a to implement a layer of bit mask. Bit masking is a technique to filter the byte so that it could prevent the sign bit extension from clobbering the higher bytes.</p><p>For example, in order to convert the byte to int, which is to be used as an argument for Integer.toHexString(), do the following:<br /><pre>
int maskedValue = (int) guid[0] & 0xff;
String hexString = Integer.toHexString(maskedValue);
</pre></p><p>The above is just an example of bit masking and we&#8217;ll be using this technique (not the exact code) for the rest of the decoding process.</p><h4>How To Decode The Bytes</h4><p>If you had follow the codes above to obtain the &#8220;<strong>guid</strong>&#8221; byte array, here&#8217;s the step-by-step process of decoding each byte within the array:</p><ol><li>First, know the sequence of the byte index that forms the Dashed String. Just refer to the above.</li><li>Next, apply bit masking to each and every single byte value accessed in the array.</li><li>Follow by converting to the Hex representation of the value.</li><li>Just make sure that the Hex value is a double digit value, meaning instead of &#8220;A&#8221;, it should be &#8220;0A&#8221;</li><li>Lastely, form the Binding String in the syntax format of &#8220;&lt;GUID=dashed-string-value&gt;&#8221;</li></ol><p>To do this in Java, just follow the codes below:<br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> convertToBindingString<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> objectGUID<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> displayStr = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;GUID=&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>convertToDashedString<span style="color: #009900;">&#40;</span>objectGUID<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> displayStr.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> convertToDashedString<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> objectGUID<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> displayStr = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">11</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">12</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">13</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">14</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> displayStr.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #339933;">&lt;</span>= 0xF<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> sb = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> sb.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #003399; font-weight: bold;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong>Codes Explanation:</strong><br /> The prefixZeros() method is used to convert the int value to Hex value and adding a &#8220;0&#8243; in front of the Hex character is it is only of a single digit and thus making it a double Hex value.</p><p>The core is in the convertToDashedString() method where it takes the byte array of the objectGUID value as an argument, access the byte array index individually according to the dashed-string sequence, perform bit mask on each and every byte, send it to the prefixZeros() method, then form the string sequence.</p><p>Lastly, convertToBindingString() method is more like a wrapper where it takes the objectGUID byte array, pass it to method convertToDashedString() and add both prefix &#8220;&lt;GUID=&#8221;and postfix &#8220;&gt;&#8221; to the result that was return from the convertToDashedString() method.</p><h3>How To Use Binding String To Bind An Object?</h3><p>Once you have successfully converted the raw byte array gotten from the <strong>objectGUID </strong>attribute to the <strong>Binding String</strong> format, you may always directly bind a user with the following codes:</p><p><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #666666; font-style: italic;">// After initializing the ctx object which is an instance of DirContext...</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">String</span> bindingString = <span style="color: #0000ff;">&quot;&lt;GUID=ac642e6e-6ab5-425a-bcc9-9f5067d46e3f&gt;&quot;</span><span style="color: #339933;">;</span></li><li><span style="color: #003399; font-weight: bold;">Attributes</span> attrs = ctx.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span>bindingString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">// Then do something with the attrs, for example...</span></li><li><span style="color: #003399; font-weight: bold;">NamingEnumeration</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> ids = attrs.<span style="color: #006633;">getIDs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>ids.<span style="color: #006633;">hasMore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> id = ids.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">Object</span> value = attrs.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Attribute: &quot;</span> + id + <span style="color: #0000ff;">&quot;, Value: &quot;</span> + value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p>This is how you can directly bind the user object and obtain all of its attributes immediately. The object binding through Binding String is the easiest, if not, the fastest way of direct accessing the user in the Active Directory without needing to know the OU or the userPrincipalName.</p><p>** Personally, when I develop application that requires Active Directory access and a database for other application interest, I&#8217;ll keep the Binding String as a primary key in my user table as it could be used to referenced by other tables and make reference to the Active Directory.</p><h2>Decoding Method 2: Byte String – What Is It and Where To Use It?</h2><p>Suppose that if you need a way to search of a particular user through LDAP query using the SearchControl object or through other LDAP tools, it will be quite difficult to use the raw byte value of the objectGUID as the query parameter as the query string will require another format of the objectGUID. So here, I&#8217;ll show you how to decode the objectGUID byte array to form a Byte String (a.k.a. Octet String).</p><h3>How To Decode To Byte String?</h3><p>To decode the <strong>guid </strong>byte array to byte string, we need to loop through the array, convert the bytes to double digit Hex representation and arrange it in such format with the front slash as a prefix for each byte (without space):<br /><pre>
\ [0] \ [1] \ [2] \ [3] \ [4] \ [5] \ [6] \ [7] \ [8] \ [9] \ [10] \ [11] \ [12] \ [13] \ [14] \ [15]
</pre></p><h4>Decoding Procedure</h4><p>By using the same byte array guid variable as we&#8217;ve gotten from the codes above, just follow the below process to decode the bytes to form the Byte String:</p><ol><li>Write a while loop for loop through the guid byte array.</li><li>For every byte in the array, make sure to perform a bit mask and convert it to Hex string by invoking Integer.toHexString() method.</li><li>Once the Hex string is gotten, just check it and prefix the front with &#8220;0&#8243; for single digit to make it as a double digit Hex string.</li><li>Build the final Byte String with the front slash &#8220;\&#8221; prefixed on every Hex string value.</li></ol><p>This is very simple and straight forward. Here are the Java codes to perform the mentioned process:<br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> convertToByteString<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> objectGUID<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> result = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span> i = <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> objectGUID.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> i++<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> transformed = prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>transformed<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> result.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #339933;">&lt;</span>= 0xF<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> sb = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> sb.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #003399; font-weight: bold;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><h3>How To Use The Byte String To Search For An Object?</h3><p>As mentioned, the Byte String is used for LDAP query instead to bind an object directly from the Active Directory. For example, after getting the raw bytes of the objectGUID from a fictional user with userPrincipalName of &#8220;adambristol@developerscrappad.com&#8221;, and once the bytes were converted to Byte String, the Byte String output will be something like the below:<br /><pre>
\6e\2e\64\ac\b5\6a\5a\42\bc\c9\9f\50\67\d4\6e\3f
</pre></p><p>Next, in order to construct a property LDAP search query with the objectGUID parameter value properly defined, the search query should look like the below example:</p><p><pre>
(&(objectClass=person)(objectGUID=\6e\2e\64\ac\b5\6a\5a\42\bc\c9\9f\50\67\d4\6e\3f))
</pre></p><p>This is how we put the Byte String in to good use for LDAP searching. By putting it in Java codes, it should very well be like the below:</p><p><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #666666; font-style: italic;">// After initializing the ctx object, which is an instance of DirContext</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li><span style="color: #003399; font-weight: bold;">String</span> searchFilter = <span style="color: #0000ff;">&quot;(&amp;(objectClass=person)(objectGUID=<span style="color: #000099; font-weight: bold;">\\</span>6e<span style="color: #000099; font-weight: bold;">\\</span>2e<span style="color: #000099; font-weight: bold;">\\</span>64<span style="color: #000099; font-weight: bold;">\\</span>ac<span style="color: #000099; font-weight: bold;">\\</span>b5<span style="color: #000099; font-weight: bold;">\\</span>6a<span style="color: #000099; font-weight: bold;">\\</span>5a<span style="color: #000099; font-weight: bold;">\\</span>42<span style="color: #000099; font-weight: bold;">\\</span>bc<span style="color: #000099; font-weight: bold;">\\</span>c9<span style="color: #000099; font-weight: bold;">\\</span>9f<span style="color: #000099; font-weight: bold;">\\</span>50<span style="color: #000099; font-weight: bold;">\\</span>67<span style="color: #000099; font-weight: bold;">\\</span>d4<span style="color: #000099; font-weight: bold;">\\</span>6e<span style="color: #000099; font-weight: bold;">\\</span>3f))&quot;</span><span style="color: #339933;">;</span></li><li><span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">SUBTREE_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">NamingEnumeration</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">SearchResult</span><span style="color: #339933;">&gt;</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">// Do something with the search result...</span></li><li><span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchResult</span> sr = answer.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">Attributes</span> attrs = sr.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> ids = attrs.<span style="color: #006633;">getIDs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>ids.<span style="color: #006633;">hasMore</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> id = ids.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">Object</span> value = attrs.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>id<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Attribute: &quot;</span> + id + <span style="color: #0000ff;">&quot;, Value: &quot;</span> + value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p>The Byte String was used for the searchFilter and for every front slash &#8220;\&#8221;, please remember to escape it. This sums up the construction of Byte String and how to put it in use when you need to perform the LDAP search for a particular user.</p><h2>Summary</h2><p>I hope these 2 ways of decoding the <strong>objectGUID </strong>value written here could help you to approach your Active Directory user access and management through your Java application in a more confident and efficient way. I have written a class with the codes below at your disposal to simplify the <strong>objectGUID </strong>decoding experience:</p><p><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ObjectGUID_Tools <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> convertToByteString<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> objectGUID<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> result = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span> i = <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> objectGUID.<span style="color: #006633;">length</span><span style="color: #339933;">;</span> i++<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> transformed = prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\\</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>transformed<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> result.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> convertToBindingString<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> objectGUID<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> displayStr = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&lt;GUID=&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>convertToDashedString<span style="color: #009900;">&#40;</span>objectGUID<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> displayStr.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> convertToDashedString<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">byte</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> objectGUID<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> displayStr = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">3</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">5</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">4</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">7</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">6</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">8</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">9</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;-&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">10</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">11</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">12</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">13</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">14</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;displayStr.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span>prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span><span style="color: #009900;">&#41;</span> objectGUID<span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">15</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;</span> 0xFF<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> displayStr.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399; font-weight: bold;">String</span> prefixZeros<span style="color: #009900;">&#40;</span><span style="color: #006600; font-weight: bold;">int</span> value<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>value <span style="color: #339933;">&lt;</span>= 0xF<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> sb = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;0&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sb.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> sb.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #003399; font-weight: bold;">Integer</span>.<span style="color: #006633;">toHexString</span><span style="color: #009900;">&#40;</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p>Best of effort to you and thank you for reading.</p><h3>Related Articles:</h3><ul><li><a href="http://www.developerscrappad.com/963/java/jndi/java-jndi-ldap-windows-active-directory-authentication-organizational-unit-group-and-other-information-access/">Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group &amp; Other Information Access</a></li><li><a href="http://www.developerscrappad.com/1052/windows/active-directory/quick-note-unable-to-perform-ldap-wildcard-search-on-windows-active-directory/">Quick Note: Unable To Perform LDAP Wildcard “*” Search On Windows Active Directory</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Quick Note: Unable To Perform LDAP Wildcard “*” Search On Windows Active Directory</title><link>http://www.developerscrappad.com/1052/windows/active-directory/quick-note-unable-to-perform-ldap-wildcard-search-on-windows-active-directory/</link> <comments>http://www.developerscrappad.com/1052/windows/active-directory/quick-note-unable-to-perform-ldap-wildcard-search-on-windows-active-directory/#comments</comments> <pubDate>Tue, 09 Oct 2012 07:08:10 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[Active Directory]]></category> <category><![CDATA[LDAP]]></category> <category><![CDATA[JNDI]]></category> <category><![CDATA[Windows Active Directory]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=1052</guid> <description><![CDATA[In case you are searching high and low for a solution or an answer to why Windows Active Directory doesn&#8217;t return any search when you perform a wildcard search on attributes like &#8220;distinguishedName&#8220;, &#8220;memberOf&#8221; or &#8220;member&#8220;, well, here&#8217;s the answer&#8230; In any X.500 compliant directory server, the rules are at such where by it doesn&#8217;t [...]]]></description> <content:encoded><![CDATA[<p>In case you are searching high and low for a solution or an answer to why Windows Active Directory doesn&#8217;t return any search when you perform a wildcard search on attributes like &#8220;<strong>distinguishedName</strong>&#8220;, &#8220;<strong>memberOf</strong>&#8221; or &#8220;<strong>member</strong>&#8220;, well, here&#8217;s the answer&#8230;<br /> <span id="more-1052"></span><br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/1394496_13224780.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/1394496_13224780-150x150.jpg?e83a2c" alt="" title="1394496_13224780" width="150" height="150" class="alignnone size-thumbnail wp-image-1055" style="display: none;" /></a><br /> In any X.500 compliant directory server, the rules are at such where by it doesn&#8217;t allow wildcard &#8220;*&#8221; search on attributes which are of Distinguished Name (DN) type. Therefore, if you are performing query such as:</p><p><pre>
(&(objectClass=person)(userPrincipalName=username@mydomain.com)(memberOf=Some Group*))
</pre></p><p>You wouldn&#8217;t be able to get any result from this search. Therefore, if you are developing software solution which requires wildcard searching on DN typed attribute, you need to find a work around.</p><h2>How To Know If An Attribute Is Of Type Distinguished Name?</h2><p>This is very simple for Windows Active Directory. Just perform the below as the:</p><ol><li>In the command prompt or just type &#8220;<strong>mmc /a</strong>&#8221; and press &#8220;Enter&#8221;. You may do this with the Start button -> Run -> &#8220;<strong>mmc /a</strong>&#8221; as well. This command will bring out <strong>Microsoft Management Console</strong>.</li><li>At the console, Click <strong>File -> Add/Remove Snap-ins</strong>.</li><li>In the &#8220;<strong>Available Span-ins</strong>&#8221; selection list, select <strong>Active Directory Schema</strong>, then click on the &#8220;<strong>Add &gt;</strong>&#8221; button. Then click &#8220;<strong>OK</strong>&#8220;.</li><li>Now, <strong>Active Directory Schema</strong> should appear as part of the <strong>Console Root</strong> tree. Expend it and click on the &#8220;<strong>Attributes</strong>&#8221; folder. You should see all of the attributes in the table.</li><li>In the attributes table, just click on the &#8220;<strong>Syntax</strong>&#8221; column header to sort it, scroll down until you see attributes with syntax of &#8220;<strong>Distinguished Name</strong>&#8221; like the picture below:<br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/dn.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/dn-300x160.jpg?e83a2c" alt="" title="dn" width="300" height="160" class="aligncenter size-medium wp-image-1104" /></a></li></ol><p><strong>The attributes list that carries the type &#8220;Distinguished Name&#8221; in the Syntax column are the ones that could not be search with partial wildcard &#8220;*&#8221; search.</strong></p><p>Hope it helps.</p><h3>Related Articles:</h3><ul><li><a href="http://www.developerscrappad.com/963/java/jndi/java-jndi-ldap-windows-active-directory-authentication-organizational-unit-group-and-other-information-access/">Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group &amp; Other Information Access</a></li><li><a href="http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/">Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/1052/windows/active-directory/quick-note-unable-to-perform-ldap-wildcard-search-on-windows-active-directory/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Java JNDI/LDAP: Windows Active Directory Authentication, Organizational Unit, Group &amp; Other Information Access</title><link>http://www.developerscrappad.com/963/windows/active-directory/java-jndi-ldap-windows-active-directory-authentication-organizational-unit-group-and-other-information-access/</link> <comments>http://www.developerscrappad.com/963/windows/active-directory/java-jndi-ldap-windows-active-directory-authentication-organizational-unit-group-and-other-information-access/#comments</comments> <pubDate>Thu, 04 Oct 2012 05:05:15 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[Active Directory]]></category> <category><![CDATA[JNDI]]></category> <category><![CDATA[LDAP]]></category> <category><![CDATA[Java]]></category> <category><![CDATA[Windows Active Directory]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=963</guid> <description><![CDATA[In today&#8217;s IT environment, most mid-size corporation and above will have some form of centralized employee/user management system that is often conveniently leveraging on the directory service that the operating system supplies and Windows Active Directory is one that is used and made available in the corporate space. If the Java/Java EE application that you [...]]]></description> <content:encoded><![CDATA[<p>In today&#8217;s IT environment, most mid-size corporation and above will have some form of centralized employee/user management system that is often conveniently leveraging on the directory service that the operating system supplies and Windows Active Directory is one that is used and made available in the corporate space. If the Java/Java EE application that you are writing involves accessing the Windows Active Directory for user authentication and checking of user privilege according to department, job title or even organizational unit, in order to decide if certain features of your software could be made available, this article will give you a comprehensive kick start to get the codes running as soon as possible.<br /> <span id="more-963"></span><br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/268027_2380.jpg?e83a2c" style="display: none;"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/268027_2380-150x150.jpg?e83a2c" alt="" title="Minolta DSC" width="150" height="150" class="alignnone size-thumbnail wp-image-1038" /></a><br /> But before we start, please understand that there is no straight guaranteed way that fits all situations. Why? Because different companies will have different ways of organizing the data in the Active Directory, which includes different organizational structure, different ways of encapsulating departmental information or even different ways of structuring branch information. So, the purpose of this article is to outline to you some of the common and snappy ways of accessing, slicing and dicing the data within the Active Directory and as you progress in future, you should be able to know how to maneuver your way through directory structure of different companies with different structure and capacity.</p><h2>Tools Needed</h2><p>Besides your IDE or your TextPad for your Java codes, you might need LDAP tools to explore and traverse the active directory for some insights. If you are using Eclipse IDE, you may want to consider Apache’s Directory Studio found at <a href="http://directory.apache.org/studio/">http://directory.apache.org/studio/</a>. For Netbeans users, you may want to consider the LDAP Explorer plugin which can be found at <a href="http://plugins.netbeans.org/plugin/25684/ldap-explorer">http://plugins.netbeans.org/plugin/25684/ldap-explorer</a>.</p><h2>A Story Of A Company</h2><p>Here, I’ll use a fictional company with fictional Active Directory structure that brings us to our code samples later which then enables us to authenticate and the checking of privileges to access certain feature of your application according to the user’s organizational unit, groups, department or even the job title. Let’s say, this fictional company by the name <strong>Developer&#8217;s Scrappad</strong> has both the office in Seattle, US and in London, UK. In both of these regional offices, both have a Sales &#038; Marketing department and there are active staffs within these departments. I have installed a fresh copy of Windows 2003 Server on my test machine and I have enabled Active Directory service and created the root domain as &#8220;<strong>developerscrappad.com</strong>&#8220;.</p><h3><em>The US Office Structure</em></h3><p>Just right after the root domain, I have created an Organizational Unit (OU) call &#8220;<strong>US</strong>&#8221; and within the &#8220;<strong>US</strong>&#8221; OU, I have created another OU called &#8220;<strong>Seattle Office</strong>&#8220;. I have created some fictional staff in the <strong>Sales &amp; Marketing</strong> department and you may find their details listed in the below table:</p><table style="width: 100%;"><thead style="background: #E6E6E6;"><th>First Name<br />Last Name</th><th>Logon<br />Username</th><th>Password</th><th>Type</th><th>Organization<br />(Job Title)</th><th>Organization<br />(Department)</th></thead><tbody><tr><td>Adam Bristol</td><td>adambristol</td><td>passwd1234</td><td>INetOrgPerson</td><td>Marketing Manager</td><td>Sales &amp; Marketing</td></tr><tr><td>Steven Fox</td><td>stevefox</td><td>passwd1234</td><td>INetOrgPerson</td><td>Sales Executive</td><td>Sales &amp; Marketing</td></tr><tr><td>Lynn Zhang</td><td>lynnzhang</td><td>passwd1234</td><td>INetOrgPerson</td><td>Advertising Executive</td><td>Sales &amp; Marketing</td></tr></tbody></table><div style="text-align: center;"><strong><em>Table 1: The staffs (INetOrgPerson) in the US &#8211; Seattle Office Organization Unit</em></strong></div><p>&nbsp;</p><h3><em>The UK Office Structure</em></h3><p>As for UK&#8217;s London Office, I have created an OU call &#8220;<strong>UK</strong>&#8221; just right below the root domain. Within the &#8220;<strong>UK</strong>&#8221; OU, I have created another OU call &#8220;<strong>London Office</strong>&#8220;. The table below shows the list of staff (of INetOrgPerson type) that resides in &#8220;<strong>London Office</strong>&#8221; OU (there&#8217;s only 2 of them):</p><table style="width: 100%;"><thead style="background: #E6E6E6;"><th>First Name<br />Last Name</th><th>Logon<br />Username</th><th>Password</th><th>Type</th><th>Organization<br />(Job Title)</th><th>Organization<br />(Department)</th></thead><tbody><tr><td>Roy Mustang</td><td>roymustang</td><td>passwd1234</td><td>INetOrgPerson</td><td>SEO Specialist</td><td>Systems Development</td></tr><tr><td>James Mahler</td><td>jamesmahler</td><td>passwd1234</td><td>INetOrgPerson</td><td>Sales Executive</td><td>Sales &amp; Marketing</td></tr></tbody></table><div style="text-align: center;"><strong><em>Table 2: The staffs (INetOrgPerson) in the UK &#8211; London Office Organization Unit</em></strong></div><p>&nbsp;</p><h3><em>Making Things Interesting With Groups</em></h3><p>Now, developerscrappad.com is pretty focus in getting their company presence and products marketed through social media. As a result, they&#8217;ve formed a group call &#8220;<strong>Social Media Marketing Taskforce</strong>&#8220;. In this group, the members include Lynn Zhang from the US&#8217;s Seattle Office and Roy Mustang from the UK&#8217;s London Office. Notice that both Lynn Zhang and Roy Mustang are from different departments, in different offices and separately located. For some business requirements to form task force like this, we can still create a group and assign both of them as members. The &#8220;<strong>Social Media Marketing Taskforce</strong>&#8221; group is created under the OU of US\Seattle Office. The below are the pictures of the users (more specifically INetOrgPerson) in different OUs and in their respective groups.</p><p>Here are some snap shots for your reference:</p><table style="border: 0px 0px 0px 0px"><tr><td><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/USTree.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/USTree-300x175.jpg?e83a2c" alt="" title="USTree" width="300" height="175" class="aligncenter size-medium wp-image-983" /></a></p><div style="text-align: center;"><em>Figure 1: US &#8211; Seattle Office</em></div></td><td><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/UKTree.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/UKTree-300x175.jpg?e83a2c" alt="" title="UKTree" width="300" height="175" class="aligncenter size-medium wp-image-982" /></a></p><div style="text-align: center;"><em>Figure 2: UK &#8211; London Office</em></div></td></tr><tr><td><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/SocialMediaTaskForce.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/SocialMediaTaskForce-260x300.jpg?e83a2c" alt="" title="SocialMediaTaskForce" width="260" height="300" class="aligncenter size-medium wp-image-1019" /></a></p><div style="text-align: center;"><em>Figure 3: Social Media Marketing Taskforce Group Members</em></div></td><td><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/AdamBristolProp.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/AdamBristolProp-224x300.jpg?e83a2c" alt="" title="AdamBristolProp" width="224" height="300" class="aligncenter size-medium wp-image-1018" /></a></p><div style="text-align: center;"><em>Figure 4: User Organization Properties</em></div></td></tr></table><h2>Windows Active Directory Authentication through Java JNDI</h2><p>Ok, enough of stories and let&#8217;s get on to the core. In order to start authenticating against the Active Directory in your Java codes, we begin by defining the environment properties and getting the <strong>InitialDirContext </strong>class object initialized. This is shown in the codes sample below. The below codes will try to authenticate Adam Bristol, who is the Marketing Manager with the login name of &#8220;<strong><em>adambristol</em></strong>&#8221; and password &#8220;<strong><em>passwd1234</em></strong>&#8221; into the system:<br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://127.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">// The value of Context.SECURITY_PRINCIPAL must be the logon username with the domain name</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;adambristol@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #666666; font-style: italic;">// The value of the Context.SECURITY_CREDENTIALS should be the user's password</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-style: italic; font-weight: bold;">/**</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Once the above line was executed successfully, the user is said to be</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* authenticated and the InitialDirContext object will be created.</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Authentication failed, just check on the exception and do something about it.</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong><em>** Please don&#8217;t forget to change the Context.PROVIDER_URL value to the IP or hostname of your Active Directory server.</em></strong></p><p>Notice that the value for <strong><em>Context.SECURITY_PRINCIPAL</em></strong> that was put into is &#8220;<strong><em>adambristol@developerscrappad.com</em></strong>&#8220;. Besides the logon username, we have to tail it with &#8220;<strong><em>@developerscrappad.com</em></strong>&#8221; which is the domain name. Please don&#8217;t forget to do this. In fact, <strong><em>Context.SECURITY_PRINCIPAL</em></strong>&#8216;s value should be the value to match against the attribute <strong><em>userPrincipalName </em></strong>in the Active Directory tree, hence &#8220;<strong><em>adambristol@developerscrappad.com</em></strong>&#8221; should be the right value.</p><h3>How To Know / Where To Find The Domain Name?</h3><p>If you are the one who had created and initialized the Active Directory, you&#8217;ll definitely know the domain name because you are the one who defines it. But for folks who are navigating around a foreign system, you can always ask the Windows Server Administrator, or if you have the AD administrative privilege, just login to the server, click on <strong>Start => Administration => Active Directory Users and Computers</strong>, you should be able to find it at the very top level of the directory tree like the below:</p><div style="text-align: center;"> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/domainpic.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/domainpic-300x175.jpg?e83a2c" alt="" title="domainpic" width="300" height="175" class="aligncenter size-medium wp-image-984" /></a><br /> <em>Figure 5: Where To Find The Domain Name</em></div><h2>How to Enable Application Features through Filtering OU, Department, Job Title and Groups</h2><p>At times, the developing software application may not only require Active Directory authentication, but also to have certain features of the application to be made available for people in specific department, job title or even for a certain specific organizational unit. We&#8217;ll explore privilege checking or rather common known as access control one by one. From here onwards, you might need LDAP tools to gain access and to view the directory tree for a clearer picture.</p><h3>How to Check If a Logon User Belongs to a Specific Organizational Unit</h3><p>By using the LDAP browser from Eclipse as an example LDAP tree browsing tool, login into the Active Directory as &#8220;<strong><em>adambristol@developerscrappad.com</em></strong>&#8220;, scroll to the Adam Bristol branch through expending <strong>DC=developerscrappad,DC=com => OU=US => OU=Seattle Office => CN=Adam Bristol</strong>. As mentioned above, what identify Adam Bristol are both the <strong><em>sAMAccountName </em></strong>attribute and the <strong><em>userPrincipalName </em></strong>attribute. If you need something visual, just take a look at the below attached a picture where the important spots had been marked with red boxes.</p> <figure><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/AdamBristol.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/AdamBristol-300x159.jpg?e83a2c" alt="" title="AdamBristol" width="300" height="159" class="aligncenter size-medium wp-image-993" /></a></p><div style="text-align: center;"><em>Figure 6: LDAP Browser&#8217;s Output For User Adam Bristol</em></div> </figure><p>Once you have the information, the next thing is to put it in codes. The purpose of the below code sample is to check if <strong>OU=US => OU=Seattle Office</strong> under the domain of <strong>DC=developerscrappad,DC=com</strong> has such a person call Adam Bristol, identified by the person&#8217;s <strong><em>sAMAccountName </em></strong>(which is the logon username) &#8220;<strong><em>adambristol</em></strong>&#8221; and <strong><em>userPrincipalName </em></strong><strong><em>adambristol@developerscrappad.com</em></strong>.</p><p>** Side Note: In fact, it will be sufficient and appropriate to only match the username with <strong><em>userPrincipalName </em></strong>as it is the preferred logon name for Windows 2000 and above. <strong><em>sAMAccountName </em></strong>is still being used but it is the logon name which used to support clients and servers from a previous version of Windows (such as Windows NT 4.0 and earlier, Windows 95, Windows 98, and LAN Manager). But here, we’ll use both as an example to illustrate some concepts.</p><p><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;adambristol@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://127.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Start checking if the user is within the organization unit(s)</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;OU=Seattle Office,OU=US,DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchFilter = <span style="color: #0000ff;">&quot;(&amp;(objectClass=person)(sAMAccountName=adambristol)(userPrincipalName=adambristol@developerscrappad.com))&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">ONELEVEL_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">boolean</span> pass = <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMoreElements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass = <span style="color: #006600; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>pass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user belongs to the specified OU(s), do something...</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user doesn't belong to the specified OU(s)</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Do something with the exception...</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong>Codes Explanation: Understanding searchBase</strong><br /> As you can see, what we are trying to achieve is to define a <strong>SearchControl </strong>object to be used for searching the tree with the <strong>DirContext </strong>object. In order to make <strong>SearchControl </strong>complete, we must first define the <strong>searchBase </strong>and the <strong>searchFilter</strong>.</p><p>In simple terms, the <strong>searchBase </strong>is the LDAP path on where the search should begin. Since <strong>Adam Bristol</strong> resides under <strong>DC=developerscrappad,DC=com => OU=US => OU => Seattle Office</strong>, the value for <strong>searchBase </strong>should be the reverse order (from further node of the tree to the root node), hence:<br /><pre>
String searchBase = "OU=Seattle Office,OU=US,DC=developerscrappad,DC=com";
</pre></p><p><strong>Codes Explanation: Understanding searchFilter</strong><br /> The <strong>searchFilter </strong>variable is where we input the LDAP search filter query. This query conforms to specific LDAP filter query syntax, you may find the syntax documented <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa746475(v=vs.85).aspx">here</a> for further understanding. For now, the query will be matching sAMAccoutName=adambristol and the <strong><em>userPrincipalName=adambristol@developerscrappad.com</em></strong> and we need to make sure the filter returns a person object with &#8220;<strong><em>objectClass=person</em></strong>&#8221; Hence:<br /><pre>
String searchFilter = \
    "(&(objectClass=person)(sAMAccountName=adambristol)\
    (userPrincipalName=adambristol@developerscrappad.com))";
</pre></p><p>Once both the <strong>searchBase </strong>and the <em>searchFilter </em>variables are defined, the <strong>SearchControl </strong>object is where we put them to work. The <strong>ctx.search()</strong> method will generate results as an instance of <strong>NamingEnumeration</strong>. If it has of records to be iterated, it means, the user is part of the specified OU. Easy isn&#8217;t it?</p><h3>How To Check If A Logon User Belongs To A Specific Department</h3><p>A department qualifying process is slightly different. Instead of traversing through the Active Directory tree, it requires a further filter of the department attribute for a specific user.</p><p>Taking an example of checking if <strong>Roy Mustang</strong> belongs to the Systems Development department, just login through the LDAP tools of your and navigate to <strong>DC=developerscrappad,DC=com => OU=UK => OU=London Office => CN=Roy Mustang</strong>, you should be able to see the attribute call &#8220;<strong>department</strong>&#8220;. The value of the &#8220;<strong>department</strong>&#8221; attribute is what we need to check if <strong>Roy Mustang</strong> is part of the Systems Development department.</p> <figure><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/roymustang.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/roymustang-300x159.jpg?e83a2c" alt="" title="roymustang" width="300" height="159" class="aligncenter size-medium wp-image-999" /></a></p><div style="text-align: center;"><em>Figure 7: LDAP Browser&#8217;s Output For User Roy Mustang</em></div> </figure><p>As for the codes, please refer to the below:<br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://127.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;roymustang@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Perform the check</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchFilter = <span style="color: #0000ff;">&quot;(&amp;(objectClass=person)(userPrincipalName=roymustang@developerscrappad.com)(department=Systems Development))&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">SUBTREE_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">boolean</span> pass = <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMoreElements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass = <span style="color: #006600; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>pass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user belongs to the specified department, do something...</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user doesn't belong to the specified department</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Do something with the exception...</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong>Codes Explanation:</strong><br /> For the codes above, we don&#8217;t have to specify the OU string in the <strong>searchBase</strong>; but please make sure that the root domain string e.g. &#8220;<strong><em>DC=developerscrappad,DC=com</em></strong>&#8221; must be there. But the catch is to make sure the search scope of the <strong>SearchControl </strong>to be set to &#8220;<strong><em>SearchControls.SUBTREE_SCOPE</em></strong>&#8220;. This is to instruct the search to perform not only from the specified <strong>searchBase</strong>, but also to search in the entire sub-tree (branches) as well.</p><p>Since we are to filter if the specific user has the &#8220;<strong>department</strong>&#8221; attribute value of &#8220;<strong><em>Systems Development</em></strong>&#8220;, we&#8217;ll have to make sure that the <strong>searchFilter </strong>consists of the precise query. Hence:</p><p><pre>
String searchFilter = \
    "(&(objectClass=person)(userPrincipalName=roymustang@developerscrappad.com)\
    (department=Systems Development))";
</pre></p><h3>How to Check &amp; Qualify the Job Title of a Logon User</h3><p>Some applications require the check of job title to see if the user is more or less superior to the others, thus allowing the user to gain access or limit on certain features in the application. Turning back to our dear marketing manager Adam Bristol and with the help of LDAP tools, the attribute that carries the job title for a specific user is &#8220;<strong>title</strong>&#8221; in the Active Directory tree.</p> <figure><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/AdamBristolTitle.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/AdamBristolTitle-300x159.jpg?e83a2c" alt="" title="AdamBristolTitle" width="300" height="159" class="aligncenter size-medium wp-image-1004" /></a></p><div style="text-align: center;"><em>Figure 8: LDAP Browser&#8217;s Output (Knowing &#8220;title&#8221;)</em></div> </figure><p>So, how can we filter the job title? Here are the codes to it:<br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://127.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;adambristol@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Check if the user has a job title of &quot;Marketing Manager&quot;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchFilter = <span style="color: #0000ff;">&quot;(&amp;(objectClass=person)(userPrincipalName=adambristol@developerscrappad.com)(title=Marketing Manager))&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">SUBTREE_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">boolean</span> pass = <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMoreElements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass = <span style="color: #006600; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>pass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user does carry the specified job title, do something...</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user doesn't carry the specified job title</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Do something with the exception...</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong>Codes Explanation:</strong><br /> The codes are very much the same as how we check on the department in the previous example. The only change is to tweak the searchFilter string. Since we are matching the &#8220;title&#8221; attribute, we have to qualify all objectClass=person, the &#8220;userPrincipalName&#8221; and the &#8220;title&#8221; attribute values at the same time. Hence:</p><p><pre>
String searchFilter = \
    "(&(objectClass=person)(userPrincipalName=adambristol@developerscrappad.com)\
    (title=Marketing Manager))";
</pre></p><h3>How To Check If A User Belongs To A Specific Group</h3><p>Checking and filtering whether a user belongs to a group can be as straight forward as all the previous examples that we’ve gone through but when it comes to group name matching with wildcard or partial match, it may not be as straight forward as it seems. Referring to user <strong>Lynn Zhang</strong>, she’s part of the &#8220;<strong>Social Media Marketing Taskforce</strong>&#8221; group. Going back to the LDAP Browser, in order to check if a user belongs to a certain specific group, you’ll need to look at the &#8220;<strong>memberOf</strong>&#8221; attribute shown in the below picture. Please take note that if the user belongs to multiple groups, there will be multiple attributes of &#8220;<strong>memberOf</strong>&#8221; with different values. The value of the &#8220;<strong>memberOf</strong>&#8221; attribute is the full qualified distinguished name of the group.</p> <figure> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/LynnZhang.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/10/LynnZhang-300x159.jpg?e83a2c" alt="" title="LynnZhang" width="300" height="159" class="aligncenter size-medium wp-image-1027" /></a></p><div style="text-align: center;"><em>Figure 9: LDAP Browser&#8217;s Output (Knowing &#8220;memberOf&#8221;)</em></div> </figure><h4>Group Name Exact Match</h4><p>In order to check if a user belongs to a group, the exact full qualified path of the group (the same value in &#8220;memberOf&#8221; attribute) is required. The sample codes are as below:<br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://127.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;lynnzhang@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Perform an exact group match with the &quot;memberOf&quot; attribute.</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> searchFilter = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(&amp;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(objectClass=person)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(userPrincipalName=lynnzhang@developerscrappad.com)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(memberOf=CN=Social Media Marketing Taskforce,OU=Seattle Office,OU=US,DC=developerscrappad,DC=com)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">SUBTREE_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">boolean</span> pass = <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMoreElements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass = <span style="color: #006600; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>pass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user belongs to the group. Do something...</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user doesn't belong to the group.</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Do something with the exception...</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><h4>Group Name Partial Match</h4><p>At time, searching through the Active Directory tree with exact match like the above will be painful especially if you are dealing with a very large directory and the matching string for &#8220;<strong>memberOf</strong>&#8221; will be tremendously long. Of course it will give the absolute result right on the dot, but what if the Administrator decides to move the group from where it was? This will cause the whole entire application to break. We can still partially match the group name in the &#8220;<strong>memberOf</strong>&#8221; attribute value with the codes below:</p><p><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span> env = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Hashtable</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">String</span>, <span style="color: #003399; font-weight: bold;">String</span><span style="color: #339933;">&gt;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">INITIAL_CONTEXT_FACTORY</span>, <span style="color: #0000ff;">&quot;com.sun.jndi.ldap.LdapCtxFactory&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_AUTHENTICATION</span>, <span style="color: #0000ff;">&quot;simple&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">PROVIDER_URL</span>, <span style="color: #0000ff;">&quot;ldap://127.0.0.1:389&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_PRINCIPAL</span>, <span style="color: #0000ff;">&quot;lynnzhang@developerscrappad.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>env.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Context</span>.<span style="color: #006633;">SECURITY_CREDENTIALS</span>, <span style="color: #0000ff;">&quot;passwd1234&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #003399; font-weight: bold;">DirContext</span> ctx<span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Authenticate the logon user</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ctx = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">InitialDirContext</span><span style="color: #009900;">&#40;</span>env<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Prepare the search criteria for group name matching</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> searchBase = <span style="color: #0000ff;">&quot;DC=developerscrappad,DC=com&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">StringBuilder</span> searchFilter = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">StringBuilder</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(&amp;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(objectClass=person)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;(userPrincipalName=lynnzhang@developerscrappad.com)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;searchFilter.<span style="color: #006633;">append</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;)&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> returnAttrs<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> = <span style="color: #009900;">&#123;</span><span style="color: #0000ff;">&quot;memberOf&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchControls</span> sCtrl = <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">SearchControls</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setSearchScope</span><span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">SearchControls</span>.<span style="color: #006633;">SUBTREE_SCOPE</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;sCtrl.<span style="color: #006633;">setReturningAttributes</span><span style="color: #009900;">&#40;</span>returnAttrs<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">NamingEnumeration</span><span style="color: #339933;">&lt;</span><span style="color: #003399; font-weight: bold;">SearchResult</span><span style="color: #339933;">&gt;</span> answer = ctx.<span style="color: #006633;">search</span><span style="color: #009900;">&#40;</span>searchBase, searchFilter.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, sCtrl<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">boolean</span> pass = <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Define the match string</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> match = <span style="color: #0000ff;">&quot;Social Media Marketing Taskforce&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// Loop through the results and check every single value in attribute &quot;memberOf&quot;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>answer.<span style="color: #006633;">hasMoreElements</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">SearchResult</span> sr = answer.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">String</span> memberOfAttrValue = sr.<span style="color: #006633;">getAttributes</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;memberOf&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>memberOfAttrValue.<span style="color: #006633;">contains</span><span style="color: #009900;">&#40;</span>match<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pass = <span style="color: #006600; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">break</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>pass<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user belongs to the group (no exact group path). Do something...</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// The user doesn't belong to the group.</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li><span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">NamingException</span> ex<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Do something with the exception...</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong>Codes Explanation:</strong><br /> Here, the <strong>searchFilter </strong>string is pretty simple by only matching the &#8220;<strong>objectClass</strong>&#8221; as &#8220;<strong><em>person</em></strong>&#8221; and &#8220;<strong>userPrincipalName</strong>&#8221; with the full logon username. The returnAttrs string array is introduced to be used by the <strong>SearchControl </strong>object so that when we retrieve the attributes of the returned records, only the &#8220;<strong>memberOf</strong>&#8221; attribute is returned.</p><p>As it progress and returns the instance of <strong>NamingEnumeration</strong>, we’ll iterate it and retrieve each item as an instance of <strong>SearchResult</strong>. From there, we’ll just get the attribute value and call the <strong>java.lang.String.contains()</strong> method to match the Group Name. Iteration through the <strong>NamingEnumeration </strong>object is required as sometimes, one user may belong to multiple groups. So, taking each &#8220;<strong>memberOf</strong>&#8221; attribute to compare is necessary.</p><p>This way is truly not very reliable and is definitely not a very efficient way, but it does get the job done when circumstances arise.</p><h2>Why Can&#8217;t We Use Wildcard &#8220;*&#8221; On &#8220;memberOf&#8221;?</h2><p>It is tempting to have searchFilter with something like:<br /><pre>
(&(objectClass=person)(userPrincipalName=someone@domain)(memberOf=CN=Some Group Name<strong>*</strong>))
</pre><br /> Unfortunately it doesn’t work like that. Why? Because the attribute &#8220;<strong>memberOf</strong>&#8221; is classified as a <strong>Distinguished Name (DN)</strong> and by the rules of X.500, no wildcard search should be permitted for any attribute type which is a Distinguished Name. The same goes for attribute &#8220;<strong>distinguishedName</strong>&#8220;, &#8220;<strong>member</strong>&#8221; and many other more. Any other attribute types beside Distinguished Name are wildcard supported.</p><p>It is irritating, if not, frustrating at first. But by knowing this fact, it allows you to pre-plan your development approach before you hit a bumper like this.</p><h2>Summary</h2><p>We’ve come to the end of the article and I hope it truly gave you a good kick start your Java/JNDI to Active Directory Server authentication, searching and validating of OU, groups and other attributes as a means to aid in information search or access control of your software application. Just make sure you keep your LDAP tools handy and always remember that wildcard doesn’t work on attributes which are type Distinguished Name. Pre-plan your development approach and you should do well.</p><p>Wishing all of you success in coding and thank you for reading.</p><h3>Related Articles:</h3><ul><li><a href="http://www.developerscrappad.com/1052/windows/active-directory/quick-note-unable-to-perform-ldap-wildcard-search-on-windows-active-directory/">Quick Note: Unable To Perform LDAP Wildcard &#8220;*&#8221; Search On Windows Active Directory</a></li><li><a href="http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/">Java LDAP/JNDI: 2 Ways Of Decoding And Using The objectGUID From Windows Active Directory</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/963/windows/active-directory/java-jndi-ldap-windows-active-directory-authentication-organizational-unit-group-and-other-information-access/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>MySQL Cluster NDB 7.2 on Solaris 10 Part 3 – Testing The Cluster</title><link>http://www.developerscrappad.com/918/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-3-testing-the-cluster/</link> <comments>http://www.developerscrappad.com/918/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-3-testing-the-cluster/#comments</comments> <pubDate>Sat, 22 Sep 2012 09:35:08 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[Cluster NDB 7.2]]></category> <category><![CDATA[Database]]></category> <category><![CDATA[Solaris 10]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=918</guid> <description><![CDATA[We are back again to have fun with our cluster that we&#8217;ve setup written in our previous articles on Part 1: MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure and Part 2: MySQL Cluster NDB 7.2 on Solaris 10 Part 2 – Starting, Distributed Synchronized Users Management [...]]]></description> <content:encoded><![CDATA[<p>We are back again to have fun with our cluster that we&#8217;ve setup written in our previous articles on Part 1: <a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure</a> and Part 2: <a href="http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/">MySQL Cluster NDB 7.2 on Solaris 10 Part 2 – Starting, Distributed Synchronized Users Management And Stopping The Cluster</a>. This article, which is the Part 3 of the series &#8211; MySQL Cluster NDB on Solaris 10, and is a continuation from the previous parts. Here, we are going to discuss how we can carry out simple test to the cluster to make sure that it works as it should intended to be. Before we begin, please be inform that the cluster environment in this tutorial is tightly coupled with <a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">Part 1</a> and <a href="http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/">Part 2</a> of the tutorial, so if you haven&#8217;t read them and if you are interested in building your own MySQL Cluster, please complete <a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">Part 1</a> and <a href="http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/">Part 2</a> before reading the below.<br /> <span id="more-918"></span><br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/662169_29387955.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/662169_29387955-150x150.jpg?e83a2c" alt="" title="662169_29387955" width="150" height="150" class="alignnone size-thumbnail wp-image-922" style="display: none;" /></a><br /> Before you continue, please make sure that all servers listed in <a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">Part 1</a> of the tutorial is started, if you can&#8217;t remember how to start them, just refer to <a href="http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/">Part 2</a> of the tutorial. Do check the Management Server&#8217;s console to see if all servers are started properly. Once everything is fine, we&#8217;ll go through certain tests below including data consistency for fail-over. Just keep in mind that this is just a very simple test (only with INSERT statements) to check if the cluster is functioning. No stress test or other complicated tests are involved for now. Just very minimal checks.</p><h2>Preparing The Test Database and Test Table</h2><p>The first task that we need to do is to setup a database and the relevant test table to perform the test procedure. Here, you may use the Management Server mysqlmngserv&#8217;s (192.168.2.50) terminal any other terminal to perform the commands, as long as there is a MySQL client on the machine.</p><p>The database that we&#8217;ll create is call <strong>NDB_TEST</strong> and the table that will be created is call <strong>NDB_TEST_TABLE</strong>. And we will create these tables with the &#8220;<strong><em>world_dba</em></strong>&#8221; user created in the MySQL database previously. Let&#8217;s get started by connecting to the terminal of the Management Server mysqlmngserv (192.168.2.50) as the &#8220;<strong><em>mysql</em></strong>&#8221; user:</p><ol><li>Change the working directory to /opt/mysql/mysql/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;</li><li>To create the database, let&#8217;s connect to mysqlserv1 (192.168.2.51)&#8217;s SQL Node by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.51</em></strong>&#8220;.</li><li>Once you have log into the mysql&gt; prompt, type &#8220;<strong><em>CREATE DATABASE NDB_TEST;</em></strong>&#8220;.</li><li>Instruct MySQL to use the newly created database by typing &#8220;<strong><em>USE NDB_TEST;</em></strong>&#8220;.</li><li>Now, create the table with the below script on the mysql&gt; prompt:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> NDB_TEST_TABLE</li><li><span style="color: #66cc66;">&#40;</span></li><li>	PK <span style="color: #993333; font-weight: bold;">BIGINT</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span></li><li>	ACTIVITY_TS <span style="color: #993333; font-weight: bold;">TIMESTAMP</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #993333; font-weight: bold;">CURRENT_TIMESTAMP</span><span style="color: #66cc66;">,</span></li><li>	ACTIVITY_LOG TEXT <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span></li><li>	<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>PK<span style="color: #66cc66;">&#41;</span></li><li><span style="color: #66cc66;">&#41;</span> Engine<span style="color: #66cc66;">=</span>NDBCLUSTER;</li></ol></div></pre></li></ol><p>The <strong>NDB_TEST_TABLE</strong> is a simple table containing with column <strong>ACTIVITY_LOG</strong> as a column for message that we&#8217;ll enter and the <strong>ACTIVITY_TS</strong> as the timestamp field when a record is inserted. It will be populated with the timestamp at the time of insertion.</p><h2>Test 1: Test When All Servers Are Up</h2><p>Perform this as the &#8220;<strong><em>mysql</em></strong>&#8221; OS user on the Management Server <strong><em>mysqlmngserv </em></strong>(192.168.2.50):</p><ol><li>Change the working directory to /opt/mysql/mysql/bin &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>Just do a brief check on all the servers&#8217; statuses by typing &#8220;<strong><em>./ndb_mgm -e show</em></strong>&#8220;, you shoule be getting the output like below:<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32   @192.168.2.52  (mysql-5.5.27 ndb-7.2.8)
</pre></p><p>With this we are sure that all servers within the cluster are now up and running.</li><li>While still at the terminal&#8217;s command prompt, use the MySQL client to login to the first SQL Node <strong><em>mysqlserv1 </em></strong>(192.168.2.51) by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.51</em></strong>&#8220;.</li><li>At the mysql&gt; prompt, perform the below command:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">USE</span> NDB_TEST;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> NDB_TEST_TABLE <span style="color: #66cc66;">&#40;</span>ACTIVITY_LOG<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Inserted when all servers are up!'</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> NDB_TEST_TABLE <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> ACTIVITY_TS;</li></ol></div></pre></p><p>You should be able to see the below output:<br /><pre style="font-family: monospace;">
+----+---------------------+-----------------------------------+
| PK | ACTIVITY_TS         | ACTIVITY_LOG                      |
+----+---------------------+-----------------------------------+
|  1 | 2012-09-19 13:11:26 | Inserted when all servers are up! |
+----+---------------------+-----------------------------------+
</pre></li></ol><p>With this, the first test had passed.</p><h2>Test 2: Test When mysqlserv1 Is Offline And mysqlserv2 Is Online</h2><p>Perform this as the &#8220;<strong>mysql</strong>&#8221; OS user on the Management Server <strong>mysqlmngserv </strong>(192.168.2.50):</p><ol><li>Change the working directory to /opt/mysql/mysql/bin &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>In the terminal&#8217;s command prompt, type the following to shutdown SQL Node 1 <strong><em>mysqlserv1 </em></strong>(192.168.2.51) remotely: &#8220;<strong><em>./mysqladmin -u world_dba -pworldpasswd -h 192.168.2.51 shutdown</strong></em>&#8220;.</li><li>To make sure that SQL Node 1 is offline, just check through &#8220;<strong><em>./ndb_mgm -e show</em></strong>&#8221; on the terminal of the Manage Server and you should be able to see something like the below:<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31 (not connected, accepting connect from 192.168.2.51)
id=32   @192.168.2.52  (mysql-5.5.27 ndb-7.2.8)
</pre></li><li>While still at the terminal command prompt, use the MySQL client to connect to SQL Node 2 <strong><em>mysqlserv2 </em></strong>(192.168.2.52) by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.52</em></strong>&#8220;.</li><li>Once you have log into the mysql&gt; prompt, enter the following command:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">USE</span> NDB_TEST;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> NDB_TEST_TABLE <span style="color: #66cc66;">&#40;</span>ACTIVITY_LOG<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Inserted when mysqlserv1 is down'</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> NDB_TEST_TABLE <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> ACTIVITY_TS;</li></ol></div></pre></p><p>You should be able to see the following output:<br /><pre style="font-family: monospace;">
+----+---------------------+-----------------------------------+
| PK | ACTIVITY_TS         | ACTIVITY_LOG                      |
+----+---------------------+-----------------------------------+
|  1 | 2012-09-19 13:11:26 | Inserted when all servers are up! |
|  2 | 2012-09-19 13:15:07 | Inserted when mysqlserv1 is down  |
+----+---------------------+-----------------------------------+
</pre></ol><h2>Test 3: Test When mysqlserv1 Is Online And mysqlserv2 Is Offline</h2><p>In this test, we&#8217;ll activate SQL Node 1 and stop the SQL Node 2, insert a record through SQL Node 2 and see if the data is consistent.</p><p>First, we have to get SQL Node 1 <strong><em>mysqlserv1 </em></strong>(192.168.2.51) up and running again, then shutdown SQL Node 2 <strong><em>mysqlserv2 </em></strong>(192.168.2.52). Follow the below instruction:</p><p>Log into the terminal of mysqlser1 (192.168.2.52) as the &#8220;<strong><em>mysql</em></strong>&#8221; user:</p><ol><li>Change the working directory to /opt/mysql/mysql/bin &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>Type &#8220;<strong><em>./mysqld &#8211;defaults-file=/opt/mysql/mysql/current-running-config-files/mysql.mysqlserv1.cnf &#038;</em></strong>&#8221; to bring back mysqlserv1</li><li>Then in the same terminal and working directory, type &#8220;<strong><em>./mysqladmin -u world_dba -pworldpasswd -h 192.168.2.52 shutdown</em></strong>&#8221; to shutdown the mysqlserv2 SQL Node.</li></ol><p>For status checking, just switch the terminal back to Management Server and perform a &#8220;<strong><em>ndb_mgm -e show</em></strong>&#8221; command, you should be able to see the below output:<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32 (not connected, accepting connect from 192.168.2.52)
</pre></p><p>In the same terminal, we have to connect to mysqlserv1 through the MySQL client and perform the below:</p><ol><li>In the working directory /opt/mysql/mysql/bin, connect to mysqlserv1 by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.51</em></strong>&#8220;.</li><li>When you reach the mysql&gt; prompt, perform the below command:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">USE</span> NDB_TEST;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> NDB_TEST_TABLE <span style="color: #66cc66;">&#40;</span>ACTIVITY_LOG<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Inserted when mysqlserv2 is down'</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> NDB_TEST_TABLE <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> ACTIVITY_TS;</li></ol></div></pre><br /> You should be able to see the below output:<br /><pre style="font-family: monospace;">
+----+---------------------+-----------------------------------+
| PK | ACTIVITY_TS         | ACTIVITY_LOG                      |
+----+---------------------+-----------------------------------+
|  1 | 2012-09-19 13:11:26 | Inserted when all servers are up! |
|  2 | 2012-09-19 13:15:07 | Inserted when mysqlserv1 is down  |
|  3 | 2012-09-19 13:26:03 | Inserted when mysqlserv2 is down  |
+----+---------------------+-----------------------------------+
</pre></li></ol><p>Once you&#8217;ve completed Test 3, we are quite sure that both the SQL Nodes <strong><em>mysqlserv1 </em></strong>and <strong><em>mysqlserv2 </em></strong>are indeed connected to the specify data nodes in the configuration and the Management Server is working in coordinating the data synchronization.</p><p>So in future, any external application which are to connect to the database could switch between mysqlserv1 or mysqlserv2 in a load-balanced round robin way.</p><h2>Test 4: Test When mysqldn1 &#8211; NodeId 11 (192.168.2.53) And mysqldn3 &#8211; NodeId 13 (192.168.2.55) Is Offline</h2><p>Things will get interesting from here on. Instead of taking turns to shut down the SQL Nodes, in this test, we&#8217;ll shutdown the two of the Data Nodes to see if the data truly syncs and if data node fail-over actually works. Just follow the below (just make sure all SQL Nodes are back and alive before doing this).</p><p>Log into the Management Server <strong><em>mysqlmngserv </em></strong>(192.168.2.50) as the &#8220;<strong><em>mysql</em></strong>&#8221; user and perform the following:</p><ol><li>Change the working directory to /opt/mysql/mysql/bin &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>We&#8217;ll perform the data node shutdown through the management console. Type &#8220;<strong><em>./ndb_mgm</em></strong>&#8221; in the command prompt.</li><li>Through the ndb_mgm&#038;gt: prompt, type &#8220;<strong><em>show</em></strong>&#8221; to show the list of data nodes.</li><li>To stop Data Node 1 &#8211; mysqldn1 (192.168.2.53), NodeId: 11, just type &#8220;<strong><em>11 stop</em></strong>&#8220;. Wait for the data node to stop with response like:<br /><pre>
ndb_mgm> 11 stop
Node 11: Node shutdown initiated
Node 11 has shutdown.
</pre></li><li>Then, to stop Data Node 3 &#8211; mysqldn3 (192.168.2.55), NodeId: 13, just type &#8220;<strong><em>13 stop</em></strong>&#8220;. Wait for the data node to stop with response like:<br /><pre>
ndb_mgm> 13 stop
Node 13: Node shutdown initiated
Node 13 has shutdown.
</pre></li><li>Type &#8220;show&#8221; again, and you should see the below:<br /><pre style="font-family: monospace;">
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11 (not connected, accepting connect from 192.168.2.53)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=13 (not connected, accepting connect from 192.168.2.55)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32   @192.168.2.52  (mysql-5.5.27 ndb-7.2.8)
</pre></li><li>So now, when both NodeId 11 and NodeId 13 are down, type &#8220;<strong><em>exit</em></strong>&#8221; on the ndb_mgm&gt; prompt to exit the console and connect the MySQL client to <strong><em>mysqlserv1 </em></strong>192.168.2.51 by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.51</em></strong>&#8220;.</li><li>In the mysql&#038;gt: prompt, just enter the below commands:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">USE</span> NDB_TEST;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> NDB_TEST_TABLE <span style="color: #66cc66;">&#40;</span>ACTIVITY_LOG<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Inserted when Data Node 1 (NodeId 11) and Data Node 3 (NodeId 13) is down'</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> NDB_TEST_TABLE <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> ACTIVITY_TS;</li></ol></div></pre></p><p>This will result the following output:<br /><pre style="font-family: monospace; font-size: 9px;">
+----+---------------------+---------------------------------------------------------------------------+
| PK | ACTIVITY_TS         | ACTIVITY_LOG                                                              |
+----+---------------------+---------------------------------------------------------------------------+
|  1 | 2012-09-19 13:11:26 | Inserted when all servers are up!                                         |
|  2 | 2012-09-19 13:15:07 | Inserted when mysqlserv1 is down                                          |
|  3 | 2012-09-19 13:26:03 | Inserted when mysqlserv2 is down                                          |
|  4 | 2012-09-19 13:32:44 | Inserted when Data Node 1 (NodeId 11) and Data Node 3 (NodeId 13) is down |
+----+---------------------+---------------------------------------------------------------------------+
</pre></li></ol><p>If you see the above output, that shows the cluster could still perform transaction on the database even without two functioning data nodes.</p><h2>Test 5: Test When mysqldn2 &#8211; NodeId 12 (192.168.2.54) And mysqldn4 &#8211; NodeId 14 (192.168.2.56) Is Offline</h2><p>Before we give this test a try, just make sure that the previously shutdown data nodes are back alive again. You can do this by:</p><ol><li>Log into mysqldn1 (192.168.2.53) through the terminal as &#8220;<strong><em>mysql</em></strong>&#8221; user.</li><li>Change the working directory to /opt/mysql/mysql/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>In the command prompt, type &#8220;<strong><em>./ndbd -c 192.168.2.50:1186</em></strong>&#8221; to connect the data node to the Management Server at 192.168.2.50. Notice that now, this command doesn&#8217;t require the flag &#8220;<strong><em>&#8211;initial</em></strong>&#8220;. Do check on the MySQL documentation for the purpose of initial flag. Now as we start the data node again for the next time, we don&#8217;t need that. But if you are starting the data node for the first time, please have the &#8220;<strong><em>&#8211;initial</em></strong>&#8221; flag.</li><li>Wait for it to be connected, then repeat step 1 to 3 with mysqldn3 at 192.168.2.55</li></ol><p>So, once both mysqldn1 NodeId 11 and mysqldn3 NodeId 13 is up and running again, its time to shutdown mysqldn2 NodeId 12 and mysqldn4 NodeId 14. Just perform this with the same procedure as mentioned in Test 4, access the Management Server&#8217;s ndb_mgm&gt; console and type &#8220;<strong><em>12 stop</em></strong>&#8221; and &#8220;<strong><em>14 stop</em></strong>&#8220;. When both the data nodes had stopped, check the status again with &#8220;<strong><em>./ndb_mgm -e show</em></strong>&#8221; and you should see:<br /><pre>
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12 (not connected, accepting connect from 192.168.2.54)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14 (not connected, accepting connect from 192.168.2.56)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32   @192.168.2.52  (mysql-5.5.27 ndb-7.2.8)
</pre></p><p>Once NodeId 12 and NodeId 14 had been shutdown, perform the following:</p><ol><li>Type &#8220;<strong><em>exit</em></strong>&#8221; on the ndb_mgm&gt; prompt to exit the console and connect the MySQL client to mysqlserv1 192.168.2.51 by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.51</em></strong>&#8220;.</li><li>In the mysql&#038;gt: prompt, just enter the below commands:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li><span style="color: #993333; font-weight: bold;">USE</span> NDB_TEST;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> NDB_TEST_TABLE <span style="color: #66cc66;">&#40;</span>ACTIVITY_LOG<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Inserted when Data Node 2 (NodeId 12) and Data Node 4 (NodeId 14) is down'</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> NDB_TEST_TABLE <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> ACTIVITY_TS;</li></ol></div></pre></p><p>This will result the following output:<br /><pre style="font-family: monospace; font-size: 9px;">
+----+---------------------+---------------------------------------------------------------------------+
| PK | ACTIVITY_TS         | ACTIVITY_LOG                                                              |
+----+---------------------+---------------------------------------------------------------------------+
|  1 | 2012-09-19 13:11:26 | Inserted when all servers are up!                                         |
|  2 | 2012-09-19 13:15:07 | Inserted when mysqlserv1 is down                                          |
|  3 | 2012-09-19 13:26:03 | Inserted when mysqlserv2 is down                                          |
|  4 | 2012-09-19 13:32:44 | Inserted when Data Node 1 (NodeId 11) and Data Node 3 (NodeId 13) is down |
|  5 | 2012-09-19 13:38:34 | Inserted when Data Node 2 (NodeId 12) and Data Node 4 (NodeId 14) is down |
+----+---------------------+---------------------------------------------------------------------------+
</pre></ol><p>Once you&#8217;ve gotten the above test result, it is quite safe to say that the cluster is working well as it is intended to be.</p><h2>Final Test: Test When All Servers and Data Nodes Are Up Again</h2><p>Just to wrap things up, let&#8217;s put back every shutdown data nodes to live and restore the cluster to its normal working order. In the previous test, we&#8217;ve shutdown NodeId 12 and NodeId 14, so just switch to mysqldn2 (192.168.2.54)&#8217;s terminal and reconnect the data node to the Manage Server again with &#8220;<strong><em>ndbd -c 192.168.2.50:1186</em></strong>&#8220;, do the same to mysqldn4 (192.168.2.56). Verify with &#8220;<strong><em>ndb_mgm -e show</em></strong>&#8221; command on the Management Server and you should get back the below result:<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32   @192.168.2.52  (mysql-5.5.27 ndb-7.2.8)
</pre></p><p>Perform the final test below with the &#8220;<strong><em>mysql</em></strong>&#8221; user on the Management Server:</p><ol><li>Assuming that you are at the working path of &#8220;<strong><em>/opt/mysql/mysql/bin</em></strong>&#8220;, connect the MySQL client to mysqlserv1 (192.168.2.51) by typing &#8220;<strong><em>./mysql -u world_dba -pworldpasswd -h 192.168.2.51</em></strong>&#8220;.</li><li>When you reach the mysql&gt; prompt, type the following command:<br /><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow"><ol><li></li><li><span style="color: #993333; font-weight: bold;">USE</span> NDB_TEST;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> NDB_TEST_TABLE <span style="color: #66cc66;">&#40;</span>ACTIVITY_LOG<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'Inserted all servers are up and living again. Test Completed!'</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #66cc66;">*</span> <span style="color: #993333; font-weight: bold;">FROM</span> NDB_TEST_TABLE <span style="color: #993333; font-weight: bold;">ORDER</span> <span style="color: #993333; font-weight: bold;">BY</span> ACTIVITY_TS;</li></ol></div></pre></li><li>You should be able to see the below output:<br /><pre style="font-family: monospace; font-size: 9px;">
+----+---------------------+---------------------------------------------------------------------------+
| PK | ACTIVITY_TS         | ACTIVITY_LOG                                                              |
+----+---------------------+---------------------------------------------------------------------------+
|  1 | 2012-09-19 13:11:26 | Inserted when all servers are up!                                         |
|  2 | 2012-09-19 13:15:07 | Inserted when mysqlserv1 is down                                          |
|  3 | 2012-09-19 13:26:03 | Inserted when mysqlserv2 is down                                          |
|  4 | 2012-09-19 13:32:44 | Inserted when Data Node 1 (NodeId 11) and Data Node 3 (NodeId 13) is down |
|  5 | 2012-09-19 13:38:34 | Inserted when Data Node 2 (NodeId 12) and Data Node 4 (NodeId 14) is down |
|  6 | 2012-09-19 13:41:58 | Inserted all servers are up and living again. Test Completed!             |
+----+---------------------+---------------------------------------------------------------------------+
</pre></li></ol><p>With this, we can conclude that the cluster, at least for the data persisting aspect is running fine.</p><h2>Summary</h2><p>We have now come to the end of this three part series on MySQL Cluster NDB 7.2 on Solaris 10. although it is just a mini series on a relatively simple cluster configuration but hopefully, you are able to get the idea of how to successfully build and deploy a MySQL Cluster environment on the Solaris 10 OS, at least knowing the minimal configuration requirement for the .cnf and config.ini files, the data directories, using the Management Server for certain cluster controls, enabling of synchronized distributed user management and shared privileges  and finally, brief testing of the cluster to see if it is truly functioning as it is intended to be. The journey doesn&#8217;t end here though as there are many other aspects that the learning curve consist of including cluster replication, backups, restores, optimization, etc. which is well worth your time to understand if you are serious about maintaining the cluster(s).</p><p>Well, wishing you many success in your future MySQL cluster deployment and hope you&#8217;ve enjoyed reading our articles.</p><p>Thank you.</p><h3>Related Articles</h3><ul><li><a href="http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/">MySQL Cluster NDB 7.2 on Solaris 10 Part 2 – Starting, Distributed Synchronized Users Management And Stopping The Cluster</a></li><li><a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure</a></li><li><a href="http://www.developerscrappad.com/172/database/mysql/installing-mysql-5-0-on-solaris-10/">Installing MySQL 5.0 on Solaris 10</a></li><li><a href="http://www.developerscrappad.com/185/database/mysql/installing-mysql-5-5-on-solaris-10/">Installing MySQL 5.5 on Solaris 10</a><li><a href="http://www.developerscrappad.com/210/database/mysql/how-to-boot-mysql-5-5-on-solaris-10-during-system-startup/">How To Boot MySQL 5.5 On Solaris 10 During System Startup</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/918/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-3-testing-the-cluster/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>MySQL Cluster NDB 7.2 on Solaris 10 Part 2 – Starting, Distributed Synchronized Users Management And Stopping The Cluster</title><link>http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/</link> <comments>http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/#comments</comments> <pubDate>Tue, 18 Sep 2012 07:32:46 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[Cluster NDB 7.2]]></category> <category><![CDATA[Database]]></category> <category><![CDATA[Solaris 10]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=839</guid> <description><![CDATA[This is the continuation from the previous part of the tutorial MySQL Cluster NDB 7.2 on Solaris 10 Part 1 &#8211; How To Install, Setup and Configure. If you have not read it, it is highly recommended that you read Part 1 before coming on this. Anyway, this part is all about how you can [...]]]></description> <content:encoded><![CDATA[<p>This is the continuation from the previous part of the tutorial <a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">MySQL Cluster NDB 7.2 on Solaris 10 Part 1 &#8211; How To Install, Setup and Configure</a>. If you have not read it, it is highly recommended that you read Part 1 before coming on this. Anyway, this part is all about how you can start the servers within the cluster, enable synchronization of users across servers and stopping the cluster gracefully. The cluster environment is tightly coupled with the previous part of the tutorial. If you came from there, just read on.<br /> <span id="more-839"></span><br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/1344508_94522719.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/1344508_94522719-150x150.jpg?e83a2c" alt="" title="1344508_94522719" width="150" height="150" class="alignnone size-thumbnail wp-image-888" style="display: none;" /></a></p><h2>Gentlemen, Start Your Engines!</h2><p>This is the moment of truth, after all the laborious efforts in installing and configuring the servers, it is time to put the cluster in action. But before you do that, there is a sequence to which server to start. The rule of thumb is always to start the management server, follow by the data nodes, then the SQL Nodes as the last to be started.</p><h3>Starting the Management Server</h3><p>Perform this as the &#8220;<strong>mysql</strong>&#8221; user on the Management Server <strong><em>mysqlmngserv</em></strong> (192.168.2.50):</p><ol><li>Log into the terminal and switch to the user &#8220;mysql&#8221; by typing &#8220;<strong><em>su mysql</em></strong>&#8220;.</li><li>Change the working directory to /opt/mysql/mysql/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>Start the Management Server by typing: &#8220;<strong><em>./ndb_mgmd -f /opt/mysql/mysql/current-running-config-files/config.ini &#8211;initial</em></strong>&#8220;.</li><li>You should be able to see the output like:<br /><pre>
...
# ./ndb_mgmd -f /opt/mysql/mysql/current-running-config-files/config.ini --initial
MySQL Cluster Management Server mysql-5-5-27 ndb-7.2.8
# 
</pre><br /> It will return to the prompt if is was started successfully.</p><li>Next, check the status of all the servers involve in the cluster by typing &#8220;<strong><em>./ndb_mgm -e show</em></strong>&#8220;, you should get something like the below:<br /><pre>
$ ./ndb_mgm -e show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11 (not connected, accepting connect from 192.168.2.53)
id=12 (not connected, accepting connect from 192.168.2.54)
id=13 (not connected, accepting connect from 192.168.2.55)
id=14 (not connected, accepting connect from 192.168.2.56)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31 (not connected, accepting connect from 192.168.2.51)
id=32 (not connected, accepting connect from 192.168.2.52)
</pre></li></ol><p>As you can see from the terminal, the management server was successfully started; leaving the rest of the data nodes unconnected and of course the SQL Nodes are not running now.</p><h3>Starting and Connecting The Data Nodes</h3><p>The next step to do after starting the Management Server is to start and connect the data nodes. To do this just follow the below:</p><p>Please perform this one by one of <strong>ONLY </strong>the data node servers, from <strong><em>mysqldn1 </em></strong>(192.168.2.53) to <strong><em>mysqldn4 </em></strong>(192.168.2.56). You may first start with <strong><em>mysqldn1 </em></strong>(192.168.2.53). Please perform the below as the &#8220;<strong>mysql</strong>&#8221; user:</p><ol><li>Log into the shell and switch to the user &#8220;mysql&#8221; by typing &#8220;<strong><em>su mysql</em></strong>&#8220;.</li><li>Change the working directory to /opt/mysql/mysql/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>Connect the data nodes to the management server by typing &#8220;<strong><em>./ndbd &#8211;initial -c 192.168.2.50:1186</em></strong>&#8220;. <strong>The 192.168.2.50 is the IP of the Management Server (mnysqlmngserv)</strong> and the 1186 is actually the default port for the connection. This command actually starts and connects the data node to the management server both at the same time.</li><li>Switch back to the terminal of the <strong>Management Server (mysqlmngserv)</strong>, change the working directory to <strong><em>/opt/mysql/mysql/bin</em></strong> and check the status again by typing &#8220;<strong><em>./ndb_mgm -e show</em></strong>&#8220;.</li><li>You would be getting the below output:<br /><pre>
$ ./ndb_mgm -e show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, starting, Nodegroup: 0)
id=12 (not connected, accepting connect from 192.168.2.54)
id=13 (not connected, accepting connect from 192.168.2.55)
id=14 (not connected, accepting connect from 192.168.2.56)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31 (not connected, accepting connect from 192.168.2.51)
id=32 (not connected, accepting connect from 192.168.2.52)
</pre><br /> The connecting data node(s) will have the status like &#8220;&#8230;mysql-5.5.27 ndb-7.2.8, starting, &#8230;&#8221;. Notice that there is a word &#8220;<em>starting</em>&#8221; in the status. Just be mindful that it will take sometime for the data node to get started.</li><li>Never mind about waiting. Just move on and repeat step 1 to 4 for <strong>mysqldn2 </strong>(192.168.2.54), <strong>mysqldn3 </strong>(192.168.2.55) and <strong>mysqldn4 </strong>(192.168.2.56) and you will eventually get the following output when you check the Management Server&#8217;s status with &#8220;<strong><em>ndb_mgm -e show</em></strong>&#8220;.<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31 (not connected, accepting connect from 192.168.2.51)
id=32 (not connected, accepting connect from 192.168.2.52)
</pre></li></ol><h3>Starting the MySQL Server (SQL Nodes)</h3><p>Now, for the final part of the cluster, follow the below instructions to start both of the SQL Nodes. Just perform this as the &#8220;<strong>mysql</strong>&#8221; user for <strong>ONLY </strong>both the <strong><em>mysqlserv1 </em></strong>(192.168.2.51) and <strong><em>mysqlserv2 </em></strong>(192.168.2.52). You may first do this on <strong><em>mysqlserv1 </em></strong>(192.168.2.51):</p><ol><li>Log into the terminal and switch to the &#8220;<strong><em>mysql</em></strong>&#8221; user by typing &#8220;<strong><em>su mysql</em></strong>&#8220;</li><li>Change the working directory to /opt/mysql/mysq/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>Start the MySQL server by typing &#8220;<strong><em>./mysqld &#8211;defaults-file=/opt/mysql/mysql/current-running-config-files/mysql.mysqlserv1.cnf &#038;</em></strong>&#8220;. The <strong><em>&#8211;defaults-file</em></strong> flag will tell the SQL node to read the specific .cnf file from the directory <strong><em>current-running-config-files</em></strong>. The is the time when the <strong><em>mysql.mysqlserv1.cnf</em></strong> file created in Part 1 of the tutorial is put to use.</li><li>To check the status, you may always switch back to the Management Server <strong>mysqlmngserv</strong> (192.168.2.50) to see the status with the command &#8220;<strong><em>ndb_mgm -e show</em></strong>&#8220;. You should be getting an output like below:<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32 (not connected, accepting connect from 192.168.2.52)
</pre></li><li>For the next SQL Node <strong>mysqlserv2 </strong>(192.168.2.52), just switch to the server&#8217;s terminal repeat step 1 to 4. The command to start mysqlserv2 is &#8220;<strong><em>./mysqld &#8211;defaults-file=/opt/mysql/mysql/current-running-config-files/mysql.mysqlserv2.cnf &#038;</em></strong>&#8220;. Just make sure you get the value for the <strong><em>&#8211;defaults-file</em></strong> parameter correct.</li></ol><p>Finally, to see if all servers have started correctly, please switch back to the Management Server <strong>mysqlmngserv </strong>(192.168.2.50) and check with the command &#8220;<strong><em>ndb_mgm -e show</em></strong>&#8220;, you should be able to see the below output:<br /><pre>
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @192.168.2.53  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0, Master)
id=12   @192.168.2.54  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 0)
id=13   @192.168.2.55  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)
id=14   @192.168.2.56  (mysql-5.5.27 ndb-7.2.8, Nodegroup: 1)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.2.50  (mysql-5.5.27 ndb-7.2.8)

[mysqld(API)]   2 node(s)
id=31   @192.168.2.51  (mysql-5.5.27 ndb-7.2.8)
id=32   @192.168.2.52  (mysql-5.5.27 ndb-7.2.8)
</pre></p><h2>Enabling Distributed Synchronized User Management On MySQL Cluster NDB</h2><p>Before you go ahead connecting and testing the cluster, we would like to bring to your attention that whatever user(s) that you had or are about to create on one MySQL server is <strong>NOT</strong> portable across the cluster by default. But there is a solution to it and this section will guide you in enabling synchronization of users across servers within the cluster. Let&#8217;s be patient and go through the instruction below, as it is well worth your effort.</p><p>Please perform this as the &#8220;<strong><em>mysql</em></strong>&#8221; user on the first SQL Node <strong><em>mysqlserv1 </em></strong>(192.168.2.51):</p><ol><li>When you&#8217;ve log into the terminal, just change the directory to /opt/mysql/mysql/share by tying &#8220;<strong><em>cd /opt/mysql/mysql/share</em></strong>&#8220;.</li><li>If you list the directory with &#8220;ls&#8221; command, you should be able to see a file named &#8220;<strong>ndb_dist_priv.sql</strong>&#8220;. This script is to enable the cluster to create tables of engine NDB type for the storage of users&#8217; info across all servers in the cluster.</li><li>To run the <strong>ndb_dist_priv.sql</strong> file, change the directory to /opt/mysql/mysql/bin with &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8221; and type &#8220;<strong><em>./mysql -u root < ../share/ndb_dist_priv.sql</em></strong>&#8220;. This will load a couple of stored procedures into the database, which is to be used to perform the synchronization of users.<li>Next, you have to connect to the SQL node by typing &#8220;<strong><em>mysql -u root</em></strong>&#8221; and when it comes to the <em>mysql&gt;</em> prompt, just type: &#8220;<strong><em>CALL mysql.mysql_cluster_move_privileges();</em></strong>&#8220;</li><li>While still at the <em>mysql&gt;</em> prompt, just check on the conversion status by keying in a query &#8220;<strong><em>SELECT CONCAT(&#8216;Conversion &#8216;, IF(mysql.mysql_cluster_privileges_are_distributed(), &#8216;succeeded&#8217;, &#8216;failed&#8217;), &#8216;.&#8217;) AS Result;</em></strong>&#8221; you should be getting an output like:<br /><pre style="font-family: monospace;">
+-----------------------+
| Result                |
+-----------------------+
| Conversion succeeded. |
+-----------------------+
1 row in set (0.11 sec)
</pre></li><li>Please, you <strong>MUST </strong>repeat step 1 to 5 for mysqlserv2 (192.168.2.52). DO NOT MISS THIS STEP! And if we have any additional SQL Nodes to be added into the cluster in future, perform step 1 to 5 as well.</li></ol><p>Once you&#8217;ve done the above, any user that you create in future will automatically be available throughout all the registered SQL Nodes. You may do the below to create a user &#8220;<strong><em>world_dba</em></strong>&#8221; with the password &#8220;<strong><em>worldpasswd</em></strong>&#8220;. We&#8217;ll be using <strong><em>world_dba</em></strong> to do our dirty works instead of the <strong><em>root</em></strong> user. Just connect to the database with &#8220;<strong><em>mysql -u root</em></strong>&#8221; on any of the <strong>SQL Nodes</strong> (either mysqlserv1 192.168.2.51 or mysqlserv2 192.168.2.52) and do the following on the mysql> prompt:</p><p><pre>
CREATE USER 'world_dba'@'localhost' IDENTIFIED BY 'worldpasswd';
CREATE USER 'world_dba'@'%' IDENTIFIED BY 'worldpasswd';
GRANT ALL PRIVILEGES ON *.* TO 'world_dba'@'localhost' WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO 'world_dba'@'%' WITH GRANT OPTION;
</pre></p><h2>Stopping The Cluster Gracefully</h2><p>To stop the server process, most people will search for the <em>mysql</em> process with &#8220;<strong><em>ps -ef | grep mysql</em></strong>&#8221; and send the command &#8220;<strong><em>kill -p &lt;proc no.&gt;</em></strong>&#8221; with the &#8220;<strong>mysql</strong>&#8221; or the &#8220;<strong>root</strong>&#8221; user, but that&#8217;s not very graceful. In order to stop the servers with the proper stop command, just follow the below instruction.</p><h3>How To Stop The MySQL Server (SQL Nodes)</h3><p>To gracefully stop the SQL Nodes, just log into the terminal of the Management Server as the &#8220;<strong><em>mysql</em></strong>&#8221; user:</p><ol><li>Change the working directory to &#8220;/opt/mysql/mysql/bin&#8221; by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;.</li><li>Type &#8220;<strong><em>./mysqladmin -u world_dba -h &lt;IP for SQL Node&gt; shutdown</em></strong>&#8220;. Just replace the IP with either mysqlserv1&#8242;s IP at <strong><em>192.168.2.51</em></strong> or mysqlserv2&#8242;s IP at <strong><em>192.168.2.52</em></strong></li></ol><h3>How To Stop The Data Nodes</h3><p>You can always stop the Data Nodes through the Management Server&#8217;s console. From here, instead of using the IP of the data node, the NodeId is needed in this procedure. Just log into the terminal of the management server as the &#8220;<strong>mysql</strong>&#8221; user and perform the below:</p><ol><li>Change the working directory to /opt/mysql/mysql/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;</li><li>Open the NDB Management console by typing &#8220;<strong><em>./ndb_mgm</em></strong>&#8220;. You&#8217;ll be leaded to the ndb_mgm&gt; prompt.</li><li>You may type &#8220;<strong><em>show</em></strong>&#8221; at the ndb_mgm&gt; prompt to list all data nodes, showing their respective NodeIDs.</li><li>To stop the data node, just type &#8220;<strong><em>&lt;NodeID&gt; stop</em></strong>&#8221; with &lt;NodeID&gt; as the NodeId of the data node. e.g. &#8220;<strong><em>21 stop</em></strong>&#8221; to stop mysqldn1 192.168.2.53 or &#8220;<strong><em>22 stop</em></strong>&#8221; to stop mysqldn2 192.168.2.54 and so on.</li></ol><h3>How To Stop The Management Server</h3><p>Before you stop the Management Server, it is always a good practice to first stop the SQL Nodes before doing so. Anyway, stopping the Management Server is the easiest. Just perform the below as &#8220;<strong>mysql</strong>&#8221; user in the terminal:</p><ol><li>Change the working directory to /opt/mysql/mysql/bin by typing &#8220;<strong><em>cd /opt/mysql/mysql/bin</em></strong>&#8220;</li><li>Open the NDB Management console by typing &#8220;<strong><em>./ndb_mgm</em></strong>&#8220;. You&#8217;ll be leaded to the ndb_mgm&gt; prompt.</li><li>Just type &#8220;<strong><em>shutdown</em></strong>&#8221; in the ndb_mgm&gt; prompt. This command will first shutdown all data nodes controlled by the management server, then the management server itself. It is one of the most convenient way if you want to stop all data nodes and management server together at the same time.</li></ol><h2>To Be Continued&#8230;</h2><p>For the next part of the tutorial, we&#8217;ll discuss more on testing procedures. Since clustering is suppose to promote high availability, we&#8217;ll try to distort the servers within the cluster and see if they do actually synchronize the data when nodes are revived. So, stay tune.</p><h3>Proceed to Part 3:</h3><p><a href="http://www.developerscrappad.com/918/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-3-testing-the-cluster/">MySQL Cluster NDB 7.2 on Solaris 10 Part 3 – Testing The Cluster</a></p><h3>Related Articles:</h3><ul><li><a href="http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/">MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure</a></li><li><a href="http://www.developerscrappad.com/172/database/mysql/installing-mysql-5-0-on-solaris-10/">Installing MySQL 5.0 on Solaris 10</a></li><li><a href="http://www.developerscrappad.com/185/database/mysql/installing-mysql-5-5-on-solaris-10/">Installing MySQL 5.5 on Solaris 10</a><li><a href="http://www.developerscrappad.com/210/database/mysql/how-to-boot-mysql-5-5-on-solaris-10-during-system-startup/">How To Boot MySQL 5.5 On Solaris 10 During System Startup</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>MySQL Cluster NDB 7.2 on Solaris 10 Part 1 – How To Install, Setup and Configure</title><link>http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/</link> <comments>http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/#comments</comments> <pubDate>Tue, 18 Sep 2012 05:27:59 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[MySQL]]></category> <category><![CDATA[Cluster NDB 7.2]]></category> <category><![CDATA[Database]]></category> <category><![CDATA[Solaris10]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=796</guid> <description><![CDATA[If you have landed on this page, we believe you might either had a bumpy ride in getting the MySQL cluster working, or simple feeling tired to read and maneuver around those lengthy documentation or just desperate to get things done in the shortest time span; fret not, we&#8217;ve been there, done that and that [...]]]></description> <content:encoded><![CDATA[<p>If you have landed on this page, we believe you might either had a bumpy ride in getting the MySQL cluster working, or simple feeling tired to read and maneuver around those lengthy documentation or just desperate to get things done in the shortest time span; fret not, we&#8217;ve been there, done that and that is why this this tutorial was written so that it can benefit and shorten the learning curve for all those who are going through the same painful task of installing and getting MySQL Cluster NDB up and running on Solaris 10 in the shortest time.<br /> <span id="more-796"></span><br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/442256_20337880.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/442256_20337880-150x150.jpg?e83a2c" alt="" title="442256_20337880" width="150" height="150" class="alignnone size-thumbnail wp-image-843" style="display: none;"/></a><br /> MySQL Cluster NDB had greatly evolved and this article only focuses on installing the MySQL NDB Cluster Ver. 7.2.x on a bunch of Solaris 10 OS machines. Yes, I&#8217;ve mentioned machine<strong>s</strong> with the &#8220;s&#8221; as clustering / high-availability will only be meaningful if it could be deployed in a distributed environment, thus resulting in substantially fail-safe work horses or 99.9x uptime if that&#8217;s what we are aiming for. This article is not going to dwell too much on terminologies or theories (however, it is required and good to know some of it). If you need those, please read through the official MySQL documentation. But, for now, we just want to get things working as soon as possible.</p><h2>Assumptions and Disclaimer:</h2><ul><li>Readers are assumed to have at least some basic Unix/Linux administrative skills.</li><li>Readers are assumed to have FRESH running copy of Solaris 10 8/11 (u10-ga2).</li><li>Readers are assumed to have NO previously installed MySQL version in the system.</li><li>Readers are assumed to have backed up any critical data before the installation.</li><li>The MySQL Cluster NDB version used for this tutorial is 7.2.8 (GA) Generally Available Release</li><li>Readers are to take full responsibility of any potential software, data, hardware, financial and life damages prior to following this tutorial.</li></ul><h2>What Is Required In A MySQL Cluster?</h2><p>Let&#8217;s go through this very quickly for knowledge sake. In a MySQL clustered environment, what is required are only the 3 components below:</p><div style="margin-left: 30px;"><h3><em>MySQL Server(s) (or known as SQL Node) :- </em></h3><p>These are the few host/IP targets that clients connect to, either directly or in a round robin load-balanced manner. Just like the normal MySQL server, these are the servers that serve the querying of data and persistence of data who’s IPs and hostname should be made visible to connecting clients.</p><h3><em>Data Node(s) :- </em></h3><p>These are the targets where data of the database is stored in a decentralized and distributed manner. It usually comes with pairs of 2, with one master and the rest as replication, so that if a data node is down, the rest will have the most updated data to serve the data needs for the MySQL Servers or SQL Nodes stated above.</p><h3><em>Management Server (or known as Management Node) :- </em></h3><p>With all these decentralizing and distributions of server running about, somebody has to manage the flow of query, data, checking and managing of servers&#8217; uptime status; this is where the Management Server comes into play. The Management Server is just like the conductor in the orchestra, telling musicians what and when to play. In a clustered environment, one Management Server is enough.</p></div><p></p><h2>Servers Preparation:</h2><p>Once you have understood what SQL Nodes, Data Nodes and Management Server are, Without further ado, the server topology in the diagram below is what this tutorial focuses on deploying (just click on the diagram to expend). You may improvise to fit to your needs later; but for now and let&#8217;s get things started with this:</p> <figure> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/mysql_cluster_topology.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/mysql_cluster_topology-300x225.jpg?e83a2c" alt="" title="mysql_cluster_topology" width="300" height="225" class="aligncenter size-medium wp-image-857" /><div style="text-align: center;"><em>The Intended Demo MySQL Cluster Server Topology</em></div><p></a><br /> </figure><p>Here, we have altogether 7 servers involved (2 SQL Nodes, 4 Data Nodes in groups of 2 and 1 management server) each with the same hardware specs of the below. You may always use VMWare, Oracle&#8217;s Virtual Box or other virtualization software to create these virtual machines with the below specs:</p><ul style="list-style-type:square"><li>1 CPU: X86-64 base</li><li>40GB harddisk space</li><li>1GB of RAM</li><li>Installed OS: Solaris 10 8/11 (u10 ga2 for Intel x86-64)</li></ul><p>In my opinion, this hardware (or rather virtual hardware) configuration is just nice and not too superficial for a demo and for actual production implementation.</p><p>All the servers shown in the diagram carries IP, hostname and node IDs listed below:</p><table style="width: 100%;"><thead><th style="width: 30%; padding: 5px 5px 5px 5px;">Server</th><th style="width: 70%; padding: 5px 5px 5px 5px;">Configuration Details</th></thead><tbody><tr><td style="padding: 15px 5px 15px 5px;">Management Server</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqlmngserv, <strong>IP</strong>: 192.168.2.50<br /> <strong>Node ID</strong>: 1<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqlmngserv<br /> <strong>Location of &#8220;config.ini&#8221; file</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/opt/mysql/mysql/current-running-config-files/config.ini</td></tr><tr><td style="padding: 15px 5px 15px 5px;">MySQL Server (SQL Node) 1</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqlserv1, <strong>IP</strong>: 192.168.2.51<br /> <strong>Node ID</strong>: 31<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqlserv1<br /> <strong>Location of &#8220;.cnf&#8221; file</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/opt/mysql/mysql/current-running-config-files/mysql.mysqlserv1.cnf</td></tr><tr><td style="padding: 15px 5px 15px 5px;">MySQL Server (SQL Node) 2</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqlserv2, <strong>IP</strong>: 192.168.2.52<br /> <strong>Node ID</strong>: 32<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqlserv2<br /> <strong>Location of &#8220;.cnf&#8221; file</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/opt/mysql/mysql/current-running-config-files/mysql.mysqlserv2.cnf</td></tr><tr><td style="padding: 15px 5px 15px 5px;">Data Node 1</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqldn1, <strong>IP</strong>: 192.168.2.53<br /> <strong>Node ID</strong>: 11<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqldn1<br /> &#8211; Not Require To Have Specific .cnf or .ini file for now -</td></tr><tr><td style="padding: 15px 5px 15px 5px;">Data Node 2</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqldn2, <strong>IP</strong>: 192.168.2.54<br /> <strong>Node ID</strong>: 12<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqldn2<br /> &#8211; Not Require To Have Specific .cnf or .ini file for now -</td></tr><tr><td style="padding: 15px 5px 15px 5px;">Data Node 3</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqldn3, <strong>IP</strong>: 192.168.2.55<br /> <strong>Node ID</strong>: 13<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqldn3<br /> &#8211; Not Require To Have Specific .cnf or .ini file for now -</td></tr><tr><td style="padding: 15px 5px 15px 5px;">Data Node 4</td><td style="padding: 15px 5px 15px 5px;"> <strong>Hostname</strong>: mysqldn4, <strong>IP</strong>: 192.168.2.56<br /> <strong>Node ID</strong>: 14<br /> <strong>Data Directory Location</strong>:<br />&nbsp;&nbsp;&nbsp;&nbsp;/var/mysql/cluster-data/mysqldn4<br /> &#8211; Not Require To Have Specific .cnf or .ini file for now -</td></tr></tbody></table><p>The contents in the table will be for our reference. Please don&#8217;t worry much about the data directory location, the .cnf files and the config.ini file for now, we&#8217;ll go through that later.</p><div style="margin-left: 30px;"><h3><em>What Is Node ID?</em></h3><p>Have you notice in the diagram and table above that Node ID was mentioned? Node ID is just, well&#8230;IDs for the servers. It is something that is defined by you and it has to be unique throughout the cluster environment. However, there are a set of limits to the NodeId that you can assign:</p><ul><li>For Management Server &#8211; permitted NodeId range: 1 &#8211; 255</li><li>For Data Nodes &#8211; permitted NodeId range: 1 &#8211; 48</li><li>For MySQL Server (SQL Nodes) &#8211; permitted NodeId range: 1 &#8211; 255</li></ul><p>You can set any numbers that you desire as long as it conforms to the ranges listed above. I have assigned several node IDs including the management server. Just for this tutorial, I will have the Data nodes assigned with IDs beginning from 11 and below 30 and SQL nodes beginning from 31 and above, and lastly the management server always with Node ID 1. Remember that Node ID is user-defined and it is required in the configuration.</p><h3><em>What Is Node Group?</em></h3><p>Node Group is simply a logical group of Data Nodes and exist only specifically for the Data Nodes. The Node Group ID is something that we don&#8217;t have to define; but instead, we allow the management server to assign which group the data nodes belong to. We have Node Group 0 and Node Group 1, because typically, these numbers are how the management server assigns to them. So, how does the management server knows how many data nodes are in a group? That depends on how many replicas which was specified for a group to have. We&#8217;ll talk more about that later.</p></div><h2>Installing And Setting Up The Cluster &#8211; Let&#8217;s Rock!</h2><p>Starting from here, it is time for hands on installation and setting up the cluster. Let&#8217;s do this step by step. Please don&#8217;t rush through it. I highly suggest that you double check every step before you move on and you should be able to get the cluster up and running in no time. By the way, keep SSH handy, that&#8217;s a very snappy tool and you&#8217;ll need it for speed.</p><h3>Downloads</h3><p>Please obtain a copy of the latest MySQL Cluster NDB 7.2.x from <a href="http://www.mysql.com/downloads/cluster/" target="_blank">http://www.mysql.com/downloads/cluster/</a>. <strong>YOU NEED THIS FOR ALL THE SERVERS</strong>. For the Solaris 10 MySQL Cluster NDB packages, please click on the select box under “Select Platform:” and select “Sun Solaris“. Choose the appropriate processor architecture of the package (either x86, 32-bit, x86, 64-bit or SPARC). Download the package and save them in an appropriate directory (this tutorial will deal with the file which ends with the Compressed Package &#8211; &#8220;<em>.pkg.gz</em>&#8221; extension, so you should download it instead of the Compressed Tar &#8211; &#8220;<em>.tar.gz</em>&#8221; version. At the time of writing, the latest MySQL Cluster NDB made available was version 7.2.8. The downloadable distribution&#8217;s file name on the download page is named with the format <em>mysql-cluster-gpl-xxx.pkg.gz</em>, just choose the system/processor architecture that is suitable to your system.</p><p>I will use &#8220;<strong><em>/usr/files</em></strong>&#8221; as the directory in all the servers where the <em>mysql-cluster-gpl-xxx.pkg.gz</em> file is placed throughout the tutorial (Please take note that the xxx is the architecture and version number and is to be replaced by the actual text in the file name).</p><h3>Installing The MySQL Cluster NDB 7.2.x Package</h3><p>Please perform the following as the &#8220;<strong>root</strong>&#8221; user. We have to make sure that any other previously running copies of MySQL are to be uninstalled from the system. Just follow the instructions below.</p><p>For <strong>EACH</strong> servers, perform the following as &#8220;<strong>root</strong>&#8221; user:</p><ol><li>Login as &#8220;<strong>root</strong>&#8221; through the terminal.</li><li>The very first thing to do is to create the mysql group and user. To create the group, type: &#8220;<strong><em>groupadd mysql</em></strong>&#8220;.</li><li>Then create the mysql user by typing: &#8220;<strong><em>useradd -g mysql mysql</em></strong>&#8220;.</li><li>To list all the packages, type: &#8220;<strong><em>pkginfo | grep mysql</em></strong>&#8221; at the shell. On my system, I am able to see the below:<br /><pre>
# pkginfo | grep mysql
system	SUNWmysqlr	mysql - MySQL Database Management System (root component)
system	SUNWmysqlt	mysql - MySQL Database Management System (test component)
system	SUNWmysqlu	mysql - MySQL Database Management System (usr component)
</pre></li><li>You may remove the listed packages by typing &#8220;pkgrm <package name>&#8220;. The names of the packages are list at the second column of after executing pkginfo. For my system, I will remove the listed packages by typing &#8220;<strong><em>pkgrm SUNWmysqlr SUNWmysqlt SUNWmysqlu</em></strong>&#8220;.</li><li>Change the directory to the place where you’ve downloaded the mysql-cluster-gpl-xxx.pkg.gz file. (e.g. &#8220;<strong><em>cd /usr/files</em></strong>&#8220;). If the file is compressed by gzip and you can see the .gz extension at the end of the file, you may decompress it by typing &#8220;<strong><em>gzip –d mysql-cluster-gpl-xxx.pkg.gz</em></strong>&#8220;. Once the file had been decompressed, you should be able to see <strong><em>mysql-cluster-gpl-xxx.pkg</em></strong> by typing the list command &#8220;ls&#8221;.</li><li>Install the package by typing &#8220;<strong><em>pkgadd -d mysql-cluster-gpl-xxx.pkg</em></strong>&#8221; and accept all the defaults.</li><li>Repeat step 1 to 7 for <strong>ALL SERVERS</strong> (from 192.168.2.50 to 192.168.2.56).</li></ol><h2>Preparing The Necessary Directories</h2><p>Once the package had been installed, we’ll have to create some directories to store the database’s data and configuration files. The MySQL installation does access to default directories, but it will be better for you to know which and where the data files and the most recent executing running configuration files are stored and accessed. It is easier for modification and maintenance in the long run.</p><div style="margin-left: 30px;"><h3><em>Directory For Configuration Files:</em></h3><p>The directory for configuration files is to allow us to store the most recent running/executing files such as the .ini and the .cnf files. We have to instruct MySQL to read these files from it. For this tutorial, the config files directory should be &#8220;<strong><em>/opt/mysql/mysql/current-running-config-files/</em></strong>&#8220;. Please create this directory only on the <strong>Management Server</strong> (mysqlmngserv 192.168.2.50) and both the <strong>SQL Nodes</strong> (mysqlser1 192.168.2.51 and mysqlserv2 192.168.2.52), we don&#8217;t need this directory for the Data Nodes for now.</p><p>Perform the following as the &#8220;<strong><em>root</em></strong>&#8221; user on only the Management Server and all the SQL Nodes (excluding the Data Nodes) mentioned above:</p><ul><li>In the terminal, type &#8220;<strong><em>mkdir –p /opt/mysql/mysql/current-running-config-files/</em></strong>&#8220;.</li></ul><h3><em>Directory For Core Data Files (With Initialization):</em></h3><p>This directory will be the place where the actual data files are stored for the respective servers. We have to create this for each server one after another with the directory location convention as &#8220;<strong><em>/var/mysql/cluster-data/&lt;hostname&gt;</em></strong>&#8220;. The <strong><em>&lt;hostname&gt;</em></strong> should be the actual hostname for the respective server e.g. &#8220;<strong><em>/var/mysql/cluster-data/mysqldn1</em></strong>&#8220;, &#8220;<strong><em>/var/mysql/cluster-data/mysqldn2</em></strong>&#8220;, etc. This directory format is good to distinguish itself for admins who are managing multiple servers. Other than creating the directory, we have to initialize it and change certain parameters in the <strong><em>/etc/init.d/mysql</em></strong> file.</p><p>Perform the following as the &#8220;<strong><em>root</em></strong>&#8221; user for EACH servers, you may start with the management server 192.168.2.50 and move on to the rest of the servers:</p><ol><li>In the terminal, type “<strong><em>mkdir –p /var/mysql/cluster-data/&lt;hostname&gt;</em></strong>&#8220;. Replace &#8220;<strong><em>&lt;hostname&gt;</em></strong>&#8221; with the server&#8217;s actual hostname, e.g. if you are doing this on the Management Server, the hostname is &#8220;<strong><em>mysqlmngserv</em></strong>&#8221; and the directory name should be &#8220;<strong><em>/var/mysql/cluster-data/mysqlmngserv</em></strong>&#8220;.</li><li>Change the working directory to /opt/mysql/mysql/scripts by typing &#8220;<strong><em>cd /opt/mysql/mysq/scripts</em></strong>&#8220;</li><li>Initialize the data directory by typing &#8220;<strong><em>./mysql_install_db &#8211;user=mysql &#8211;ldata=/var/mysql/cluster-data/&lt;hostname&gt;</em></strong>&#8220;. Again, replace &#8220;<strong><em>&lt;hostname&gt;</em></strong>&#8221; with the actual hostname of the server, example of full path should be &#8220;<strong><em>/var/mysql/cluster-data/mysqlmngserv</em></strong>&#8220;. The &#8211;ldata parameter value must be the data director that we&#8217;ve just created.</li><li>Next, change the directory to /etc/init.d by typing &#8220;<strong><em>cd /etc/init.d</em></strong>&#8220;.</li><li>Edit the file &#8220;<strong><em>mysql</em></strong>&#8221; with vi or some other text editor of your preference, locate the line &#8220;<strong><em>datadir=/var/lib/mysql</em></strong>&#8220;, change it to &#8220;<strong><em>datadir=/var/mysql/cluster-data/&lt;hostname&gt;</em></strong>&#8221; with &#8220;<strong><em>&lt;hostname&gt;</em></strong>&#8221; as the actual hostname, save the modification.<li>Likewise, repeat step 1 to 5 and make sure the directories are created according to the naming convention discussed above.</li></ol></div><h2>Ownership and Permission For All Necessary Directories</h2><p>After installing the MySQL Cluster NDB package and creating all the directories mentioned above, this is the time to change the ownership and the permission of the directories.</p><p>For EACH server, perform this as the &#8220;<strong><em>root</em></strong>&#8221; user:</p><ol><li>In the terminal, change the ownership of the directories by typing &#8220;<strong><em>chown –R mysql:mysql /opt/mysql /var/mysql</em></strong>&#8220;</li><li>Change the file permissions recursively by typing &#8220;<strong><em>chmod –R 755 /opt/mysql /var/mysql</em></strong>&#8220;.<li>Please repeat step 1 to 2 for all servers.</li></ol><h2>Configuration for MySQL Server (SQL Nodes Only)</h2><p>Remember the <em>current-running-config-files</em> directory that you&#8217;ve created in <em>/opt/mysql/mysql</em>? This is the time to create config files for the SQL Nodes. Just follow the instructions below and do this <strong>ONLY </strong>on mysqlserv1 (192.168.2.51) and mysqlserv2 (192.168.2.52):</p><p>Perform the below as the &#8220;<strong>mysql</strong>&#8221; user for both mysqlserv1 (192.168.2.51) and mysqlserv2 (192.168.2.52):</p><ul><li>Switch to the user by typing &#8220;<strong><em>su mysql</em></strong>&#8221; in the terminal.</li><li>Change the directory to /opt/mysql/mysq/current-running-config-files by typing &#8220;<strong><em>cd /opt/mysql/mysq/current-running-config-files</em></strong>&#8220;.</li><li>Create a file &#8220;<strong><em>mysql.mysqlserv1.cnf</em></strong>&#8221; by typing &#8220;<strong><em>touch mysql.mysqlserv1.cnf</em></strong>&#8220;. This is for mysqlserver1. As for mysqlserver2, just create a file name &#8220;<strong><em>mysql.mysqlserv2.cnf</em></strong>&#8221; with the same procedure.</li><li>Edit the newly created <strong><em>mysql.&lt;hostname&gt;.cnf</em></strong> with the contents below:<br /><pre>
[mysqld]
# run NDB storage engine
ndbcluster

# location of management server
ndb-connectstring=192.168.2.50

# define the location of the data directory
<strong><em>datadir=/var/mysql/cluster-data/mysqlserv1</em></strong>

#The rest of the configuration values

[mysql_cluster]
# location of management server
ndb-connectstring=192.168.2.50

</pre><br /> The above is for mysqlserv1 (192.168.2.51), please replace the line &#8220;<strong><em>datadir=/var/mysql/cluster-data/mysqlserv1</em></strong>&#8221; to &#8220;<strong><em>datadir=/var/mysql/cluster-data/mysqlserv2</em></strong>&#8221; for mysqlserv2 (192.168.2.52). Besides storing configuration parameters in the .cnf file, what we have defined here is to tell the SQL Node that the Management Server lies in 192.168.2.50 and it has to be tame by it. You may even define the &#8220;[client]&#8221; section and amend the “[mysqld]” section with the necessary configuration parameters for optimization purposes, just look at the <em>/opt/mysql/mysql/support-files/</em> directory for some ideas. But for now, this is sufficient.</li></ul><p>In future, for every SQL Node that you add, the above will be the reference configuration for your usage.</p><h2>Configuration for Management Server (Only for mysqlmngserv)</h2><p>Now, we need to create the <strong><em>config.ini</em></strong> file for only the Management Server and this is a crucial step. Just follow the instructions below:</p><p>Perform this as the &#8220;<strong><em>mysql</em></strong>&#8221; user on <strong><em>ONLY</em></strong> the mysqlmngserv (192.168.2.50):</p><ol><li>Switch to the user &#8220;mysql&#8221; by typing in the terminal &#8220;<strong><em>su mysql</em></strong>&#8220;.</li><li>Change the directory to <em>/opt/mysql/mysql/current-running-config-files</em> by typing &#8220;<strong><em>cd /opt/mysql/mysql/current-running-config-files</em></strong>&#8220;.</li><li>Create a file name <em>config.ini</em> by typing &#8220;<strong><em>touch config.ini</em></strong>&#8220;.</li><li>Edit the newly created <strong><em>config.ini</em></strong> file with the contents below:<br /><pre>
[ndbd default]
# Number of replicas
# We want 2 data nodes within 1 group e.g. Data Node 1 and
# Data Node 2 belongs to one group, etc.
<strong><em>NoOfReplicas=2</em></strong>

[ndb_mgmd]
#specify the node id of the management server
NodeId=1

#hostname or IP of the management server
hostname=192.168.2.50

# The data directory for the management server
datadir=/var/mysql/cluster-data/mysqlmngserv

# For the below, for every Data Node, just specify a section call "[ndbd]"
# Configs for Data Node 1
[ndbd]
#specify the node id for the Data Node
NodeId=11
hostname=192.168.2.53
datadir=/var/mysql/cluster-data/mysqldn1

# Configs for Data Node 2
[ndbd]
NodeId=12
hostname=192.168.2.54
datadir=/var/mysql/cluster-data/mysqldn2

# Configs for Data Node 3
[ndbd]
NodeId=13
hostname=192.168.2.55
datadir=/var/mysql/cluster-data/mysqldn3

# Configs for Data Node 4
[ndbd]
NodeId=14
hostname=192.168.2.56
datadir=/var/mysql/cluster-data/mysqldn4

# Same goes, for every SQL Node, just specify a section call "[mysqld]"
# You don't have to specify the data directory for the SQL Nodes here.
# Configs for MySQL Server 1
[mysqld]
#specify the node id for the MySQL Server
NodeId=31
hostname=192.168.2.51

# Configs for MySQL Server 2
[mysqld]
NodeId=32
hostname=192.168.2.52
</pre></li><li>Save the amendments in config.ini</li></ol><p>Just a brief explanation on <em>config.ini</em>: for every Data Node that is involve in the cluster, you will need to define a &#8220;<strong>[ndbd]</strong>&#8221; section for each of it, with the specific <strong><em>NodeId</em></strong>, <strong><em>hostname </em></strong>(which points to the IP address of the data node server) and <strong><em>datadir </em></strong>(which is the data directory on the data node server itself, not the management server). Likewise for the MySQL Server (SQL Nodes), there should be a &#8220;<strong>[mysqld]</strong>&#8221; section defined for each SQL Nodes with the NodeId and the hostname parameter.</p><p>Notice the <strong><em>NoOfReplicas </em></strong>parameter? That is the parameter that is use to tell the management server how many data nodes should be within a single group. Here, the value for NoOfReplicas is 2, which means, there should be 2 data nodes within one data node group. Therefore, the equation below holds true:</p><div style="text-align: center;"><strong><em>Total Number of Data Node Groups = Number of Data Nodes / Value in NoOfReplicas</em></strong></div><p>&nbsp;</p><h2>To Be Continued&#8230;</h2><p>Hope that everything is fine when you reach here. Because of the length of the tutorial, a decision was made to separate it into several parts. For the next part, we&#8217;ll discuss more on how to start, how to manage the MySQL users (user and privilege synchronization) in the cluster/distributed environment and how to stop the servers in the cluster. So, read on&#8230;</p><h3>Proceed to Part 2:</h3><p><a href="http://www.developerscrappad.com/839/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-2-starting-distributed-synchronized-users-management-and-stopping-the-cluster/">MySQL Cluster NDB 7.2 on Solaris 10 Part 2 &#8211; Starting, Distributed Synchronized Users Management And Stopping The Cluster</a></p><h3>Related Articles:</h3><ul><li><a href="http://www.developerscrappad.com/918/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-3-testing-the-cluster/">MySQL Cluster NDB 7.2 on Solaris 10 Part 3 – Testing The Cluster</a></li><li><a href="http://www.developerscrappad.com/172/database/mysql/installing-mysql-5-0-on-solaris-10/">Installing MySQL 5.0 on Solaris 10</a></li><li><a href="http://www.developerscrappad.com/185/database/mysql/installing-mysql-5-5-on-solaris-10/">Installing MySQL 5.5 on Solaris 10</a><li><a href="http://www.developerscrappad.com/210/database/mysql/how-to-boot-mysql-5-5-on-solaris-10-during-system-startup/">How To Boot MySQL 5.5 On Solaris 10 During System Startup</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/796/database/mysql/mysql-cluster-ndb-7-2-on-solaris-10-part-1-how-to-install-setup-and-setup/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Quick Fix: How to Solve “Unable to read the logging configuration” on Netbeans7 with JBoss6</title><link>http://www.developerscrappad.com/759/java/java-ee/jboss/quick-fix-how-to-solve-unable-to-read-the-logging-configuration-on-netbeans7-with-jboss6/</link> <comments>http://www.developerscrappad.com/759/java/java-ee/jboss/quick-fix-how-to-solve-unable-to-read-the-logging-configuration-on-netbeans7-with-jboss6/#comments</comments> <pubDate>Sat, 08 Sep 2012 05:04:51 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[JBoss]]></category> <category><![CDATA[Netbeans]]></category> <category><![CDATA[Java]]></category> <category><![CDATA[Java EE]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=759</guid> <description><![CDATA[This is just a quick fix post for those whom are having this problem when running JBoss 6.x with Netbeans 7.x. This problem will occur when after you have installed a newly unzipped JBoss 6.x app server and getting it register with Netbeans 7 through the &#8220;Service&#8221; tab -> Servers tree -> &#8220;Add Server&#8220;, and [...]]]></description> <content:encoded><![CDATA[<p>This is just a quick fix post for those whom are having this problem when running JBoss 6.x with Netbeans 7.x.<br /> <span id="more-759"></span><br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/quickfix.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/quickfix-150x150.jpg?e83a2c" alt="" title="quickfix" width="150" height="150" class="alignnone size-thumbnail wp-image-781" style="display: none;"/></a><br /> This problem will occur when after you have installed a newly unzipped JBoss 6.x app server and getting it register with Netbeans 7 through the &#8220;<strong>Service</strong>&#8221; tab -> <strong>Servers </strong>tree -> &#8220;<strong>Add Server</strong>&#8220;, and when you try to start the server, it will hang with the error message:</p><p><pre style="background: #ededed;">
Calling C:\Java\jboss-6.1.0-final\bin\run.conf.bat
===============================================================================

  JBoss Bootstrap Environment

  JBOSS_HOME: C:\Java\jboss-6.1.0-final

  JAVA: C:\Program Files\Java\jdk1.6.0_30\bin\java

  JAVA_OPTS: -Dprogram.name=run.bat -Dlogging.configuration=file:logging.properties \
-Xms128m -Xmx512m -XX:MaxPermSize=256m -server

  CLASSPATH: C:\Program Files\Java\jdk1.6.0_30\lib\tools.jar;C:\Java\jboss-6.1.0-final\bin\run.jar

===============================================================================

<font style="color: red;">Unable to read the logging configuration from 'file:logging.properties' (java.io.FileNotFoundException:
logging.properties (The system cannot find the file specified))</font>
</pre></p><h2>Solution for Microsoft Windows</h2><p>If you are running on windows, you can fix this issue before you start the JBoss server through Netbeans:</p><ol><li>Go to the &#8220;<strong>bin</strong>&#8221; directory where you&#8217;ve installed JBoss</li><li>Edit the &#8220;<strong>run.bat</strong>&#8221; file</li><li>Search for the line &#8220;<strong>set JAVA_OPTS=-Dprogram.name=%PROGNAME% -Dlogging.configuration=file:%DIRNAME%logging.properties %JAVA_OPTS%</strong>&#8220;</li><li><p>Change the <strong>%DIRNAME%</strong> to your absolute path to the &#8220;bin&#8221; directory of your installed JBoss.e.g.</p><p><strong>set JAVA_OPTS=-Dprogram.name=%PROGNAME% -Dlogging.configuration=file:&#8221;C:\Java\jboss-6.1.0-final\bin\logging.properties&#8221; %JAVA_OPTS%</strong></p></li><li>I&#8217;m adding the double quote &#8221; so that if your directory name has spaces, it will still be legitimate.</li><li>Try to start your server through Netbeans again, it should be working fine after this.</li></ol><h2>Solution for Unix/Linux</h2><p>If you are running on any flavor of Unix or Linux, you can fix this issue before you start the JBoss server through Netbeans:</p><ol><li>Go to the &#8220;<strong>bin</strong>&#8221; directory where you&#8217;ve installed JBoss</li><li>Edit the &#8220;<strong>run.sh</strong>&#8221; file</li><li>Search for the line <strong>JAVA_OPTS=&#8221;${JAVA_OPTS:+$JAVA_OPTS -Dlogging.configuration=file:${DIRNAME}/logging.properties}&#8221;</strong></li><li><p>Change the <strong>${DIRNAME}</strong> to your absolute path to the &#8220;bin&#8221; directory of your installed JBoss.e.g.</p><p><strong>JAVA_OPTS=&#8221;${JAVA_OPTS:+$JAVA_OPTS -Dlogging.configuration=file:/java/jboss-6.1.0-final/bin/logging.properties}&#8221;</strong></p></li><li>Try to start your server through Netbeans again, it should be working fine after this.</li></ol><p>Hope it helps.</p> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/759/java/java-ee/jboss/quick-fix-how-to-solve-unable-to-read-the-logging-configuration-on-netbeans7-with-jboss6/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Making sense of EJB3.x Transaction Attributes – Part 4 (NEVER)</title><link>http://www.developerscrappad.com/748/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-4-never/</link> <comments>http://www.developerscrappad.com/748/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-4-never/#comments</comments> <pubDate>Wed, 05 Sep 2012 15:03:22 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[Java EE]]></category> <category><![CDATA[Container-Managed Transaction]]></category> <category><![CDATA[EJB3]]></category> <category><![CDATA[JPA]]></category> <category><![CDATA[NEVER]]></category> <category><![CDATA[TransactionAttribute]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=748</guid> <description><![CDATA[This is the last part in the series of &#8220;Making sense of EJB3.x Transaction Attributes&#8220;. So far, we&#8217;ve discussed transaction attribute type REQUIRES_NEW, MANDATORY, SUPPORTSand NOT_SUPPORTED. Here, we&#8217;ll cover the last attribute which is &#8220;NEVER&#8220;. The NEVER transaction attribute type is a simple one, but yet sometimes, it is difficult and confusing to where it [...]]]></description> <content:encoded><![CDATA[<p>This is the last part in the series of &#8220;<strong>Making sense of EJB3.x Transaction Attributes</strong>&#8220;. So far, we&#8217;ve discussed transaction attribute type <strong><a href="http://www.developerscrappad.com/572/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-1-requires_new/">REQUIRES_NEW</a></strong>, <strong><a href="http://www.developerscrappad.com/619/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-2-mandatory/">MANDATORY</a></strong>, <strong><a href="http://www.developerscrappad.com/709/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-3-difference-between-supports-and-not_supported/">SUPPORTS</a></strong>and <strong><a href="http://www.developerscrappad.com/709/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-3-difference-between-supports-and-not_supported/">NOT_SUPPORTED</a></strong>. Here, we&#8217;ll cover the last attribute which is &#8220;<strong>NEVER</strong>&#8220;. The <strong>NEVER </strong>transaction attribute type is a simple one, but yet sometimes, it is difficult and confusing to where it can be applied in your Java EE project. This is a very short article with no code samples except to tell you where I think the <strong>NEVER </strong>transaction attribute type should be used.<br /> <span id="more-748"></span><br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/1209407_15765517.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/1209407_15765517-150x150.jpg?e83a2c" alt="" title="1209407_15765517" width="150" height="150" class="alignnone size-thumbnail wp-image-754" style="display: none;" /></a><br /> In fact, <strong><em>TransactionAttributeType.NEVER</em></strong> tells a method in a session bean not to get involve with any transaction. Yes is as simple as that. Truthfully, TransactionAttributeType.NEVER is very rigid and it is so strict that even when it detects that there is a living transaction that the method annotated is involved, it throws an EJBException. But there are good uses for it.</p><p><pre>
<h3>STICKY IMPORTANT HIGHLIGHT!!!:</h3>
<em>** You can only bring out the effects of transaction attributes only when you call the method through a
session bean instance and NOT through a direct method call. Even if your methods are within the same
bean, you need to get the local instance of the same bean and call through its local interface instead
of a direct method invoke.</em>
</pre></p><h2>When to use TransactionAttributeType.NEVER</h2><p>In my opinion, a method should be annotated with TransactionAttributeType.NEVER if it only consist of logics that &#8220;NEVER&#8221; touches the database or any invocation of other methods which are transactional. Thus, the word NEVER.</p><p>For my past projects, I&#8217;ll annotate session bean methods with <strong><em>NEVER </em></strong>if they are only specifically involve in physical file reading and writing (I&#8217;ll skip the debates on EJB specs), raw number crunching, cropping/transformation/editing of an image, algorithms which serves an algorithmic purpose (funny, but it makes sense e.g. calculation of the upper and lower Bollinger bands for financial numbers) or even password encryption and decryption. These are just some of the examples of usage for methods with <strong><em>NEVER </em></strong>transaction attribute type. Notice that the above use cases didn’t touch any database layer and whatever the method processes, it is final and no correction when things go wrong. If you have specific use cases like this, <strong><em>NEVER </em></strong>is just the answer to your session bean method.</p><p>The benefits of using TransactionAttributeType.NEVER is it doesn&#8217;t involve any database transaction and thus it has limited overhead in usage of app server resources.</p><h2>Transaction Attribute Types That &#8220;NEVER&#8221; Co-exists:</h2><p>A session bean method that is annotated as NEVER is safe to be invoked by another session bean method that is annotated by <strong><em>TransactionAttributeType.NOT_SUPPORTED</em></strong>, as it will suspend any transaction before carrying out its business.</p><h2>Summary</h2><p>I hope that you have gain much by reading all of this 4 part series of transaction attributes. Knowing the behavior of the attribute type will just increase your knowledge, but knowing when to use them at the right time in the right places will do wonders in your application.</p><p>Hope you&#8217;ve enjoy reading.</p><h3>Related Articles:</h3><ul><li><a href="http://www.developerscrappad.com/572/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-1-requires_new/" target="_blank">Making sense of EJB3.x Transaction Attributes – Part 1 (REQUIRES_NEW)</a></li><li><a href="http://www.developerscrappad.com/619/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-2-mandatory/" target="_blank">Making sense of EJB3.x Transaction Attributes – Part 2 (MANDATORY)</a></li><li><a href="http://www.developerscrappad.com/709/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-3-difference-between-supports-and-not_supported/" target="_blank">Making sense of EJB3.x Transaction Attributes – Part 3 (Difference Between SUPPORTS and NOT_SUPPORTED)</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/748/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-4-never/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Making sense of EJB3.x Transaction Attributes – Part 3 (Difference Between SUPPORTS and NOT_SUPPORTED)</title><link>http://www.developerscrappad.com/709/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-3-difference-between-supports-and-not_supported/</link> <comments>http://www.developerscrappad.com/709/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-3-difference-between-supports-and-not_supported/#comments</comments> <pubDate>Wed, 05 Sep 2012 07:01:46 +0000</pubDate> <dc:creator>Max Lam</dc:creator> <category><![CDATA[Java EE]]></category> <category><![CDATA[Container-Managed Transaction]]></category> <category><![CDATA[EJB3]]></category> <category><![CDATA[JPA]]></category> <category><![CDATA[NOT_SUPPORTED]]></category> <category><![CDATA[SUPPORTS]]></category> <category><![CDATA[TransactionAttribute]]></category><guid isPermaLink="false">http://www.developerscrappad.com/?p=709</guid> <description><![CDATA[Oracle had extensively documented the behavior of each transaction attributes in the Java EE documentation, but they always fail to provide an extensive coverage on when and where these individual transaction attributes are supposed to be used and in what context of business logic are these democrats deem suitable. Here, let us explore both the [...]]]></description> <content:encoded><![CDATA[<p>Oracle had extensively documented the behavior of each transaction attributes in the Java EE documentation, but they always fail to provide an extensive coverage on when and where these individual transaction attributes are supposed to be used and in what context of business logic are these democrats deem suitable.<br /> <span id="more-709"></span><br /> Here, let us explore both the <strong><em>SUPPORTS</em></strong> and the <strong><em>NOT_SUPPORTED</em></strong> transaction attribute types. I have decided to write on both SUPPORTS and NOT_SUPPORTED together in this article because I think it will be convenient to distinguish their behavior and usage. As far as my writings are concern, I would always like to clear the fog of where and when to apply these stuff in your software project and I&#8217;ll do my very best to make so simple even a new guy taking up Java EE development could understand. Just read through the entire article to the bottom and you should be able to understand what&#8217;s all this about.<br /> <br /> <a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/978635_75102122.jpg?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/978635_75102122-150x150.jpg?e83a2c" alt="" title="978635_75102122" width="150" height="150" class="alignnone size-thumbnail wp-image-737" style="display: none;"/></a></p><h2>Behavior of SUPPORTS and NOT_SUPPORTED</h2><p>Just briefly take a look at the code snippet below:<br /><pre>
@Local
public interface ISessionFacade1 {
	public void method1();
	public void method2();
}

@Stateless
public class SessionFacade1 implements ISessionFacade1
{
	@TransactionAttribute( TransactionAttributeType.SUPPORTS)
	public void method1() {
		//Do Something...
	}

	@TransactionAttribute( TransactionAttributeType.NOT_SUPPORTED)
	public void method2() {
		//Do Something...
	}		
}

public class SessionFacade2
{
	@EJB
	private ISessionFacade1 sf1;

	public void performBusinessLogic()
	{
                /**
                 * For sf1.method1() will will ride on the same transaction that is
                 * within performBusinessLogic()
                 */
		sf1.method1();

		/**
                 * As for sf1.method2(), it will just suspend the transaction within
                 * performBusinessLogic(), run it by its own and resume the transaction again.
                 */
		sf2.method2();
	}	

}
</pre></p><p>Right here, we have both stateless session bean of <strong><em>SessionFacade1</em></strong> (implementing <strong><em>ISessionFacade1</em></strong>local interface) and <strong><em>SessionFacade2</em></strong>. In <strong><em>SessionFacade1</em></strong>, we have 2 methods where by <strong><em>method1()</em></strong> was annotated with <strong><em>@TransactionAttribute(TransactionAttributeType.SUPPORTS)</em></strong> and <strong><em>method2()</em></strong> was annotated with <strong><em>@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)</em></strong>. Now, if <strong><em>performBusinessLogic()</em></strong> in <strong><em>SessionFacade2</em></strong> runs and invokes <strong><em>method1()</em></strong> in <strong><em>SessionFacade1</em></strong>, since <strong><em>method1()</em></strong> was annotated with <strong><em>SUPPORTS</em></strong>, it will ride on the same transaction as <strong><em>performBusinessLogic()</em></strong>. If <strong><em>performBusinessLogic()</em></strong> has transaction T1, <strong><em>method1()</em></strong> will also use the same transaction T1 as <strong><em>performBusinessLogic()</em></strong>. But if any external invocation on method1() is without a transaction, method1() won&#8217;t start its own transaction and will just execute without a transaction.</p><p>The interesting part lies in <strong><em>method2()</em></strong> of <strong><em>SessionFacade2</em></strong>. When <strong><em>performBusinessLogic()</em></strong> invokes <strong><em>method2()</em></strong>, even if <strong><em>performBusinessLogic()</em></strong> carries a transaction T1 (T1 is just a name given), <strong><em>method2()</em></strong> will neither ride on T1 nor will it start its own transaction. It will simply suspend T1 or whatever transaction that the external invoker has, execute its individual contents, only then the transaction T1 will be resumed after that. Simple said, any methods with <strong><em>NOT_SUPPORTED</em></strong> are non-transactional and will not participate in any existing transactions; it won&#8217;t throw an error whether if it is within a transaction or not, but it just won&#8217;t participate in a transaction.</p><p><pre>
<h3>STICKY IMPORTANT HIGHLIGHT!!!:</h3>
<em>** You can only bring out the effects of transaction attributes only when you call the method through a
session bean instance and NOT through a direct method call. Even if your methods are within the same
bean, you need to get the local instance of the same bean and call through its local interface instead
of a direct method invoke.</em>
</pre></p><h2>Need an Example?</h2><p>OK, enough theories, I&#8217;m gonna give you a very simple example of how the data is being affected by just executing 2 methods of the same code contents but with different democrat. One with <strong><em>SUPPORTS</em></strong> and another with <strong><em>NOT_SUPPORTED</em></strong>.</p><p>The below is the a simple single database table (MySQL orientated) which encapsulates a bank account holder with the current balance in his or her bank account.</p><p><a href="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/supportdemo.png?e83a2c"><img src="http://cdn.developerscrappad.com/wp-content/uploads/2012/09/supportdemo.png?e83a2c" alt="" title="supportdemo" width="362" height="233" class="aligncenter size-full wp-image-718" /></a></p><div style="clear: both;">&nbsp;</div><p>In this superficial table, the <strong><em>USERNAME </em></strong>column represents the bank account holder and the <strong><em>ACCT_BALANCE </em></strong>column represents the current account balance in terms of money. Let&#8217;s populate the table with 2 users, &#8220;<strong><em>DUMMY1</em></strong>&#8221; with $100,000 and &#8220;<strong><em>DUMMY2</em></strong>&#8221; with $1,000,000. You may use the script below to generate the table and the data.</p><p><pre class="devcodeblock" title="SQL"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> BANK_ACCOUNT</li><li><span style="color: #66cc66;">&#40;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;PK <span style="color: #993333; font-weight: bold;">BIGINT</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span><span style="color: #66cc66;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;USERNAME <span style="color: #993333; font-weight: bold;">VARCHAR</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">255</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;ACCT_BALANCE <span style="color: #993333; font-weight: bold;">DECIMAL</span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">,</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span><span style="color: #66cc66;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span><span style="color: #66cc66;">&#40;</span>PK<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #993333; font-weight: bold;">UNIQUE</span><span style="color: #66cc66;">&#40;</span>USERNAME<span style="color: #66cc66;">&#41;</span></li><li><span style="color: #66cc66;">&#41;</span> ENGINE<span style="color: #66cc66;">=</span>InnoDB;</li><li>&nbsp;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> BANK_ACCOUNT <span style="color: #66cc66;">&#40;</span>USERNAME<span style="color: #66cc66;">,</span> ACCT_BALANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DUMMY1'</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">100000</span><span style="color: #66cc66;">&#41;</span>;</li><li><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> BANK_ACCOUNT <span style="color: #66cc66;">&#40;</span>USERNAME<span style="color: #66cc66;">,</span> ACCT_BALANCE<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">'DUMMY2'</span><span style="color: #66cc66;">,</span> <span style="color: #cc66cc;">1000000</span><span style="color: #66cc66;">&#41;</span>;</li></ol></div></pre></p><p><strong><em>The below are the codes with the entity class (BankAccountEntity.java):</em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.entity</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.io.Serializable</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.math.BigDecimal</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.Column</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.Entity</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.GeneratedValue</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.GenerationType</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.Id</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.NamedQueries</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.NamedQuery</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.Table</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@<span style="color: #003399; font-weight: bold;">Entity</span></li><li>@Table<span style="color: #009900;">&#40;</span>name = <span style="color: #0000ff;">&quot;BANK_ACCOUNT&quot;</span><span style="color: #009900;">&#41;</span></li><li>@NamedQueries<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;@NamedQuery<span style="color: #009900;">&#40;</span>name = <span style="color: #0000ff;">&quot;BankAccountEntity.findByPk&quot;</span>, query = <span style="color: #0000ff;">&quot;SELECT b FROM BankAccountEntity b WHERE b.pk = :pk&quot;</span><span style="color: #009900;">&#41;</span>,</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@NamedQuery<span style="color: #009900;">&#40;</span>name = <span style="color: #0000ff;">&quot;BankAccountEntity.findByUsername&quot;</span>, query = <span style="color: #0000ff;">&quot;SELECT b FROM BankAccountEntity b WHERE b.username = :username&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span></li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BankAccountEntity <span style="color: #000000; font-weight: bold;">implements</span> <span style="color: #003399; font-weight: bold;">Serializable</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #006600; font-weight: bold;">long</span> serialVersionUID = -7053090916337791292L<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Id</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@GeneratedValue<span style="color: #009900;">&#40;</span>strategy = GenerationType.<span style="color: #006633;">IDENTITY</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Column<span style="color: #009900;">&#40;</span>name = <span style="color: #0000ff;">&quot;PK&quot;</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399; font-weight: bold;">Long</span> pk<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Column<span style="color: #009900;">&#40;</span>name = <span style="color: #0000ff;">&quot;USERNAME&quot;</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@Column<span style="color: #009900;">&#40;</span>name = <span style="color: #0000ff;">&quot;ACCT_BALANCE&quot;</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399; font-weight: bold;">BigDecimal</span> acctBalance<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Long</span> pk<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">pk</span> = pk<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Long</span> pk, <span style="color: #003399; font-weight: bold;">String</span> username, <span style="color: #003399; font-weight: bold;">BigDecimal</span> acctBalance<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">pk</span> = pk<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">username</span> = username<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">acctBalance</span> = acctBalance<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">Long</span> getPk<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> pk<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> setPk<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Long</span> pk<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">pk</span> = pk<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">String</span> getUsername<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> username<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> setUsername<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">username</span> = username<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">BigDecimal</span> getAcctBalance<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> acctBalance<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> setAcctBalance<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">BigDecimal</span> acctBalance<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">acctBalance</span> = acctBalance<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #003399; font-weight: bold;">Override</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">int</span> hashCode<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #006600; font-weight: bold;">int</span> hash = <span style="color: #cc66cc;">0</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hash += <span style="color: #009900;">&#40;</span>pk <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span> <span style="color: #339933;">?</span> pk.<span style="color: #006633;">hashCode</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> : <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> hash<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #003399; font-weight: bold;">Override</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">boolean</span> equals<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">Object</span> object<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">// TODO: Warning - this method won't work in the case the id fields are not set</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #009900;">&#40;</span>object <span style="color: #000000; font-weight: bold;">instanceof</span> BankAccountEntity<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BankAccountEntity other = <span style="color: #009900;">&#40;</span>BankAccountEntity<span style="color: #009900;">&#41;</span> object<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">pk</span> == <span style="color: #006600; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> other.<span style="color: #006633;">pk</span> <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> || <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">pk</span> <span style="color: #339933;">!</span>= <span style="color: #006600; font-weight: bold;">null</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">pk</span>.<span style="color: #006633;">equals</span><span style="color: #009900;">&#40;</span>other.<span style="color: #006633;">pk</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #006600; font-weight: bold;">false</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #006600; font-weight: bold;">true</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #003399; font-weight: bold;">Override</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399; font-weight: bold;">String</span> toString<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #0000ff;">&quot;com.developerscrappad.entity.BankAccountEntity[ pk=&quot;</span> + pk + <span style="color: #0000ff;">&quot; ]&quot;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p>Here, let&#8217;s have 2 stateless session beans where by <strong><em>BankQuerySessionFacade</em></strong>&#8216;s methods are to only perform querying of the accounts and <strong><em>BankTransactionSessionFacade </em></strong>will have a method to perform fund transfer between accounts of different account holders. All with necessary @Local interfaces</p><p><strong><em>Codes for interface IBankQuerySessionFacadeLocal:</em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.ejb</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.developerscrappad.entity.BankAccountEntity</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.Local</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@Local</li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> IBankQuerySessionFacadeLocal <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity findBankAccountByUsernameWithSupports<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity findBankAccountByUsernameWithNotSupported<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong><em>Codes for interface IBankQuerySessionFacadeRemote:</em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.ejb</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.Remote</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@<span style="color: #003399; font-weight: bold;">Remote</span></li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> IBankQuerySessionFacadeRemote <span style="color: #000000; font-weight: bold;">extends</span> IBankQuerySessionFacadeLocal <span style="color: #009900;">&#123;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong><em>Codes for BankQuerySessionFacade (which is specifically for querying purposes):</em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.ejb</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.developerscrappad.entity.BankAccountEntity</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.Stateless</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.TransactionAttribute</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.TransactionAttributeType</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.EntityManager</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.PersistenceContext</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.Query</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@Stateless</li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BankQuerySessionFacade <span style="color: #000000; font-weight: bold;">implements</span> IBankQuerySessionFacadeLocal, IBankQuerySessionFacadeRemote <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@PersistenceContext<span style="color: #009900;">&#40;</span>unitName = <span style="color: #0000ff;">&quot;YourPersistentUnitName&quot;</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> EntityManager em<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">protected</span> EntityManager getEntityManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> em<span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> BankAccountEntity findBankAccountByUsername<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #003399; font-weight: bold;">Query</span> q = getEntityManager<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">createNamedQuery</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;BankAccountEntity.findByUsername&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;q.<span style="color: #006633;">setParameter</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;username&quot;</span>, username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>BankAccountEntity<span style="color: #009900;">&#41;</span> q.<span style="color: #006633;">getSingleResult</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #003399; font-weight: bold;">Override</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;@TransactionAttribute<span style="color: #009900;">&#40;</span> TransactionAttributeType.<span style="color: #006633;">SUPPORTS</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity findBankAccountByUsernameWithSupports<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> findBankAccountByUsername<span style="color: #009900;">&#40;</span>username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #003399; font-weight: bold;">Override</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;@TransactionAttribute<span style="color: #009900;">&#40;</span> TransactionAttributeType.<span style="color: #006633;">NOT_SUPPORTED</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> BankAccountEntity findBankAccountByUsernameWithNotSupported<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> username<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">return</span> findBankAccountByUsername<span style="color: #009900;">&#40;</span>username<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong><em>Codes for IBankTransactionSessionFacadeLocal:</em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.ejb</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.math.BigDecimal</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.Local</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@Local</li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> IBankTransactionSessionFacadeLocal <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> performFundTransfer<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> fromUsername, <span style="color: #003399; font-weight: bold;">String</span> toUsername, <span style="color: #003399; font-weight: bold;">BigDecimal</span> transferAmount<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399; font-weight: bold;">Exception</span><span style="color: #339933;">;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong><em>Codes for IBankTransactionSessionFacadeRemote: </em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.ejb</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.Remote</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@<span style="color: #003399; font-weight: bold;">Remote</span></li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">interface</span> IBankTransactionSessionFacadeRemote <span style="color: #000000; font-weight: bold;">extends</span> IBankTransactionSessionFacadeLocal <span style="color: #009900;">&#123;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p><strong><em>Codes for BankTransactionSessionFacade (this is where the transaction content lies):</em></strong><br /><pre class="devcodeblock" title="Java(TM) 2 Platform Standard Edition 5.0"><div class="devcodeoverflow" style="height: 200px;"><ol><li><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.developerscrappad.ejb</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.developerscrappad.entity.BankAccountEntity</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">com.sun.istack.logging.Logger</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.math.BigDecimal</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.EJB</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.Stateless</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.TransactionAttribute</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.ejb.TransactionAttributeType</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.EntityManager</span><span style="color: #339933;">;</span></li><li><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">javax.persistence.PersistenceContext</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>@Stateless</li><li><span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> BankTransactionSessionFacade <span style="color: #000000; font-weight: bold;">implements</span> IBankTransactionSessionFacadeLocal, IBankTransactionSessionFacadeRemote <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399; font-weight: bold;">Logger</span> log = <span style="color: #003399; font-weight: bold;">Logger</span>.<span style="color: #006633;">getLogger</span><span style="color: #009900;">&#40;</span>BankTransactionSessionFacade.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@PersistenceContext<span style="color: #009900;">&#40;</span>unitName = <span style="color: #0000ff;">&quot;YourPersistentUnitName&quot;</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> EntityManager em<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@EJB</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">private</span> IBankQuerySessionFacadeLocal bankQuerySF<span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;@<span style="color: #003399; font-weight: bold;">Override</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;@TransactionAttribute<span style="color: #009900;">&#40;</span>TransactionAttributeType.<span style="color: #006633;">REQUIRED</span><span style="color: #009900;">&#41;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #006600; font-weight: bold;">void</span> performFundTransfer<span style="color: #009900;">&#40;</span><span style="color: #003399; font-weight: bold;">String</span> fromUsername, <span style="color: #003399; font-weight: bold;">String</span> toUsername, <span style="color: #003399; font-weight: bold;">BigDecimal</span> transferAmount<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399; font-weight: bold;">Exception</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BankAccountEntity fromBankAccount = bankQuerySF.<span style="color: #006633;">findBankAccountByUsernameWithSupports</span><span style="color: #009900;">&#40;</span>fromUsername<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BankAccountEntity toBankAccount = bankQuerySF.<span style="color: #006633;">findBankAccountByUsernameWithSupports</span><span style="color: #009900;">&#40;</span>toUsername<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Check if the funds are enough for transfer</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000;&nbsp;&nbsp;font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>fromBankAccount.<span style="color: #006633;">getAcctBalance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">compareTo</span><span style="color: #009900;">&#40;</span>transferAmount<span style="color: #009900;">&#41;</span> == -<span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #000000; font-weight: bold;">throw</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399; font-weight: bold;">Exception</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Insufficient funds&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//Perform the transfer</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fromBankAccount.<span style="color: #006633;">setAcctBalance</span><span style="color: #009900;">&#40;</span>fromBankAccount.<span style="color: #006633;">getAcctBalance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">subtract</span><span style="color: #009900;">&#40;</span>transferAmount<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;toBankAccount.<span style="color: #006633;">setAcctBalance</span><span style="color: #009900;">&#40;</span>toBankAccount.<span style="color: #006633;">getAcctBalance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>transferAmount<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;em.<span style="color: #006633;">persist</span><span style="color: #009900;">&#40;</span>fromBankAccount<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;em.<span style="color: #006633;">persist</span><span style="color: #009900;">&#40;</span>toBankAccount<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;em.<span style="color: #006633;">flush</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #666666; font-style: italic;">//This portion is for analysis, checking and illustration purposes</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BankAccountEntity fromBankAccount1 = bankQuerySF.<span style="color: #006633;">findBankAccountByUsernameWithSupports</span><span style="color: #009900;">&#40;</span>fromUsername<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BankAccountEntity fromBankAccount2 = bankQuerySF.<span style="color: #006633;">findBankAccountByUsernameWithNotSupported</span><span style="color: #009900;">&#40;</span>fromUsername<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-style: italic; font-weight: bold;">/**</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* For the below log trace, fromBankAccount1 amount should show the</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* deducted amount from fromUsername, BUT, the fromBankAccount2 amount</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* will still show the original amount balance from fromUsername!</span></li><li><span style="color: #008000; font-style: italic; font-weight: bold;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.<span style="color: #006633;">fine</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;fromBankAccount1 amount: &quot;</span> + fromBankAccount1.<span style="color: #006633;">getAcctBalance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log.<span style="color: #006633;">fine</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;fromBankAccount2 amount: &quot;</span> + fromBankAccount2.<span style="color: #006633;">getAcctBalance</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #009900;">&#125;</span></li><li><span style="color: #009900;">&#125;</span></li></ol></div></pre></p><p>What we are about to do here is to perform a fund transfer of $10,000 from the account of &#8220;<strong><em>DUMMY2</em></strong>&#8221; to the the account of &#8220;<strong><em>DUMMY1</em></strong>&#8220;. This is done in <strong><em>BankTransactionSessionFacade</em></strong>&#8216;s <strong><em>performFundTransfer()</em></strong> method. But meanwhile, the purpose is to examine the <strong><em>BankAccountEntity</em></strong> object of the same username if we query the <strong><em>BankAccountEntity</em></strong> object with both <strong><em>SUPPORTS </em></strong>and <strong><em>NOT_SUPPORTED</em></strong> transaction attribute type.</p><p>So, we have a client code to invoke <strong><em>performFundTransfer()</em></strong> e.g.:<br /><pre>
Context ctx = new InitialContext();
IBankTransactionSessionFacadeRemote remote = (IBankTransactionSessionFacadeRemote) \<br /> ctx.lookup(IBankTransactionSessionFacadeRemote.class.getName());<br />
remote.performFundTransfer("DUMMY2", "DUMMY1", new BigDecimal(10000));
</pre></p><p>If you execute the above code snippet, the transfer happened in the <strong><em>BankTransactionSessionFacade.performFundTransfer</em></strong> will persist well for both <strong><em>fromBankAccount</em></strong> (which belongs to username &#8220;<strong><em>DUMMY2</em></strong>&#8220;) and <strong><em>toBankAccount </em></strong>(which belongs to username &#8220;<strong><em>DUMMY1</em></strong>&#8220;).</p><p>Now for the fun part, when we again query the account belonging to &#8220;<strong><em>DUMMY2</em></strong>&#8221; through both <strong><em>BankQuerySessionFacade.findBankAccountByUsernameWithSupports()</em></strong> method and <strong><em>BankQuerySessionFacade.findBankAccountByUsernameWithNotSupported()</em></strong>method like the later portion of codes of <strong><em>BankTransactionSessionFacade</em></strong>:</p><p><pre>
BankAccountEntity fromBankAccount1 = \
bankQuerySF.findBankAccountByUsernameWithSupports(fromUsername);
BankAccountEntity fromBankAccount2 = \
bankQuerySF.findBankAccountByUsernameWithNotSupported(fromUsername);

log.fine("fromBankAccount1 amount: " + fromBankAccount1.getAcctBalance());
log.fine("fromBankAccount2 amount: " + fromBankAccount2.getAcctBalance());
</pre></p><p><strong><em>fromBankAccount1 </em></strong>entity object will rightfully reflect the deducted amount from <strong><em>DUMMY2</em></strong>, which is $990,000. But for <strong><em>fromBankAccount2</em></strong>, the the <strong><em>getAcctBalance()</em></strong> will yield the same unchanged account balance value of $1,000,000. This is because for <strong><em>BankQuerySessionFacade.findBankAccountByUsernameWithSupports()</em></strong> method, it queries within the same transaction used in <strong><em>BankTransactionSessionFacade.performFundTransfer()</em></strong> and the data righly reflects all that has happened within the transaction; but for <strong><em>BankQuerySessionFacade.findBankAccountByUsernameWithNotSupported()</em></strong>, it suspends the transaction running within <strong><em>BankTransactionSessionFacade.performFundTransfer()</em></strong> and queries what is still stored in the database before the <strong><em>BankTransactionSessionFacade.performFundTransfer()</em></strong> commits when it leaves the method.</p><p>So with this, we could draw some conclusion between <strong><em>SUPPORTS </em></strong>and <strong><em>NOT_SUPPORTED</em></strong>.</p><h2>When to use TransactionAttributeType.SUPPORTS?</h2><p>This is not absolute, but in my opinion and after going through myriads of projects with Java EE, I would annotate <strong><em>TransactionAttributeType.SUPPORTS</em></strong> on methods that query objects which the underlying data is consistently updated (constantly changing) and would always be involved in other transaction methods that carries Transaction Attribute Types like <strong><em>REQUIRED</em></strong>, <strong><em>MANDATORY </em></strong>or <strong><em>REQUIRES_NEW</em></strong>.</p><p>Query methods for changing data are well suited to be annotated with <strong><em>SUPPORTS </em></strong>because if the method only queries even without transaction, it could still return the data while not having to cause transaction overhead.</p><p>But on the contrary, if you annotate a method which performs persisting, merging or deletion of data in the database, use SUPPORTS wisely with discerning care.</p><h2>When to use TransactionAttributeType.NOT_SUPPORTED?</h2><p><strong><em>TransactionAttributeType.NOT_SUPPORTED</em></strong> are better suited for methods that query objects which carries static data that won&#8217;t be expected to be changed or to be transactionally involved with other business transaction. It can be querying methods for statically permanent data like country list, region list, gender list, etc. Methods that query data to especially establish drop-down list options in the selection box of web-forms are very well suited to be annotated with <strong><em>NOT_SUPPORTED</em></strong>.</p><p>Annotating <strong><em>NOT_SUPPORTED </em></strong>in methods like these will greatly save applications from transaction overhead(s).</p><h2>Summary</h2><p>We have seen from the previous posts on <strong><em>REQUIRES_NEW </em></strong>and <strong><em>MANDATORY </em></strong>(<strong><em>REQUIRED </em></strong>included) that are mostly used for heavy transactionally orientated processes for data persisting, merging and deletion. But both <strong><em>SUPPORTS </em></strong>and <strong><em>NOT_SUPPORTED </em></strong>are just right for methods that performs data query instead of writing stuff back into the database.</p><p>Overall, for methods that are annotated with <strong><em>SUPPORTS</em></strong>, it can be part of a transaction context and it can run even without transaction, that makes it suitable for querying of constantly changing data. Whereas for methods that are annotated with <strong><em>NOT_SUPPORTED</em></strong>, it will just suspend any transaction if it is run within a transaction context, thus making it suitable to for querying any data which is non-changing, static and permanent.</p><p>I hope this article truly makes sense out of <strong><em>SUPPORTS </em></strong>and <strong><em>NOT_SUPPORTED </em></strong>transaction attribute types. Thank you for reading and happy coding.</p><h3>Related Articles</h3><ul><li><a href="http://www.developerscrappad.com/572/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-1-requires_new/" target="_blank">Making sense of EJB3.x Transaction Attributes – Part 1 (REQUIRES_NEW)</a></li><li><a href="http://www.developerscrappad.com/619/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-2-mandatory/" target="_blank">Making sense of EJB3.x Transaction Attributes – Part 2 (MANDATORY)</a></li><li><a href="http://www.developerscrappad.com/748/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-4-never/">Making sense of EJB3.x Transaction Attributes – Part 4 (NEVER)</a></li></ul> ]]></content:encoded> <wfw:commentRss>http://www.developerscrappad.com/709/java/java-ee/making-sense-of-ejb3-x-transaction-attributes-part-3-difference-between-supports-and-not_supported/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Database Caching using disk: basic
Object Caching 812/966 objects using disk: basic
Content Delivery Network via cdn.developerscrappad.com

Served from: www.developerscrappad.com @ 2012-12-18 11:03:52 -->
