Tag: Datasource

SAR dependency alternate approach using @Singleton in JBossAS7.1.2

Hi,

SAR files are called as Service Archives. The extension of SAR files are *.sar which contains a “META-INF/jboss-service.xml” file, this file describes the custom MBeans which has to be exposed at the time of deployment or JBoss Startup. JBoss’s service archive architecture is based on the JMX and the SAR files which are basically JBoss specific can be deployed in the jboss inorder to publish your MBean based services. At the time of JBoss startup these service archive deployer (SARDeployer) instantiates the JBoss service classes and exposes them as manageable beans through JMX.

In previous release of JBoss 5/6 the SAR provided mbeans dependency could be very easily defined using <depends> tag, as following:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE server>
<server>
    <mbean code="custom.mbean.MyServerMonitor" name="service.server.monitor:service=MyMonitor">
         <attribute name="Frequency">5000</attribute>
         <depends>jboss.jca:service=DataSourceBinding,name=MySqlDS</depends>
    </mbean>
</server>

@org.jboss.ejb3.annotation.Service and @org.jboss.ejb3.annotation.Management are no longer supported which could be used to define Services. However in JBossAS7 this approach of defining the dependency is not good and you may see following kind of exceptions at the time of server startup:

JBAS014775:    New missing/unsatisfied dependencies:
      service jboss.mbean.service."jboss.as:subsystem=datasources,data-source=MySqlDS".create (missing) dependents: [service jboss.mbean.service."service.server.monitor:service=MyMonitor".create]
      service jboss.mbean.service."jboss.as:subsystem=datasources,data-source=MySqlDS".start (missing) dependents: [service jboss.mbean.service."service.server.monitor:service=MyMonitor".start]

JBossAS7 is fully EE6 certified application server and it provides a much better approach to create a Service with the help of EJB3.1 specific “javax.ejb.Startup” and “javax.ejb.Singleton” annotations. This kind of service can be made dependent to other services like DataSource. In this example we will see What is the better approach to define a service (without using container specific SAR feature).

The Source code for this demo can be found in the following github link:
https://github.com/jaysensharma/MiddlewareMagicDemos/tree/master/SingletonServiceDemo

Creating DataSource in JBossAS7.1.2

As we are going make our Service dependent on a DataSource, sothat we can see how the dependency goes.

Configuration-1). So here first of all we will create a DataSource by running the following CLI script in batch mode. So create a file with name “createDataSource.cli” somewhere in your filesystem like “/home/jaysensharma/SingletonServiceDemo/createDataSource.cli” as following:

deploy  /home/jaysensharma/SingletonServiceDemo/mysql-connector-java-5.1.13-bin.jar

/subsystem=datasources/data-source="MySqlDS":add(jndi-name="java:jboss/datasources/MySqlDS",driver-name="mysql-connector-java-5.1.13-bin.jar",connection-url="jdbc:mysql://localhost:3306/testDB",user-name="root",password="redhat")

Configuration-2). Now start your “$JBOSS_HOME/bin/jboss-cli.sh” script in order to run the above deploy the mysql driver and create DataSource as following:

./jboss-cli.sh -c --controller=10.10.10.10:9999 --file=/home/jaysensharma/SingletonServiceDemo/createDataSource.cli

Configuration-3). As soon as you will run the cli script as mentioned above you will see that the following kind of datasource is created on your standalone*.xml.

                <datasource jndi-name="java:jboss/datasources/MySqlDS" pool-name="MySqlDS">
                    <connection-url>jdbc:mysql://localhost:3306/testDB</connection-url>
                    <driver>mysql-connector-java-5.1.13-bin.jar</driver>
                    <security>
                        <user-name>root</user-name>
                        <password>redhat</password>
                    </security>
                </datasource>

Creating @Singleton service dependent on the DataSource

Step1). First of all we will create a directory somewhere in our file system as “/home/jaysensharma/SingletonServiceDemo” and then we will create a directory with name “src” inside “/home/jaysensharma/SingletonServiceDemo”:

Step2). Now write a @Startup @Singleton EJB3.1 service using “SingletonServiceBean.java” inside “/home/jaysensharma/SingletonServiceDemo/src” as following:

package sar.dependency.alternative;
import javax.ejb.Startup;
import javax.ejb.Singleton;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

//commons logging
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

// DataSource related
import javax.sql.DataSource;
import java.sql.Connection;

// Resource Injection related
import javax.annotation.Resource;

@Startup
@Singleton

public class SingletonServiceBean
 {
     private static Log logger = LogFactory.getLog(SingletonServiceBean.class);
     Connection con=null;


     public SingletonServiceBean()
            {
               logger.info("SingletonServiceBean constructor invoked.");
            }


     @Resource(name = "java:jboss/datasources/MySqlDS")
     DataSource ds;
     /* This @PostConstruct annotation is required to tell JBoss to invoke the "performOperations" immediately after the "SingletonServiceBean" creation. */
     @PostConstruct
     public void performOperations()
	    {
               logger.info("SingletonServiceBean performOperations() invoked.");
               try{
                     con=ds.getConnection();
                     logger.info("***** DataSource = "+ds+" . Connection con = "+con+" retrieved from the ConnectionPool.*****");
                  }
               catch(Exception e)
                 {
                     logger.error("Unable to get Connection From DataSource = "+ds+" ERROR: "+e.getMessage());
                     e.printStackTrace();
                 }
	    }


	@PreDestroy
	public void cleanUp() throws Exception {
	  logger.info("cleaning up connections.");
          if(con!=null)
            {
               try{
                     con.close();
                     logger.info("Connection con = "+con+" is successfully returned to the ConnectionPool.");
                  }
               catch(Exception e)
                 {
                     logger.error("Unable to Close Connection con = "+con+" ERROR: "+e.getMessage());
                     e.printStackTrace();
                 }
               finally{
                        try{   con.close(); }
                        catch(Exception ee) { ee.printStackTrace(); }
                      }
            }
	}
 }

Step3). Now the most important part of building / deploying the Singleton Service which we created, so in order to achieve that we will create a simple ant build script, So Create a “build.xml” file inside the “/home/jaysensharma/SingletonServiceDemo” directory as following:

<project name="SingletonStartupService" default="all">
<property name="jboss.home" value="/home/jaysensharma/jboss-as-7.1.2.Final" />
<property name="jboss.module.dir" value="${jboss.home}/modules" />
<property name="basedir" value="." />
<property name="tmp.dir" value="tmp" />
<property name="src.dir" value="src" />
<property name="output.dir" value="build" />
<property name="ear.name" value="TestSingletonService.ear" />
<property name="ejb.jar" value="singletonServiceEJB.jar" />


        <path id="jboss.classpath">
           <fileset dir="${jboss.module.dir}">
               <include name="**/*.jar"/>
           </fileset>
        </path>

        <target name="all" depends="deploy" />

        <target name="build_ear">
           <delete dir="${tmp.dir}" />
           <mkdir dir="${tmp.dir}" />
           <javac srcdir="${src.dir}" destdir="${tmp.dir}"  includes="*.java" classpathref="jboss.classpath"/>

           <jar jarfile="${tmp.dir}/${ejb.jar}" basedir="${tmp.dir}" compress="true" />

           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/sar"/>
           </delete>
           <mkdir dir="${tmp.dir}/META-INF"/>
           <copy todir="${tmp.dir}/META-INF">
                <fileset dir="${src.dir}/">
                  <include name="application.xml"/>
                </fileset>
           </copy>
           <jar jarfile="${tmp.dir}/${ear.name}" basedir="${tmp.dir}" compress="true" />
           <delete includeEmptyDirs="true">
              <fileset dir="${tmp.dir}/META-INF"/>
           </delete>
           <delete file="${tmp.dir}/${ejb.jar}"/>

           <copy file="${tmp.dir}/${ear.name}" tofile="${output.dir}/${ear.name}"/>
           <delete dir="${tmp.dir}"/>
        </target>


        <target name="deploy" depends="build_ear">
            <echo message="*******************  Deploying the EAR file ${ear.name} *********************" />
            <echo message="********** ${output.dir}/${ear.name} to ${jboss.home}/standalone/deployments **********" />
            <copy todir="${jboss.home}/standalone/deployments/">
                <fileset dir="${output.dir}/">
                  <include name="${ear.name}"/>
                </fileset>
            </copy>
            <echo message="*******************  Deployed Successfully   *********************" />
        </target>

</project>

NOTE: The only change in the above file you need to do is to change the “jboss.home” directory path in the second line of the above script to point to your own JBoss AS7 directory.

Step-4). Now before running your ANT script to build and deploy the above webapplication you should have the ANT as well as JAVA set in the $PATH variable of the Shell / command prompt as following:

For Unix Based OS:
export PATH=/home/jaysensharma/jdk1.6.0_21/bin:/home/jaysensharma/org.apache.ant_1.6.5/bin:$PATH

For Windows Based OS:
set PATH=C:/jdk1.6.0_21/bin;C:/org.apache.ant_1.6.5/bin;%PATH%

Step-5). Now once the PATH is set In the command/Shell prompt you can move inside the directory “/home/jaysensharma/SingletonServiceDemo” and then run the ant to build and deploy the EJB based EAR applicationon your JBoss Standalone full profile, by running the command “ant deploy”

[jaysensharma@localhost SingletonServiceDemo]$ ant
Buildfile: build.xml

build_ear:
    [mkdir] Created dir: /home/jaysensharma/SingletonServiceDemo/tmp
    [javac] Compiling 1 source file to /home/jaysensharma/SingletonServiceDemo/tmp
      [jar] Building jar: /home/jaysensharma/SingletonServiceDemo/tmp/singletonServiceEJB.jar
    [mkdir] Created dir: /home/jaysensharma/SingletonServiceDemo/tmp/META-INF
      [jar] Building jar: /home/jaysensharma/SingletonServiceDemo/tmp/TestSingletonService.ear
   [delete] Deleting: /home/jaysensharma/SingletonServiceDemo/tmp/singletonServiceEJB.jar
     [copy] Copying 1 file to /home/jaysensharma/SingletonServiceDemo/build
   [delete] Deleting directory /home/jaysensharma/SingletonServiceDemo/tmp

deploy:
     [echo] *******************  Deploying the EAR file TestSingletonService.ear *********************
     [echo] ********** build/TestSingletonService.ear to /home/jaysensharma/jboss-as-7.1.2.Final/standalone/deployments **********
     [copy] Copying 1 file to /home/jaysensharma/jboss-as-7.1.2.Final/standalone/deployments
     [echo] *******************  Deployed Successfully   *********************

all:

BUILD SUCCESSFUL
Total time: 1 second

Step-6). As the application is deployed on your JBoss so now try restarting your JBoss and then see whether the Above service us successfully get the DataSource and JDBC Connection or not. If the Dependency is correctly working then after restarting your JBoss you will see the following kind of message on your JBoss console / logs.

22:41:51,569 INFO  [sar.dependency.alternative.SingletonServiceBean] (MSC service thread 1-1) ***** DataSource = org.jboss.jca.adapters.jdbc.WrapperDataSource@43877c42 . Connection con = org.jboss.jca.adapters.jdbc.jdk6.WrappedConnectionJDK6@5424bf0 retrieved from the ConnectionPool.*****

.
.
Thanks
MiddlewareMagic Team 🙂


Management User Authentication using Encrypted Passwords with Database LoginModule AS7

Hi,

We have seen that using “$JBOSS_HOME/bin/add-user.sh” script we can create Management & Application Users. Using “add-user.sh” script when we create users then the credentials of Management user is stored inside the “$JBOSS_HOME/standalone/configuration/mgmt-users.properties” and inside the “$JBOSS_HOME/standalone/configuration/mgmt-users.properties” file. Even though the passwords are encrypted in these properties file still many administrators like to store their management credentials inside the Database rather than storing them inside the Database.

In our previous Demo we saw how to Authenticate Management Users based on the “DatabaseServerLoginModule” http://middlewaremagic.com/jboss/?p=2187 But the problem with that approach is we can see the Cleartext passwords present inside the Database as following:

mysql> select * from PRINCIPLES;
+--------------+----------+
| principal_id | password |
+--------------+----------+
| adminUser    | admin123 |
+--------------+----------+
1 row in set (0.00 sec)

But in this Current Demo we will see how we can store the Encrypted (MD5 + hex) password in the Database so that it will be safe. This can be simply achieved by adding the following two module options in the “security-domain”


    <module-option name="hashAlgorithm" value="MD5"/>
    <module-option name="hashEncoding" value="hex"/>

We will see it in more details so first we will proceed with creating the Hashed Password. Here we will write a simple program in order to Encrypt the Management User’s password.

Program to Encrypt Management User’s Password

Step1). Write the following program “EncryptPassword.java” inside your file system somewhere.

import java.security.MessageDigest;
import java.math.BigInteger;
import org.jboss.crypto.CryptoUtil;

public class EncryptPassword
  {
    public static void main(String ar[]) throws Exception
     {
       /*
       You will need the following JAFRs in your classpath in order to compile & run this program 
       export CLASSPATH=$JBOSS_HOME/modules/org/picketbox/main/picketbox-4.0.7.Final.jar:$JBOSS_HOME/bin/client/jboss-client.jar:$CLASSPATH:.:
       */

       //String clearTextPassword=ar[0]+":ManagementRealm:"+ar[1];     //---> This is how JBoss Encrypts password

       String clearTextPassword=ar[0];
       String hashedPassword=CryptoUtil.createPasswordHash("MD5", "hex", null, null, clearTextPassword);
       System.out.println("clearTextPassword: "+clearTextPassword);
       System.out.println("hashedPassword: "+hashedPassword);
     }
  }

Step2). Now Open a terminal/Command prompt then set the PATH to include the JDK “bin” directory in it. Also we will set the CLASSPATH by including the “picketbox-4.0.7.Final.jar” and “jboss-client.jar” jar, which are required in order to compile and run the program. As soon as we will run the following program we will see the HashedPassword which we need to insert in the database “PRINCIPLES” table.


export JBOSS_HOME=/home/userone/jboss-as-7.1.1.Final

export CLASSPATH=$JBOSS_HOME/modules/org/picketbox/main/picketbox-4.0.7.Final.jar:$JBOSS_HOME/bin/client/jboss-client.jar:$CLASSPATH:.:

javac EncryptPassword.java 

java EncryptPassword admin123

_________

OUTPUT
_________

clearTextPassword: admin123
hashedPassword: 0192023a7bbd73250516f069df18b500

MySQL Database & Datasource configuration

First of all we will see what all configurations are needed at the Database end and the Datasource configuration.
Step3). Start the MySQL database and then create the following Tables with the required Data as mentioned:

CREATE TABLE PRINCIPLES ( principal_id VARCHAR(64) primary key,password VARCHAR(64));
CREATE TABLE ROLES ( principal_id VARCHAR(64),user_role VARCHAR(64),role_group VARCHAR(64));

Insert into PRINCIPLES values('adminUser','0192023a7bbd73250516f069df18b500');
Insert into ROLES values('adminUser','admin','admin');

You can insert more records in your database based on your requirement. I created only one Admin User.

mysql> select * from PRINCIPLES;
+--------------+----------------------------------+
| principal_id | password                         |
+--------------+----------------------------------+
| adminUser    | ec28e69f42b23f2e524572c4f263263d |
+--------------+----------------------------------+
1 row in set (0.00 sec)

***NOTE*** As you can see that actually the password for user “adminUser” is “admin123” but we entered the Encrypted password (0192023a7bbd73250516f069df18b500) for this user inside the Database not the Clear Text Password.

JBossAS7 side configuration

Step4). Place the MySQL database driver “mysql-connector-java-5.1.13-bin.jar” inside the “$JBOSS_HOME/standalone/deployments” directory.

Step5). Now start your JBossAS7 standalone profile as following:

[userone@localhost bin]$ ./standalone.sh -c standalone-full.xml -bmanagement 10.10.10.10 -b 20.20.20.20

NOTE: You can start your Server in localhost address as well. Here i started the JBoss Management interface at 10.10.10.10 Address where as the public interface on “20.20.20.20”.

Step6). It’s time to create a DataSource. So lets start the JBossAS7.1.1.Final and then open the JBoss CLI utility “$JBOSS_HOME/bin/jboss-cli.sh” then run the following command in order to create MySQL DataSource as following:

 [userone@localhost bin]$ ./jboss-cli.sh --connect --controller=10.10.10.10:9999

 [standalone@10.10.10.10:9999 /] /subsystem=datasources/data-source="java:jboss/MySqlDS":add(jndi-name="java:jboss/MySqlDS",pool-name="MySqlPool",driver-name="mysql-connector-java-5.1.13-bin.jar",connection-url="jdbc:mysql://localhost:3306/testDB",user-name="root",password="redhat")

Once the above command executes successfully executes you will see the following kind of entry inside your “$JBOSS_HOME/standalone/configuration/standalone-full.xml” file (Inside the “[subsystem xmlns=”urn:jboss:domain:datasources:1.0″]” subsystem):

   <datasource jndi-name="java:jboss/MySqlDS" pool-name="java:jboss/MySqlDS">
       <connection-url>jdbc:mysql://localhost:3306/testDB</connection-url>
       <driver>mysql-connector-java-5.1.13-bin.jar</driver>
       <security>
          <user-name>root</user-name>
          <password>redhat</password>
       </security>
   </datasource>

Step7). Now we will create a Security-Domain inside the “[subsystem xmlns=”urn:jboss:domain:security:1.1″]” subsystem of your “$JBOSS_HOME/standalone/configuration/standalone-full.xml” file as following:

  <security-domain name="DBAuthTest">
      <authentication>
         <login-module code="Database" flag="required">
            <module-option name="dsJndiName" value="java:jboss/MySqlDS"/>
            <module-option name="principalsQuery" value="select password from  PRINCIPLES where principal_id=?"/>
            <module-option name="rolesQuery" value="select user_role, 'Roles' from  ROLES where  principal_id=?"/>
            <module-option name="password-stacking" value="useFirstPass"/>

            <!-- Encryption Related module-options -->
            <module-option name="hashAlgorithm" value="MD5"/>
            <module-option name="hashEncoding" value="hex"/>

         </login-module>
         <login-module code="org.jboss.security.auth.spi.RoleMappingLoginModule" flag="optional">
            <module-option name="rolesProperties" value="${jboss.server.config.dir}/test-roles.properties"/>
            <module-option name="replaceRole" value="false"/>
         </login-module>
     </authentication>
   </security-domain>

Step8). As you can see above that in the “RoleMappingLoginModule” configuration we passed a file “test-roles.properties” for mapping the database user to the authorization role. So we will need to now create a file with name “test-roles.properties” inside the following location
“$JBOSS_HOME/standalone/configuration/test-roles.properties”
and
“$JBOSS_HOME/domain/configuration/test-roles.properties”

#username=RoleName
adminUser=admin

Step9). The Most important part now. We will edit the “$JBOSS_HOME/standalone/configuration/standalone-full.xml” file as well as “$JBOSS_HOME/domain/configuration/domain.xml” file <management> <security-realms> section as following sothat our custom security “DBAuthTest” can be associated with this ManagementRealm:

    <security-realm name="ManagementRealm">
        <authentication>
             <jaas name="DBAuthTest"/>
        </authentication>
    </security-realm>

Step10). Restart your JBossAS7 profile and then try to access the JBoss Console “http://10.10.10.10:9990/console” with the database table credential like
username: adminUser
password: admin123

.
.
Thanks 🙂
MiddlewareMagic Team


Configuring JBossAS7 ManagementRealm with the Database LoginModule

Hi,
Hi,
We have seen that using “$JBOSS_HOME/bin/add-user.sh” script we can create Management & Application Users. Using “add-user.sh” script when we create users then the credentials of Management user is stored inside the “$JBOSS_HOME/standalone/configuration/mgmt-users.properties” and inside the “$JBOSS_HOME/standalone/configuration/mgmt-users.properties” file. Even though the passwords are encrypted still many administrators like to store their management credentials inside the Database rather than storing them inside the Database.

So here as part of this Demo we will see how to create a Database authentication “security-domain” and how to associate the “ManagementRealm” with the “DBAuthTest” security-domain. We will need to follow the below mentioned steps in order to achieve the same.

MySQL Database & Datasource configuration

First of all we will see what all configurations are needed at the Database end and the Datasource configuration.
Step1). Start the MySQL database and then create the following Tables with the required Data as mentioned:

CREATE TABLE PRINCIPLES ( principal_id VARCHAR(64) primary key,password VARCHAR(64));
CREATE TABLE ROLES ( principal_id VARCHAR(64),user_role VARCHAR(64),role_group VARCHAR(64));

Insert into PRINCIPLES values('adminUser','admin123');
Insert into ROLES values('adminUser','admin','admin');

You can insert more records in your database based on your requirement. I created only one Admin User.

JBossAS7 side configuration

Step2). Place the MySQL database driver “mysql-connector-java-5.1.13-bin.jar” inside the “$JBOSS_HOME/standalone/deployments” directory.

Step3). Now start your JBossAS7 standalone profile as following:

[userone@localhost bin]$ ./standalone.sh -c standalone-full.xml -bmanagement 10.10.10.10 -b 20.20.20.20

NOTE: You can start your Server in localhost address as well. Here i started the JBoss Management interface at 10.10.10.10 Address where as the public interface on “20.20.20.20”.

Step4). It’s time to create a DataSource. So lets start the JBossAS7.1.1.Final and then open the JBoss CLI utility “$JBOSS_HOME/bin/jboss-cli.sh” then run the following command in order to create MySQL DataSource as following:

 [userone@localhost bin]$ ./jboss-cli.sh --connect --controller=10.10.10.10:9999

 [standalone@10.10.10.10:9999 /] /subsystem=datasources/data-source="java:jboss/MySqlDS":add(jndi-name="java:jboss/MySqlDS",pool-name="MySqlPool",driver-name="mysql-connector-java-5.1.13-bin.jar",connection-url="jdbc:mysql://localhost:3306/testDB",user-name="root",password="redhat")

Once the above command executes successfully executes you will see the following kind of entry inside your “$JBOSS_HOME/standalone/configuration/standalone-full.xml” file (Inside the “[subsystem xmlns=”urn:jboss:domain:datasources:1.0″]” subsystem):

   <datasource jndi-name="java:jboss/MySqlDS" pool-name="java:jboss/MySqlDS">
       <connection-url>jdbc:mysql://localhost:3306/testDB</connection-url>
       <driver>mysql-connector-java-5.1.13-bin.jar</driver>
       <security>
          <user-name>root</user-name>
          <password>redhat</password>
       </security>
   </datasource>

Step5). Now we will create a Security-Domain inside the “[subsystem xmlns=”urn:jboss:domain:security:1.1″]” subsystem of your “$JBOSS_HOME/standalone/configuration/standalone-full.xml” file as following:

   <security-domain name="DBAuthTest">
       <authentication>
           <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
               <module-option name="dsJndiName" value="java:jboss/MySqlDS"/>
               <module-option name="principalsQuery" value="select password from  PRINCIPLES where principal_id=?"/>
               <module-option name="rolesQuery" value="select user_role, 'Roles' from  ROLES where  principal_id=?"/>
           </login-module>
           <login-module code="org.jboss.security.auth.spi.RoleMappingLoginModule" flag="optional">
               <module-option name="rolesProperties" value="${jboss.server.config.dir}/test-roles.properties"/>
               <module-option name="replaceRole" value="false"/>
           </login-module>
       </authentication>
   </security-domain>

Step6). As you can see above that in the “RoleMappingLoginModule” configuration we passed a file “test-roles.properties” for mapping the database user to the authorization role. So we will need to now create a file with name “test-roles.properties” inside the following location
“$JBOSS_HOME/standalone/configuration/test-roles.properties”
and
“$JBOSS_HOME/domain/configuration/test-roles.properties”

#username=RoleName
adminUser=admin

Step7). The Most important part now. We will edit the “$JBOSS_HOME/standalone/configuration/standalone-full.xml” file as well as “$JBOSS_HOME/domain/configuration/domain.xml” file <management> <security-realms> section as following sothat our custom security “DBAuthTest” can be associated with this ManagementRealm:

    <security-realm name="ManagementRealm">
        <authentication>
             <jaas name="DBAuthTest"/>
        </authentication>
    </security-realm>

Step8). Restart your JBossAS7 profile and then try to access the JBoss Console “http://10.10.10.10:9990/console” with the database table credential like

[userone@localhost bin]$ ./standalone.sh -c standalone-full.xml -bmanagement 10.10.10.10 -b 20.20.20.20

username: adminUser
password: admin123

.
.
Thanks
MiddlewareMagic Team


Copyright © 2010-2012 Middleware Magic. All rights reserved. |