Ver Fonte

no message

student há 4 semanas atrás
commit
4ed621b03f
100 ficheiros alterados com 17528 adições e 0 exclusões
  1. 48 0
      .gitignore
  2. 73 0
      KittyFallWs/KittyFallWs/build.xml
  3. 3 0
      KittyFallWs/KittyFallWs/manifest.mf
  4. 1403 0
      KittyFallWs/KittyFallWs/nbproject/build-impl.xml
  5. 8 0
      KittyFallWs/KittyFallWs/nbproject/genfiles.properties
  6. 190 0
      KittyFallWs/KittyFallWs/nbproject/project.properties
  7. 13 0
      KittyFallWs/KittyFallWs/nbproject/project.xml
  8. 348 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/Common.java
  9. 83 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/Encrypt.java
  10. 368 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/EncryptUtil.java
  11. 84 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/MessageResponse.java
  12. 76 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/RouteManager.java
  13. 445 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/SentEmail.java
  14. 164 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/SmsSender.java
  15. 114 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/SmsWs.java
  16. 118 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/StaticCode.java
  17. 96 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/WebserviceAbstract.java
  18. 511 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/WebserviceManager.java
  19. 73 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/WebserviceObject.java
  20. 225 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/ConnectionPoolManager.java
  21. 347 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/ConnectionPoolObject.java
  22. 110 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/DbProcessorAbstract.java
  23. 7056 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/WsProcessUtils.java
  24. 51 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/ScanProcessManager.java
  25. 36 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/Start.java
  26. 18 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/Stop.java
  27. 24 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/test.java
  28. 693 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/Exchange.java
  29. 285 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/ExchangeChannel.java
  30. 277 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/ExchangeClientChannel.java
  31. 578 0
      KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/WSProcessor.java
  32. 3190 0
      KittyFallWs/KittyFallWs/src/com/vas/webservices/KittyFallWs.java
  33. 19 0
      KittyFallWs/etc/app.conf
  34. 34 0
      KittyFallWs/etc/database.xml
  35. 1 0
      KittyFallWs/etc/database.xml.ept
  36. 51 0
      KittyFallWs/etc/key/MYJOB_DAILY/PrivateKeyCP.pem
  37. 14 0
      KittyFallWs/etc/key/MYJOB_DAILY/PublicKeyCP.pem
  38. 14 0
      KittyFallWs/etc/key/MYJOB_DAILY/PublicKeyVT.pem
  39. 51 0
      KittyFallWs/etc/key/MYJOB_MONTHLY/PrivateKeyCP.pem
  40. 14 0
      KittyFallWs/etc/key/MYJOB_MONTHLY/PublicKeyCP.pem
  41. 14 0
      KittyFallWs/etc/key/MYJOB_MONTHLY/PublicKeyVT.pem
  42. 50 0
      KittyFallWs/etc/log.conf
  43. 22 0
      KittyFallWs/etc/loglevel.conf
  44. 3 0
      KittyFallWs/etc/route.xml
  45. 1 0
      KittyFallWs/etc/route.xml.ept
  46. 116 0
      KittyFallWs/etc/server.cfg
  47. 13 0
      KittyFallWs/etc/webservice.cfg
  48. 3 0
      KittyFallWs/etc/webservices.xml
  49. BIN
      KittyFallWs/lib/CollaborationAgent-2.1.jar
  50. BIN
      KittyFallWs/lib/PropertiesUtils.jar
  51. BIN
      KittyFallWs/lib/VasgwFW.jar
  52. BIN
      KittyFallWs/lib/activation.jar
  53. BIN
      KittyFallWs/lib/annotations-1.3.2.jar
  54. BIN
      KittyFallWs/lib/axis-ant.jar
  55. BIN
      KittyFallWs/lib/axis.jar
  56. BIN
      KittyFallWs/lib/bcprov-jdk16-141.jar
  57. BIN
      KittyFallWs/lib/c3p0-0.9.2.1.jar
  58. BIN
      KittyFallWs/lib/commons-codec-1.3.jar
  59. BIN
      KittyFallWs/lib/commons-collections-3.2.jar
  60. BIN
      KittyFallWs/lib/commons-dbcp-1.2.2.jar
  61. BIN
      KittyFallWs/lib/commons-discovery-0.2.jar
  62. BIN
      KittyFallWs/lib/commons-httpclient-3.1.jar
  63. BIN
      KittyFallWs/lib/commons-io-1.4.jar
  64. BIN
      KittyFallWs/lib/commons-lang-2.4.jar
  65. BIN
      KittyFallWs/lib/commons-logging-1.0.4.jar
  66. BIN
      KittyFallWs/lib/commons-net-2.0.jar
  67. BIN
      KittyFallWs/lib/commons-pool-1.3.jar
  68. BIN
      KittyFallWs/lib/commons-v2.1-yc14.jar
  69. BIN
      KittyFallWs/lib/commons-v2.2.jar
  70. BIN
      KittyFallWs/lib/commons.jar
  71. BIN
      KittyFallWs/lib/gson-2.2.2.jar
  72. BIN
      KittyFallWs/lib/httpclient-4.0.jar
  73. BIN
      KittyFallWs/lib/httpcore-4.0.1.jar
  74. BIN
      KittyFallWs/lib/httpmime-4.0.jar
  75. BIN
      KittyFallWs/lib/javax.ws.rs-api-2.0.jar
  76. BIN
      KittyFallWs/lib/javax.ws.rs.jar
  77. BIN
      KittyFallWs/lib/javax.xml.soap-3.1.jar
  78. BIN
      KittyFallWs/lib/jaxrpc.jar
  79. BIN
      KittyFallWs/lib/jep.jar
  80. BIN
      KittyFallWs/lib/jgroups-2.10.0.GA.jar
  81. BIN
      KittyFallWs/lib/json-lib-2.4-jdk15.jar
  82. BIN
      KittyFallWs/lib/json.jar
  83. BIN
      KittyFallWs/lib/jsonwebservice-ri-0.8.0.jar
  84. BIN
      KittyFallWs/lib/log4j-1.2.15-ext.jar
  85. BIN
      KittyFallWs/lib/log4j-1.2.15.jar
  86. BIN
      KittyFallWs/lib/mail.jar
  87. BIN
      KittyFallWs/lib/mchange-commons-java-0.2.3.4.jar
  88. BIN
      KittyFallWs/lib/mina-core-2.0.0-M5.jar
  89. BIN
      KittyFallWs/lib/mmserver-3.2.jar
  90. BIN
      KittyFallWs/lib/mysql-connector-java-5.1.37-bin.jar
  91. BIN
      KittyFallWs/lib/ojdbc7-12.1.0.2.jar
  92. BIN
      KittyFallWs/lib/org-netbeans-modules-java-j2seproject-copylibstask.jar
  93. BIN
      KittyFallWs/lib/org-openide-util.jar
  94. BIN
      KittyFallWs/lib/portal-kernel.jar
  95. BIN
      KittyFallWs/lib/sendmt.jar
  96. BIN
      KittyFallWs/lib/slf4j-api-1.5.6.jar
  97. BIN
      KittyFallWs/lib/slf4j-jdk14-1.5.6.jar
  98. BIN
      KittyFallWs/lib/telnetd2.jar
  99. BIN
      KittyFallWs/lib/ultis.jar
  100. BIN
      KittyFallWs/lib/utils.jar

+ 48 - 0
.gitignore

@@ -0,0 +1,48 @@
+# Build output
+bin/
+obj/
+Debug/
+Release/
+x64/
+x86/
+
+# Visual Studio / Rider / VS Code local state
+.vs/
+.idea/
+.vscode/
+*.user
+*.suo
+*.userosscache
+*.sln.docstates
+
+# .NET generated files
+project.assets.json
+project.nuget.cache
+*.nuget.g.props
+*.nuget.g.targets
+*.nupkg
+
+# Logs and temp files
+*.log
+*.tmp
+*.temp
+*.cache
+.tmp*/
+tmp/
+temp/
+
+# Local run output
+logs/
+Logs/
+
+# NetBeans generated files
+/KittyFallWs/KittyFallWs/nbproject/private/
+/KittyFallWs/KittyFallWs/dist/
+/KittyFallWs/KittyFallWs/build/
+
+# Raw design/input files copied locally
+/kitty_css/
+/kitty_css.zip
+/*.xlsx
+/Kich_ban_dich_vu_Kitty_Fall.txt
+/Ke_hoach_thiet_ke_database_game_Kitty_Fall.txt

+ 73 - 0
KittyFallWs/KittyFallWs/build.xml

@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="KittyFallWs" default="default" basedir=".">
+    <description>Builds, tests, and runs the project KittyFallWs.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties
+      -post-init:                called after initialization of project properties
+      -pre-compile:              called before javac compilation
+      -post-compile:             called after javac compilation
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-jar:                  called before JAR building
+      -post-jar:                 called after JAR building
+      -post-clean:               called after cleaning build products
+
+    (Targets beginning with '-' are not intended to be called on their own.)
+
+    Example of inserting an obfuscator after compilation could look like this:
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Another way to customize the build is by overriding existing main targets.
+    The targets of interest are: 
+
+      -init-macrodef-javac:     defines macro for javac compilation
+      -init-macrodef-junit:     defines macro for junit execution
+      -init-macrodef-debug:     defines macro for class debugging
+      -init-macrodef-java:      defines macro for class execution
+      -do-jar:                  JAR building
+      run:                      execution of project 
+      -javadoc-build:           Javadoc generation
+      test-report:              JUnit report generation
+
+    An example of overriding the target for project execution could look like this:
+
+        <target name="run" depends="KittyFallWs-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that the overridden target depends on the jar target and not only on 
+    the compile target as the regular run target does. Again, for a list of available 
+    properties which you can use, check the target you are overriding in the
+    nbproject/build-impl.xml file. 
+
+    -->
+</project>

+ 3 - 0
KittyFallWs/KittyFallWs/manifest.mf

@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+X-COMMENT: Main-Class will be added automatically by build
+

+ 1403 - 0
KittyFallWs/KittyFallWs/nbproject/build-impl.xml

@@ -0,0 +1,1403 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+  - initialization
+  - compilation
+  - jar
+  - execution
+  - debugging
+  - javadoc
+  - test compilation
+  - test execution
+  - test debugging
+  - applet
+  - cleanup
+
+        -->
+<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="KittyFallWs-impl">
+    <fail message="Please build using Ant 1.8.0 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.8.0"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+    <!-- 
+                ======================
+                INITIALIZATION SECTION 
+                ======================
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/config.properties"/>
+        <property file="nbproject/private/configs/${config}.properties"/>
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.6"/>
+        <property name="default.javac.target" value="1.6"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user" name="-init-project">
+        <property file="nbproject/configs/${config}.properties"/>
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-init-macrodef-property" name="-do-init">
+        <property name="platform.java" value="${java.home}/bin/java"/>
+        <available file="${manifest.file}" property="manifest.available"/>
+        <condition property="splashscreen.available">
+            <and>
+                <not>
+                    <equals arg1="${application.splash}" arg2="" trim="true"/>
+                </not>
+                <available file="${application.splash}"/>
+            </and>
+        </condition>
+        <condition property="main.class.available">
+            <and>
+                <isset property="main.class"/>
+                <not>
+                    <equals arg1="${main.class}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="profile.available">
+            <and>
+                <isset property="javac.profile"/>
+                <length length="0" string="${javac.profile}" when="greater"/>
+                <matches pattern="((1\.[89])|9)(\..*)?" string="${javac.source}"/>
+            </and>
+        </condition>
+        <condition property="do.archive">
+            <or>
+                <not>
+                    <istrue value="${jar.archive.disabled}"/>
+                </not>
+                <istrue value="${not.archive.disabled}"/>
+            </or>
+        </condition>
+        <condition property="do.mkdist">
+            <and>
+                <isset property="do.archive"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <not>
+                    <istrue value="${mkdist.disabled}"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.archive+manifest.available">
+            <and>
+                <isset property="manifest.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+main.class.available">
+            <and>
+                <isset property="main.class.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+splashscreen.available">
+            <and>
+                <isset property="splashscreen.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+profile.available">
+            <and>
+                <isset property="profile.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="have.tests">
+            <or/>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <and>
+                <isset property="javadoc.preview"/>
+                <isfalse value="${javadoc.preview}"/>
+            </and>
+        </condition>
+        <property name="run.jvmargs" value=""/>
+        <property name="run.jvmargs.ide" value=""/>
+        <property name="javac.compilerargs" value=""/>
+        <property name="work.dir" value="${basedir}"/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <property name="javac.debug" value="true"/>
+        <property name="javadoc.preview" value="true"/>
+        <property name="application.args" value=""/>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <property name="runtime.encoding" value="${source.encoding}"/>
+        <property name="manifest.encoding" value="${source.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="do.depend" value="false"/>
+        <condition property="do.depend.true">
+            <istrue value="${do.depend}"/>
+        </condition>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <not>
+                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
+            <isset property="profile.available"/>
+        </condition>
+        <condition else="false" property="jdkBug6558476">
+            <and>
+                <matches pattern="1\.[56]" string="${java.specification.version}"/>
+                <not>
+                    <os family="unix"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="javac.fork">
+            <or>
+                <istrue value="${jdkBug6558476}"/>
+                <istrue value="${javac.external.vm}"/>
+            </or>
+        </condition>
+        <property name="jar.index" value="false"/>
+        <property name="jar.index.metainf" value="${jar.index}"/>
+        <property name="copylibs.rebase" value="true"/>
+        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <property name="java.failonerror" value="true"/>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.dir">Must set src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.jar">Must set dist.jar</fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete>
+                    <fileset file="${javac.includesfile.binary}"/>
+                </delete>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set"/>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="KittyFallWs" testname="TestNG tests" workingDir="${work.dir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-debug" unless="${nb.junit.batch}">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties" if="${nb.junit.batch}" name="-init-macrodef-junit-debug-batch">
+        <macrodef name="junit-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <batchtest todir="${build.test.results.dir}">
+                        <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                            <filename name="${test.binarytestincludes}"/>
+                        </fileset>
+                    </batchtest>
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <customize/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug,-init-macrodef-junit-debug-batch" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-debug excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename KittyFallWs -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+                    <customize>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                        <arg line="${testng.cmd.args}"/>
+                    </customize>
+                </j2seproject3:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </j2seproject3:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <classpath>
+                            <path path="${run.test.classpath}"/>
+                        </classpath>
+                        <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </j2seproject3:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
+        <macrodef name="resolve">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${env.@{value}}"/>
+            </sequential>
+        </macrodef>
+        <macrodef name="profile">
+            <attribute default="${main.class}" name="classname"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property environment="env"/>
+                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+                <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                    <jvmarg line="${profiler.info.jvmargs}"/>
+                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                    <arg line="${application.args}"/>
+                    <classpath>
+                        <path path="${run.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <attribute default="" name="stopclassname"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <property name="version-output" value="java version &quot;${ant.java.version}"/>
+        <condition property="have-jdk-older-than-1.4">
+            <or>
+                <contains string="${version-output}" substring="java version &quot;1.0"/>
+                <contains string="${version-output}" substring="java version &quot;1.1"/>
+                <contains string="${version-output}" substring="java version &quot;1.2"/>
+                <contains string="${version-output}" substring="java version &quot;1.3"/>
+            </or>
+        </condition>
+        <condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
+            <istrue value="${have-jdk-older-than-1.4}"/>
+        </condition>
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg line="${debug-args-line}"/>
+                    <jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-java">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-copylibs">
+        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${manifest.file}" name="manifest"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+                <pathconvert property="run.classpath.without.build.classes.dir">
+                    <path path="${run.classpath}"/>
+                    <map from="${build.classes.dir.resolved}" to=""/>
+                </pathconvert>
+                <pathconvert pathsep=" " property="jar.classpath">
+                    <path path="${run.classpath.without.build.classes.dir}"/>
+                    <chainedmapper>
+                        <flattenmapper/>
+                        <filtermapper>
+                            <replacestring from=" " to="%20"/>
+                        </filtermapper>
+                        <globmapper from="*" to="lib/*"/>
+                    </chainedmapper>
+                </pathconvert>
+                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" manifestencoding="UTF-8" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+                    <manifest>
+                        <attribute name="Class-Path" value="${jar.classpath}"/>
+                        <customize/>
+                    </manifest>
+                </copylibs>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-presetdef-jar">
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifestencoding="UTF-8">
+                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+            </jar>
+        </presetdef>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.processor.options" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+    <!--
+                ===================
+                COMPILATION SECTION
+                ===================
+            -->
+    <target name="-deps-jar-init" unless="built-jar.properties">
+        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+        <delete file="${built-jar.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+        <echo level="warn" message="Cycle detected: KittyFallWs was already built"/>
+    </target>
+    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-jar.properties}" verbose="false"/>
+        <property file="${built-jar.properties}" prefix="already.built.jar."/>
+        <antcall target="-warn-already-built-jar"/>
+        <propertyfile file="${built-jar.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+    <target depends="init" name="-check-automatic-build">
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+    </target>
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+        <antcall target="clean"/>
+    </target>
+    <target depends="init,deps-jar" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-depend">
+        <pathconvert property="build.generated.subdirs">
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="*"/>
+            </dirset>
+        </pathconvert>
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy todir="${build.classes.dir}/META-INF">
+            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <!--
+                ====================
+                JAR BUILDING SECTION
+                ====================
+            -->
+    <target depends="init" name="-pre-pre-jar">
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+    </target>
+    <target name="-pre-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <touch file="${tmp.manifest.file}" verbose="false"/>
+    </target>
+    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <copy encoding="${manifest.encoding}" file="${manifest.file}" outputencoding="UTF-8" tofile="${tmp.manifest.file}"/>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="Main-Class" value="${main.class}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="Profile" value="${javac.profile}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
+        <basename file="${application.splash}" property="splashscreen.basename"/>
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+        </manifest>
+    </target>
+    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.mkdist" name="-do-jar-copylibs">
+        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+        <echo level="info">To run this application from the command line without Ant, try:</echo>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <echo level="info">java -jar "${dist.jar.resolved}"</echo>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+        <j2seproject1:jar manifest="${tmp.manifest.file}"/>
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <pathconvert property="run.classpath.with.dist.jar">
+            <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+        </pathconvert>
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java} -cp ${run.classpath.with.dist.jar} ${main.class}">
+            <isset property="main.class.available"/>
+        </condition>
+        <condition else="debug" property="jar.usage.level" value="info">
+            <isset property="main.class.available"/>
+        </condition>
+        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
+    </target>
+    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
+        <delete>
+            <fileset file="${tmp.manifest.file}"/>
+        </delete>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
+    <target name="-post-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-jar,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar" description="Build JAR." name="jar"/>
+    <!--
+                =================
+                EXECUTION SECTION
+                =================
+            -->
+    <target depends="init,compile" description="Run a main class." name="run">
+        <j2seproject1:java>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <target name="-do-not-recompile">
+        <property name="javac.includes.binary" value=""/>
+    </target>
+    <target depends="init,compile-single" name="run-single">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <!--
+                =================
+                DEBUGGING SECTION
+                =================
+            -->
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <j2seproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init,compile" name="-debug-start-debuggee">
+        <j2seproject3:debug>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+    </target>
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <j2seproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+                =================
+                PROFILING SECTION
+                =================
+            -->
+    <!--
+                pre NB7.2 profiler integration
+            -->
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile/>
+    </target>
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
+        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="${profile.class}"/>
+    </target>
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </profile>
+    </target>
+    <target depends="profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <junit dir="${profiler.info.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${profiler.info.jvm}" showoutput="true">
+            <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+            <jvmarg value="${profiler.info.jvmargs.agent}"/>
+            <jvmarg line="${profiler.info.jvmargs}"/>
+            <test name="${profile.class}"/>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+            <syspropertyset>
+                <propertyref prefix="test-sys-prop."/>
+                <mapper from="test-sys-prop.*" to="*" type="glob"/>
+            </syspropertyset>
+            <formatter type="brief" usefile="false"/>
+            <formatter type="xml"/>
+        </junit>
+    </target>
+    <!--
+                end of pre NB72 profiling section
+            -->
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="run"/>
+    </target>
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-single"/>
+    </target>
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-test-with-main"/>
+    </target>
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <startprofiler/>
+        <antcall target="run-applet"/>
+    </target>
+    <!--
+                ===============
+                JAVADOC SECTION
+                ===============
+            -->
+    <target depends="init" if="have.sources" name="-javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
+            <and>
+                <isset property="endorsed.classpath.cmd.line.arg"/>
+                <not>
+                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="bug5101868workaround" value="*.java">
+            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
+        </condition>
+        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}"/>
+            </classpath>
+            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+                <exclude name="*.java"/>
+            </fileset>
+            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                =========================
+                TEST COMPILATION SECTION
+                =========================
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-test-depend">
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir=""/>
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" processorpath="${javac.test.processorpath}" srcdir=""/>
+        <copy todir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,compile,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}" processorpath="${javac.test.processorpath}" sourcepath="" srcdir=""/>
+        <copy todir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                =======================
+                TEST EXECUTION SECTION
+                =======================
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run" if="have.tests" name="-do-test-run">
+        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                =======================
+                TEST DEBUGGING SECTION
+                =======================
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                =========================
+                APPLET EXECUTION SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" name="run-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject1:java classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <!--
+                =========================
+                APPLET DEBUGGING  SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject3:debug classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+    <!--
+                ===============
+                CLEANUP SECTION
+                ===============
+            -->
+    <target name="-deps-clean-init" unless="built-clean.properties">
+        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+        <delete file="${built-clean.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+        <echo level="warn" message="Cycle detected: KittyFallWs was already built"/>
+    </target>
+    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-clean.properties}" verbose="false"/>
+        <property file="${built-clean.properties}" prefix="already.built.clean."/>
+        <antcall target="-warn-already-built-clean"/>
+        <propertyfile file="${built-clean.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init" name="-do-clean">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target name="-check-call-dep">
+        <property file="${call.built.properties}" prefix="already.built."/>
+        <condition property="should.call.dep">
+            <and>
+                <not>
+                    <isset property="already.built.${call.subproject}"/>
+                </not>
+                <available file="${call.script}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+            <propertyset>
+                <propertyref prefix="transfer."/>
+                <mapper from="transfer.*" to="*" type="glob"/>
+            </propertyset>
+        </ant>
+    </target>
+</project>

+ 8 - 0
KittyFallWs/KittyFallWs/nbproject/genfiles.properties

@@ -0,0 +1,8 @@
+build.xml.data.CRC32=3733161b
+build.xml.script.CRC32=de576a7b
+build.xml.stylesheet.CRC32=8064a381@1.80.1.48
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=3733161b
+nbproject/build-impl.xml.script.CRC32=add137f0
+nbproject/build-impl.xml.stylesheet.CRC32=830a3534@1.80.1.48

+ 190 - 0
KittyFallWs/KittyFallWs/nbproject/project.properties

@@ -0,0 +1,190 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processor.options=
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.test.classpath=\
+    ${run.test.classpath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/KittyFallWs.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+excludes=
+file.reference.activation.jar=..\\lib\\activation.jar
+file.reference.annotations-1.3.2.jar=..\\lib\\annotations-1.3.2.jar
+file.reference.axis-ant.jar=..\\lib\\axis-ant.jar
+file.reference.axis.jar=..\\lib\\axis.jar
+file.reference.bcprov-jdk16-141.jar=..\\lib\\bcprov-jdk16-141.jar
+file.reference.c3p0-0.9.2.1.jar=..\\lib\\c3p0-0.9.2.1.jar
+file.reference.CollaborationAgent-2.1.jar=..\\lib\\CollaborationAgent-2.1.jar
+file.reference.commons-codec-1.3.jar=..\\lib\\commons-codec-1.3.jar
+file.reference.commons-collections-3.2.jar=..\\lib\\commons-collections-3.2.jar
+file.reference.commons-dbcp-1.2.2.jar=..\\lib\\commons-dbcp-1.2.2.jar
+file.reference.commons-discovery-0.2.jar=..\\lib\\commons-discovery-0.2.jar
+file.reference.commons-httpclient-3.1.jar=..\\lib\\commons-httpclient-3.1.jar
+file.reference.commons-io-1.4.jar=..\\lib\\commons-io-1.4.jar
+file.reference.commons-lang-2.4.jar=..\\lib\\commons-lang-2.4.jar
+file.reference.commons-logging-1.0.4.jar=..\\lib\\commons-logging-1.0.4.jar
+file.reference.commons-net-2.0.jar=..\\lib\\commons-net-2.0.jar
+file.reference.commons-pool-1.3.jar=..\\lib\\commons-pool-1.3.jar
+file.reference.commons-v2.1-yc14.jar=..\\lib\\commons-v2.1-yc14.jar
+file.reference.commons-v2.2.jar=..\\lib\\commons-v2.2.jar
+file.reference.commons.jar=..\\lib\\commons.jar
+file.reference.gson-2.2.2.jar=..\\lib\\gson-2.2.2.jar
+file.reference.httpclient-4.0.jar=..\\lib\\httpclient-4.0.jar
+file.reference.httpcore-4.0.1.jar=..\\lib\\httpcore-4.0.1.jar
+file.reference.httpmime-4.0.jar=..\\lib\\httpmime-4.0.jar
+file.reference.javax.ws.rs-api-2.0.jar=..\\lib\\javax.ws.rs-api-2.0.jar
+file.reference.javax.ws.rs.jar=..\\lib\\javax.ws.rs.jar
+file.reference.javax.xml.soap-3.1.jar=..\\lib\\javax.xml.soap-3.1.jar
+file.reference.jaxrpc.jar=..\\lib\\jaxrpc.jar
+file.reference.jep.jar=..\\lib\\jep.jar
+file.reference.jgroups-2.10.0.GA.jar=..\\lib\\jgroups-2.10.0.GA.jar
+file.reference.json-lib-2.4-jdk15.jar=..\\lib\\json-lib-2.4-jdk15.jar
+file.reference.json.jar=..\\lib\\json.jar
+file.reference.jsonwebservice-ri-0.8.0.jar=..\\lib\\jsonwebservice-ri-0.8.0.jar
+file.reference.KittyFallWs-src=src
+file.reference.log4j-1.2.15-ext.jar=..\\lib\\log4j-1.2.15-ext.jar
+file.reference.log4j-1.2.15.jar=..\\lib\\log4j-1.2.15.jar
+file.reference.mail.jar=..\\lib\\mail.jar
+file.reference.mchange-commons-java-0.2.3.4.jar=..\\lib\\mchange-commons-java-0.2.3.4.jar
+file.reference.mina-core-2.0.0-M5.jar=..\\lib\\mina-core-2.0.0-M5.jar
+file.reference.mmserver-3.2.jar=..\\lib\\mmserver-3.2.jar
+file.reference.mysql-connector-java-5.1.37-bin.jar=..\\lib\\mysql-connector-java-5.1.37-bin.jar
+file.reference.ojdbc7-12.1.0.2.jar=..\\lib\\ojdbc7-12.1.0.2.jar
+file.reference.org-netbeans-modules-java-j2seproject-copylibstask.jar=..\\lib\\org-netbeans-modules-java-j2seproject-copylibstask.jar
+file.reference.org-openide-util.jar=..\\lib\\org-openide-util.jar
+file.reference.portal-kernel.jar=..\\lib\\portal-kernel.jar
+file.reference.PropertiesUtils.jar=..\\lib\\PropertiesUtils.jar
+file.reference.sendmt.jar=..\\lib\\sendmt.jar
+file.reference.slf4j-api-1.5.6.jar=..\\lib\\slf4j-api-1.5.6.jar
+file.reference.slf4j-jdk14-1.5.6.jar=..\\lib\\slf4j-jdk14-1.5.6.jar
+file.reference.telnetd2.jar=..\\lib\\telnetd2.jar
+file.reference.ultis.jar=..\\lib\\ultis.jar
+file.reference.utils.jar=..\\lib\\utils.jar
+file.reference.VasgwFW.jar=..\\lib\\VasgwFW.jar
+file.reference.vaspapi.jar=..\\lib\\vaspapi.jar
+file.reference.viettel-lib-2.0.jar=..\\lib\\viettel-lib-2.0.jar
+file.reference.viettelsecurity.2.0.jar=..\\lib\\viettelsecurity.2.0.jar
+file.reference.vsa3-vpclient-ws-1.0.jar=..\\lib\\vsa3-vpclient-ws-1.0.jar
+file.reference.vsa3-vptoken-1.0.jar=..\\lib\\vsa3-vptoken-1.0.jar
+file.reference.wsdl4j-1.5.1.jar=..\\lib\\wsdl4j-1.5.1.jar
+includes=**
+jar.compress=false
+javac.classpath=\
+    ${file.reference.CollaborationAgent-2.1.jar}:\
+    ${file.reference.PropertiesUtils.jar}:\
+    ${file.reference.VasgwFW.jar}:\
+    ${file.reference.activation.jar}:\
+    ${file.reference.annotations-1.3.2.jar}:\
+    ${file.reference.axis-ant.jar}:\
+    ${file.reference.axis.jar}:\
+    ${file.reference.bcprov-jdk16-141.jar}:\
+    ${file.reference.c3p0-0.9.2.1.jar}:\
+    ${file.reference.commons-codec-1.3.jar}:\
+    ${file.reference.commons-collections-3.2.jar}:\
+    ${file.reference.commons-dbcp-1.2.2.jar}:\
+    ${file.reference.commons-discovery-0.2.jar}:\
+    ${file.reference.commons-httpclient-3.1.jar}:\
+    ${file.reference.commons-io-1.4.jar}:\
+    ${file.reference.commons-lang-2.4.jar}:\
+    ${file.reference.commons-logging-1.0.4.jar}:\
+    ${file.reference.commons-net-2.0.jar}:\
+    ${file.reference.commons-pool-1.3.jar}:\
+    ${file.reference.commons-v2.1-yc14.jar}:\
+    ${file.reference.commons-v2.2.jar}:\
+    ${file.reference.commons.jar}:\
+    ${file.reference.gson-2.2.2.jar}:\
+    ${file.reference.httpclient-4.0.jar}:\
+    ${file.reference.httpcore-4.0.1.jar}:\
+    ${file.reference.httpmime-4.0.jar}:\
+    ${file.reference.javax.ws.rs-api-2.0.jar}:\
+    ${file.reference.javax.ws.rs.jar}:\
+    ${file.reference.javax.xml.soap-3.1.jar}:\
+    ${file.reference.jaxrpc.jar}:\
+    ${file.reference.jep.jar}:\
+    ${file.reference.jgroups-2.10.0.GA.jar}:\
+    ${file.reference.json-lib-2.4-jdk15.jar}:\
+    ${file.reference.json.jar}:\
+    ${file.reference.jsonwebservice-ri-0.8.0.jar}:\
+    ${file.reference.log4j-1.2.15-ext.jar}:\
+    ${file.reference.log4j-1.2.15.jar}:\
+    ${file.reference.mail.jar}:\
+    ${file.reference.mchange-commons-java-0.2.3.4.jar}:\
+    ${file.reference.mina-core-2.0.0-M5.jar}:\
+    ${file.reference.mmserver-3.2.jar}:\
+    ${file.reference.mysql-connector-java-5.1.37-bin.jar}:\
+    ${file.reference.ojdbc7-12.1.0.2.jar}:\
+    ${file.reference.org-netbeans-modules-java-j2seproject-copylibstask.jar}:\
+    ${file.reference.org-openide-util.jar}:\
+    ${file.reference.portal-kernel.jar}:\
+    ${file.reference.sendmt.jar}:\
+    ${file.reference.slf4j-api-1.5.6.jar}:\
+    ${file.reference.slf4j-jdk14-1.5.6.jar}:\
+    ${file.reference.telnetd2.jar}:\
+    ${file.reference.ultis.jar}:\
+    ${file.reference.utils.jar}:\
+    ${file.reference.vaspapi.jar}:\
+    ${file.reference.viettel-lib-2.0.jar}:\
+    ${file.reference.viettelsecurity.2.0.jar}:\
+    ${file.reference.vsa3-vpclient-ws-1.0.jar}:\
+    ${file.reference.vsa3-vptoken-1.0.jar}:\
+    ${file.reference.wsdl4j-1.5.1.jar}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.external.vm=true
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=1.8
+javac.target=1.8
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+main.class=
+manifest.file=manifest.mf
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=false
+platform.active=default_platform
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project.
+# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
+# To set system properties for unit tests define test-sys-prop.name=value:
+run.jvmargs=
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+source.encoding=UTF-8
+src.dir=${file.reference.KittyFallWs-src}

+ 13 - 0
KittyFallWs/KittyFallWs/nbproject/project.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.java.j2seproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+            <name>KittyFallWs</name>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots/>
+        </data>
+    </configuration>
+</project>

+ 348 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/Common.java

@@ -0,0 +1,348 @@
+/*
+ * Copyright 2011 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import com.vas.kittyfallwsvas.wsfw.obj.ListPrize;
+import com.vas.kittyfallwsvas.wsfw.obj.MpsConfigObj;
+import com.vas.kittyfallwsvas.wsfw.obj.ProductInfo;
+import com.vas.kittyfallwsvas.wsfw.services.WSProcessor;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ *
+ * @author: TungTT
+ * @version 2.0
+ * @since: April 18, 2011
+ */
+public class Common {
+
+    public static HashMap listConfig;
+    public static boolean iLoadConfig = true;
+    public static String CHANNEL;
+    public static AtomicLong counterTransId = new AtomicLong(1000000);
+    public static int ADD_SPIN_FEE;
+    public static int ADD_SPIN_TIMES;
+    public static int MAX_WIN;
+    public static int REGISTER_FEE;
+    public static double SPIN_FEE;
+    public static int INVITE_POINT;
+    public static int MONEY_LIMIT;
+    public static int PERCENT_LIMIT;
+    public static String COUNTRY_CODE;
+    public static List<ProductInfo> listProduct;
+    public static HashMap<String, ListPrize> mapPrize;
+    public static Date END_DATE_FREE;
+    public static int MAX_PRESENT_PERDAY;
+    public static HashMap<String, MpsConfigObj> mapMpsConfig;
+//    public static String COUNTRY_CODE;
+
+    public static void loadConfig() throws ParseException {
+        // load cau hinh
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+        iLoadConfig = false;
+        Common.CHANNEL = Common.listConfig.get("CHANNEL").toString();
+        Common.COUNTRY_CODE = Common.listConfig.get("COUNTRY_CODE").toString();
+        Common.ADD_SPIN_FEE = Integer.parseInt(Common.listConfig.get("ADD_SPIN_FEE").toString());
+        Common.SPIN_FEE = Double.parseDouble(Common.listConfig.get("SPIN_FEE").toString());
+        Common.INVITE_POINT = Integer.parseInt(Common.listConfig.get("INVITE_POINT").toString());
+        Common.ADD_SPIN_TIMES = Integer.parseInt(Common.listConfig.get("ADD_SPIN_TIMES").toString());
+        try {
+            MONEY_LIMIT = Integer.parseInt(Common.listConfig.get("MONEY_LIMIT").toString());
+        } catch (Exception ex) {
+            MONEY_LIMIT = 3000;
+        }
+        try {
+            PERCENT_LIMIT = Integer.parseInt(Common.listConfig.get("PERCENT_LIMIT").toString());
+        } catch (Exception ex) {
+            PERCENT_LIMIT = 10;
+        }
+        try {
+            MAX_PRESENT_PERDAY = Integer.parseInt(Common.listConfig.get("MAX_PRESENT_PERDAY").toString());
+        } catch (Exception ex) {
+            MAX_PRESENT_PERDAY = 0;// not limit
+        }
+//        END_DATE_FREE = sdf.parse(Common.listConfig.get("END_DATE_FREE").toString());
+
+        WSProcessor.ACCOUNT_BLOCKED_RES = Arrays.asList(Common.listConfig.get("ACCOUNT_BLOCKED_RES").toString().split(","));
+        WSProcessor.LIST_SUCCESS_RES = Arrays.asList(Common.listConfig.get("LIST_SUCCESS_RES").toString().split(","));
+        WSProcessor.LIST_CANCEL_SUCCESS_RES = Arrays.asList(Common.listConfig.get("LIST_CANCEL_SUCCESS_RES").toString().split(","));
+        WSProcessor.NOT_ENOUGH_MONEY_RES = Arrays.asList(Common.listConfig.get("NOT_ENOUGH_MONEY_RES").toString().split(","));
+    }
+
+    public class Constant {
+        public static final String FUNQUIZ_SERVICEID = "5";
+
+        public static final long STATUS_ACTIVE = 1L; //trang thai co hieu luc
+        public static final long STATUS_INACTIVE = 0L; //trang thai khong hieu luc
+        public static final double AMOUNT_RATE = 10000;
+        public static final double AMOUNT_RATE_IM = 11000;
+        public static final String MAX_ANYPAY_AMOUNT = "MAX_ANYPAY_AMOUNT";
+
+        public static final String REGISTER_DAILY_HEALTH = "Health_daily";
+        public static final String REGISTER_DAILY_LOT = "Lot_daily";
+        public static final String REGISTER_DAILY_NEWS = "News_daily";
+
+        public static final String OFF_DAILY_HEALTH = "OFF2";
+        public static final String OFF_DAILY_LOT = "OFF1";
+        public static final String OFF_DAILY_NEWS = "OFF3";
+
+        public static final String DESCRIBER_HEALTH = "Health news";
+        public static final String DESCRIBER_LOT = "Lottery predictions";
+        public static final String DESCRIBER_NEWS = "newest News in Laos";
+
+        public static final String OUT_OF_TURN = "0";
+        public static final String IN_TURN = "1";
+        public static final String FOREIGN_LANGUAGE = "0";
+        public static final String GLOBAL_LANGUAGE = "1";
+        public static final int SPIN_FREE = 5;
+        public static final int MAX_MINIGAME_REWARD = 2;
+        public static final int MONEY_MINIGAME_REWARD = 1500;
+        public static final int MONEY_HIGHEST_PLAYING_TIMES_REWARD = 50;
+
+        public static final int HOUR_ADD_MONEY_HIGHEST_PLAYING_TIMES = 1;
+        public static final int HOUR_SMS_HIGHEST_PLAYING_TIMES = 2;
+
+        public static final String PLAYING_TIMES_ENABLE = "PLAYING_TIMES_ENABLE";
+        public static final String TIME_ADD_MONEY = "TIME_ADD_MONEY";
+        public static final String TIME_SEND_MT = "TIME_SEND_MT";
+
+        public static final String TRIGGER_TIME_REPORT = "TRIGGER_TIME_REPORT";
+        public static final String TRIGGER_PHONE_REPORT = "TRIGGER_PHONE_REPORT";
+        public static final int REGISTER_STATUS = 1;
+        public static final int CANCEL_STATUS = 0;
+        public static final int RENEW_STATUS = 2;
+        public static final int CHARGE_STATUS = 3;
+        public static final int UNCHARGE_STATUS = 4;
+
+        
+        public static final String MR_DAY = "MINHA_VIBE_MR_DAY";
+
+    }
+
+    public class Message {
+
+        public static final String SYSTEM_FAIL = "SYSTEM_FAIL";
+        public static final String SYNTAX_ERROR = "SYNTAX_ERROR";
+        public static final String LOGIN_FAIL = "LOGIN_FAIL";
+        public static final String GET_ACTIVE_CODE = "GET_ACTIVE_CODE";
+        public static final String GET_REGISTER_CODE = "GET_REGISTER_CODE";
+        public static final String ACTIVATE_SUCCESS = "ACTIVATE_SUCCESS";
+        public static final String REGISTER_SUCCESS = "REGISTER_SUCCESS";
+        public static final String DISABLE_EXTEND_SUCCESS = "DISABLE_EXTEND_SUCCESS";
+        public static final String ENABLE_EXTEND_SUCCESS = "ENABLE_EXTEND_SUCCESS";
+        public static final String RESET_PASSWORD_SUCCESS = "RESET_PASSWORD_SUCCESS";
+        public static final String REGISTER_SUCCESS_USSD = "REGISTER_SUCCESS_USSD";
+        public static final String CREATE_ACCOUNT_SUCCESS = "CREATE_ACCOUNT_SUCCESS";
+        public static final String INVITE_FRIEND_SUCCESS = "INVITE_FRIEND_SUCCESS";
+        public static final String INVITE_TO_SERVICE_SUCCESS = "INVITE_TO_SERVICE_SUCCESS";
+
+        public static final String INVITE_FRIEND_REGISTER_SUCCESS = "INVITE_FRIEND_REGISTER_SUCCESS";
+        public static final String INVITE_FRIEND_FAILURE = "INVITE_FRIEND_FAILURE";
+        public static final String EXCHANGE_SUCCESS = "EXCHANGE_SUCCESS";
+        public static final String EXCHANGE_FAILURE = "EXCHANGE_FAILURE";
+        public static final String MINIGAME_REWARD_SUCCESS = "MINIGAME_REWARD_SUCCESS";
+        public static final String PLAYING_TIMES_REWARD = "PLAYING_TIMES_REWARD";
+        public static final String TRIGGER_REPORT_MESSAGE = "TRIGGER_REPORT_MESSAGE";
+        public static final String EXCHANGE_SUCCESS_DAILY = "EXCHANGE_SUCCESS_DAILY";
+        public static final String EXCHANGE_SUCCESS_WEEKLY = "EXCHANGE_SUCCESS_WEEKLY";
+        public static final String EXCHANGE_SUCCESS_MONTHLY = "EXCHANGE_SUCCESS_MONTHLY";
+        public static final String EXCHANGE_SUCCESS_EMOLA = "EXCHANGE_SUCCESS_EMOLA";
+        
+        
+        public static final String TOOL_RUN = "TOOL_RUN";
+
+        
+
+        public static final String RENEW_SUCCESS = "RENEW_SUCCESS";
+        public static final String BUY_SPIN_UNSUB_SUCCESS = "BUY_SPIN_UNSUB_SUCCESS";
+        public static final String BUY_SPIN_SUB_SUCCESS = "BUY_SPIN_SUB_SUCCESS";
+        public static final String DESTROY_ACCOUNT_SUCCESS = "DESTROY_ACCOUNT_SUCCESS";
+        public static final String NOT_ENOUGH_POINT = "NOT_ENOUGH_POINT";
+        public static final String CHANGE_POINT_SUCCESS = "CHANGE_POINT_SUCCESS";
+        public static final String OVER_MAX_POINT_CHANGE = "OVER_MAX_POINT_CHANGE";
+        public static final String AREADY_MAX_POINT_CHANGE = "AREADY_MAX_POINT_CHANGE";
+
+        public static final String INVITE_FRIEND_REGISTERED = "INVITE_FRIEND_REGISTERED";
+        public static final String INVITED_FRIEND = "INVITED_FRIEND";
+        //
+        public static final String NOT_ENOUGH_BALANCE = "NOT_ENOUGH_BALANCE";
+        public static final String ALREADY_REGISTERED = "ALREADY_REGISTERED";
+        public static final String ACCOUNT_NOT_EXISTED = "ACCOUNT_NOT_EXISTED";
+        public static final String ADD_FREE_GIFT_SUCCESS = "ADD_FREE_GIFT_SUCCESS";
+        public static final String ADD_SPIN_RECHARGE_SUCCESS = "ADD_SPIN_RECHARGE_SUCCESS";
+        public static final String CHECK_SPIN_RECHARGE_SUCCESS = "CHECK_SPIN_RECHARGE_SUCCESS";
+        public static final String RETURN_WIN_ADD_POINT = "RETURN_WIN_ADD_POINT";
+        public static final String RETURN_WIN_MULTIPLE_POINT = "RETURN_WIN_MULTIPLE_POINT";
+        public static final String RETURN_WIN_INVITE_FRIEND = "RETURN_WIN_INVITE_FRIEND";
+        public static final String RETURN_INVITE_FRIEND = "RETURN_INVITE_FRIEND";
+        public static final String RETURN_WAIT_INVITE_FRIEND = "RETURN_WAIT_INVITE_FRIEND";
+        public static final String RECEIVED_INVITATION = "RECEIVED_INVITATION";
+//        public static final String RETURN_WIN_LOSE_TURN = "RETURN_WIN_LOSE_TURN";
+        public static final String RETURN_WIN_LOSE_SPIN = "RETURN_WIN_LOSE_SPIN";
+        public static final String RETURN_WIN_ADD_SPIN = "RETURN_WIN_ADD_SPIN";
+        public static final String RETURN_WIN_RESET_SPIN = "RETURN_WIN_RESET_SPIN";
+        public static final String RETURN_WIN_MULTIPLE_SPIN = "RETURN_WIN_MULTIPLE_SPIN";
+        public static final String RETURN_WIN_ADD_TIMES_UNSUB = "RETURN_WIN_ADD_TIMES_UNSUB";
+        public static final String RETURN_WIN_ADD_MONEY_UNSUB = "RETURN_WIN_ADD_MONEY_UNSUB";
+        public static final String RETURN_WIN_LOSE_TURN_UNSUB = "RETURN_WIN_LOSE_TURN_UNSUB";
+
+        // for MPS
+        public static final String NOT_REGISTERED = "NOT_REGISTERED";
+        public static final String REGISTER_WAIT_CONFIRM = "REGISTER_WAIT_CONFIRM";
+        public static final String CHARGE_WAIT_CONFIRM = "CHARGE_WAIT_CONFIRM";
+        public static final String CHARGE_FEE_SUCCESS = "CHARGE_FEE_SUCCESS";
+        public static final String UPDATE_ACCOUNT_SUCCESS = "UPDATE_ACCOUNT_SUCCESS";
+        public static final String UPDATE_PASSWORD_SUCCESS = "UPDATE_PASSWORD_SUCCESS";
+        
+        public static final String DISABLE_NOT_REGISTER = "DISABLE_NOT_REGISTER";
+
+        public static final String WRONG_INFO_TO_UPDATE = "WRONG_INFO_TO_UPDATE";
+
+        public static final String LOGIN_SUCCESS = "LOGIN_SUCCESS";
+        public static final String LOGIN_FAILURE = "LOGIN_FAILURE";
+    }
+
+    /**
+     * Dinh nghia ma check dieu kien ban dau
+     */
+    public class ValidateCode {
+
+        public static final int ACTIVE_CODE = 1;
+        public static final int REGISTER_CODE = 2;
+    }
+
+    /**
+     * Dinh nghia ma loi MO_HIS
+     */
+    public class ErrorCode {
+        // ADMIN
+        public static final String ADMIN_LOGIN_FAILURE = "3000";
+        public static final String ADMIN_ADD_FAILURE = "3001";
+        public static final String ADMIN_UPDATE_FAILURE = "3002";
+        public static final String ADMIN_DELETE_FAILURE = "3003";
+
+
+        public static final String SUCCESS = "0";
+        public static final String SUCCESS_FOR_THE_FIRST_TIME_REGISTER = "2";
+        public static final String FAILURE = "1";
+        public static final String UPDATE_PASSWORD_FAILURE = "-101";
+        public static final String LOGIN_FAILURE = "-102";
+        public static final String FRIEND_EXISTED = "-103";
+        public static final String SYSTEM_ERROR = "-104";
+        public static final String ALREADY_ANSWERED = "105";
+
+        public static final String WAITING_OTP = "100";
+        public static final String DB_ERROR = "200";
+        public static final String NOT_REGISTERED = "100";
+        public static final String QUERY_ERROR = "200";
+        public static final String NOMORE_SPIN = "300";
+        public static final String TOPUP_ERROR = "400";
+        public static final String AUTHENTICATE_FAIL = "500";
+        public static final String INVALID_PINCODE = "600";
+        public static final String ACCOUNT_EXISTED = "700";
+        public static final String MSISDN_EXISTED = "800";
+        public static final String ACCOUNT_ACTIVATED = "900";
+        public static final String ACCOUNT_NOT_EXISTED = "1000";
+        public static final String ACCOUNT_IS_LOCKED = "1100";
+        public static final String ACCOUNT_NOT_ACTIVATED = "1200";
+        public static final String ACCOUNT_NOT_REGISTERED = "1300";
+        public static final String WRONG_REGISTER_CODE = "1400";
+        public static final String NOT_ENOUGH_MONEY = "1500";
+        public static final String MSISDN_BLOCKED = "1600";
+        public static final String DISABLED_AUTO_EXTEND = "1700";
+        public static final String ENABLED_AUTO_EXTEND = "1800";
+        public static final String CHARGE_ERROR = "1900";
+        public static final String ALREADY_REGISTER = "2000";
+        public static final String NOT_ENOUGH_POINT = "2100";
+        public static final String OVER_LIMIT_EXCHANGE = "2101";
+        public static final String OTP_WRONG = "2102";
+        
+        public static final String ALREADY_INVITED = "2200";
+        public static final String OVER_MAX_POINT_CHANGE = "2300";
+    }
+
+    public class ResultCode {
+
+        public static final String OK = "OK";
+        public static final String NOK = "NOK";
+        public static final String LOGIN = "LOGIN";
+        public static final String SIGNUP = "SIGNUP";
+        public static final String INVALID_COUNTERID = "INVALID COUNTERID";
+        public static final String MANY_FAIL_TOPUP = "TOO MANY FAILED ATTEMPTS";
+        public static final String SUCCESS = "0";
+        public static final String NOT_ENOUGHT = "S-ACT-00049";
+        public static final String ERROR = "9999";
+        public static final String EXIT_PRICEPLAN = "8";
+        public static final String NOT_ENOUGH = "9";
+    }
+
+    public class ActionType {
+
+        public static final int TOPUP = 1;
+        public static final int CHECK = 2;
+    }
+
+    public class RankType {
+
+        public static final int BOUGHT = 1;
+        public static final int SPIN = 0;
+    }
+
+    public class ExtendStatus {
+
+        public static final int SUCCESS = 0;
+        public static final int NOT_ENOUGH_MONEY = 1;
+        public static final int ERROR = 2;
+    }
+
+    public class ServiceCode {
+
+//        public static final String Million = "MLNRE";
+//        public static final String GamePortal = "GAMEP";
+//        public static final String LuckySpin = "LUCSPIN";
+        public static final String LuckyDraw = "LDRAW";
+    }
+
+    public class ChargeType {
+
+        public static final String CHARGE_REGISTER = "CHARGE_REGISTER";
+        public static final String CHARGE_INVITE = "CHARGE_INVITE";
+        public static final String CHARGE_PLAY = "CHARGE_PLAY";
+        public static final String DAILY_FEE = "DAILY_FEE";
+        public static final String SPIN_FEE = "SPIN_FEE";
+    }
+
+    public class SubType {
+
+        public static final int SUB = 1;
+        public static final int UNSUB = 0;
+    }
+
+    public class PeriodPrize {
+
+        public static final int DAILY = 0;
+        public static final int WEEKLY = 1;
+        public static final int MONTHLY = 2;
+    }
+
+    public class PrizeType {
+
+        public static final int INVITE = 1;
+        public static final int ADD_POINT = 2;
+        //public static final int ADD_MONEY = 3;
+        public static final int ADD_SPIN = 4;
+    }
+    
+    public class Lang {
+        public static final String local = "1";
+        public static final String en = "2";
+    }
+}

+ 83 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/Encrypt.java

@@ -0,0 +1,83 @@
+/*
+ * @Encrypt.java	version 1.0	29/03/2010
+ *
+ * Copyright 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import org.apache.log4j.Logger;
+import sun.misc.BASE64Encoder;
+
+/**
+ *
+ * @author TungTT
+ */
+public class Encrypt {
+
+    private static String convertToHex(byte[] data) {
+        StringBuffer buf = new StringBuffer();
+        for (int i = 0; i < data.length; i++) {
+            int halfbyte = (data[i] >>> 4) & 0x0F;
+            int two_halfs = 0;
+            do {
+                if ((0 <= halfbyte) && (halfbyte <= 9)) {
+                    buf.append((char) ('0' + halfbyte));
+                } else {
+                    buf.append((char) ('a' + (halfbyte - 10)));
+                }
+                halfbyte = data[i] & 0x0F;
+            } while (two_halfs++ < 1);
+        }
+        return buf.toString();
+    }
+
+    public static String MD5(String text)
+            throws NoSuchAlgorithmException, UnsupportedEncodingException {
+        MessageDigest md;
+        md = MessageDigest.getInstance("MD5");
+        byte[] md5hash = new byte[32];
+        md.update(text.getBytes("iso-8859-1"), 0, text.length());
+        md5hash = md.digest();
+        return convertToHex(md5hash);
+    }
+
+    /**
+     *
+     * @param securityCode
+     * @param salt
+     * @return
+     */
+    public static String getHashCode(String salt, String securityCode, Logger logger) {
+        MessageDigest md = null;
+        try {
+            String seq = securityCode + salt;
+            md = MessageDigest.getInstance("SHA-256"); //step 2
+            md.update(seq.getBytes("UTF-8")); //step 3
+        } catch (Exception ex) {
+            logger.error(ex.toString(), ex);
+        }
+        byte raw[] = md.digest(); //step 4
+        String hash = (new BASE64Encoder()).encode(raw); //step 5
+        return hash;
+    }
+
+    public static void main(String[] args) {
+        MessageDigest md = null;
+        String salt = "DrawLucky@123";
+        String securityCode = "luckydraw";
+        try {
+            String seq = salt + securityCode;
+            md = MessageDigest.getInstance("SHA-256"); //step 2
+            md.update(seq.getBytes("UTF-8")); //step 3
+        } catch (Exception ex) {
+//            logger.error(ex.toString(), ex);
+        }
+        byte raw[] = md.digest(); //step 4
+        String hash = (new BASE64Encoder()).encode(raw); //step 5
+        System.out.println(hash);
+    }
+}

+ 368 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/EncryptUtil.java

@@ -0,0 +1,368 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.spec.RSAPrivateCrtKeySpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+import javax.xml.bind.DatatypeConverter;
+import org.apache.log4j.Logger;
+import org.bouncycastle.crypto.AsymmetricBlockCipher;
+import org.bouncycastle.crypto.InvalidCipherTextException;
+import org.bouncycastle.crypto.encodings.PKCS1Encoding;
+import org.bouncycastle.crypto.engines.RSAEngine;
+import org.bouncycastle.crypto.params.RSAKeyParameters;
+import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
+import org.bouncycastle.openssl.PEMReader;
+import org.bouncycastle.util.encoders.Base64;
+
+public class EncryptUtil {
+
+    private static final Logger log = Logger.getLogger(EncryptUtil.class);
+
+    private static String AESKeyGen() throws NoSuchAlgorithmException {
+        try {
+            KeyGenerator keyGen = KeyGenerator.getInstance("AES");
+            keyGen.init(128, new SecureRandom());
+            SecretKey secretKey = keyGen.generateKey();
+            return byteToHex(secretKey.getEncoded());
+        } catch (NoSuchAlgorithmException noSuchAlgo) {
+            log.error(noSuchAlgo.getMessage());
+        }
+        return null;
+    }
+    
+    
+    public static void main(String[] args) throws NoSuchAlgorithmException {
+        String key = AESKeyGen();
+        System.out.println(key);
+    }
+
+    private static String byteToHex(byte[] data) {
+        StringBuilder buf = new StringBuilder();
+        for (int i = 0; i < data.length; i++) {
+            int halfbyte = (data[i] >>> 4) & 0x0F;
+            int two_halfs = 0;
+            do {
+                if ((0 <= halfbyte) && (halfbyte <= 9)) {
+                    buf.append((char) ('0' + halfbyte));
+                } else {
+                    buf.append((char) ('a' + (halfbyte - 10)));
+                }
+                halfbyte = data[i] & 0x0F;
+            } while (two_halfs++ < 1);
+        }
+        return buf.toString();
+    }
+
+    private static byte[] hexToBytes(char[] hex) {
+        int length = hex.length / 2;
+        byte[] raw = new byte[length];
+        for (int i = 0; i < length; i++) {
+            int high = Character.digit(hex[i * 2], 16);
+            int low = Character.digit(hex[i * 2 + 1], 16);
+            int value = (high << 4) | low;
+            if (value > 127) {
+                value -= 256;
+            }
+            raw[i] = (byte) value;
+        }
+        return raw;
+    }
+
+    private static byte[] hexToBytes(String hex) {
+        return hexToBytes(hex.toCharArray());
+    }
+
+    private static String encryptAES(String data, String key) throws Exception {
+        String dataEncrypted = new String();
+        try {
+            Cipher aesCipher = Cipher.getInstance("AES");
+            byte[] raw = hexToBytes(key);
+            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+            aesCipher.init(Cipher.ENCRYPT_MODE, skeySpec);
+            byte[] byteDataToEncrypt = data.getBytes();
+            byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt);
+            dataEncrypted = DatatypeConverter.printBase64Binary(byteCipherText);
+            return dataEncrypted;
+        } catch (Exception ex) {
+            log.error(ex.getMessage(), ex);
+        }
+        return dataEncrypted;
+    }
+
+    private static RSAKeyParameters getBCPublicKeyFromString(String strPublicKey) {
+        try {
+            PublicKey prvKey = getPublicKeyFromString(strPublicKey);
+            KeyFactory keyFac = KeyFactory.getInstance("RSA");
+            RSAPublicKeySpec pkSpec = keyFac.getKeySpec(prvKey, RSAPublicKeySpec.class);
+            RSAKeyParameters pub = new RSAKeyParameters(false, pkSpec.getModulus(), pkSpec.getPublicExponent());
+            return pub;
+        } catch (Exception e) {
+            log.info("Exception : " + e);
+            return null;
+        }
+    }
+
+    private static PublicKey getPublicKeyFromString(String key) throws Exception {
+        PublicKey publicKey = null;
+        try {
+            PEMReader reader = new PEMReader(new StringReader(key), null, "SunRsaSign");
+            publicKey = (PublicKey) reader.readObject();
+        } catch (Exception e) {
+            log.error("error getPublicKeyFromString ", e);
+        }
+        return publicKey;
+    }
+
+    private static String encryptRSA(String toEncrypt, String strPublicKey) {
+        RSAKeyParameters rsaPbKey = getBCPublicKeyFromString(strPublicKey);
+        if (rsaPbKey == null) {
+            log.info("RSAPublicKey == null");
+            return null;
+        }
+        try {
+            AsymmetricBlockCipher theEngine = new RSAEngine();
+            theEngine = new PKCS1Encoding(theEngine);
+            theEngine.init(true, rsaPbKey);
+            return new String(Base64.encode(theEngine.processBlock(toEncrypt.getBytes(), 0, toEncrypt.getBytes().length)));
+        } catch (InvalidCipherTextException ex) {
+            log.error("encryptRSA error ", ex);
+        }
+        return null;
+    }
+
+    private static String createMsgSignature(String data, String strPrivateKey) {
+        String encryptData = "";
+        try {
+            PrivateKey privateKey = getPrivateKeyFromString(strPrivateKey);
+            java.security.Signature s = java.security.Signature.getInstance("SHA1withRSA");
+            s.initSign(privateKey);
+            s.update(data.getBytes());
+            byte[] signature = s.sign();
+            encryptData = new String(Base64.encode(signature));                             //Encrypt data
+        } catch (Exception e) {
+            log.error("createMsgSignature", e);
+        }
+        return encryptData;
+    }
+
+    private static PrivateKey getPrivateKeyFromString(String key) throws Exception {
+        PrivateKey privateKey = null;
+        try {
+            KeyPair pemPair;
+            PEMReader reader = new PEMReader(new StringReader(key), null, "SunRsaSign");
+            pemPair = (KeyPair) reader.readObject();
+
+            privateKey = (PrivateKey) pemPair.getPrivate();
+        } catch (Exception e) {
+            log.info("error getPrivateKeyFromString " + e);
+        }
+        return privateKey;
+
+    }
+
+    private static boolean verifyMsgSignature(String encodeText, String strPublicKey, String input) {
+
+        try {
+            PublicKey publicKey = getPublicKeyFromString(strPublicKey);
+            byte[] base64Bytes = Base64.decode(encodeText);                                 // decode base64
+            java.security.Signature sig = java.security.Signature.getInstance("SHA1WithRSA");
+            sig.initVerify(publicKey);
+            sig.update(input.getBytes());
+
+            return sig.verify(base64Bytes);
+        } catch (Exception e) {
+            log.error("verifyMsgSignature", e);
+        }
+        return false;
+    }
+    private static final Map<String, String> KEY_MPS = new HashMap<String, String>();
+
+    private static String getKeyFile(String filePath) {
+        String value = KEY_MPS.get(filePath);
+        if (value != null) {
+            return value;
+        }
+
+        File file = new File(filePath);
+        StringBuilder contents = new StringBuilder();
+        BufferedReader reader = null;
+
+        try {
+            reader = new BufferedReader(new FileReader(file));
+            String text = null;
+            while ((text = reader.readLine()) != null) {
+                contents.append(text)
+                        .append(System.getProperty(
+                                "line.separator"));
+            }
+        } catch (IOException e) {
+            log.error("getKeyFile", e);
+        } finally {
+            try {
+                if (reader != null) {
+                    reader.close();
+                }
+            } catch (IOException e) {
+                log.error("getKeyFile", e);
+            }
+
+            value = contents.toString();
+            if (!value.isEmpty()) {
+                KEY_MPS.put(filePath, value);
+            }
+        }
+
+        return value;
+    }
+
+    private static String decryptRSA(String toDecrypt, String strPrivateKey) {
+
+        RSAPrivateCrtKeyParameters rsaPrKey = getBCPrivateKeyFromString(strPrivateKey);
+        if (rsaPrKey == null) {
+            log.info("RSAPrivateKey == null");
+            return null;
+        }
+
+        try {
+            AsymmetricBlockCipher theEngine = new RSAEngine();
+            theEngine = new PKCS1Encoding(theEngine);
+            theEngine.init(false, rsaPrKey);
+            return new String(theEngine.processBlock(Base64.decode(toDecrypt), 0, Base64.decode(toDecrypt).length));
+        } catch (Exception ex) {
+            log.error("decryptRSA", ex);
+        }
+        return null;
+    }
+
+    private static RSAPrivateCrtKeyParameters getBCPrivateKeyFromString(String strPrivateKey) {
+        try {
+            PrivateKey prvKey = getPrivateKeyFromString(strPrivateKey);
+            KeyFactory keyFac = KeyFactory.getInstance("RSA");
+            RSAPrivateCrtKeySpec pkSpec = keyFac.getKeySpec(prvKey, RSAPrivateCrtKeySpec.class);
+            RSAPrivateCrtKeyParameters priv = new RSAPrivateCrtKeyParameters(pkSpec.getModulus(),
+                    pkSpec.getPublicExponent(), pkSpec.getPrivateExponent(), pkSpec.getPrimeP(),
+                    pkSpec.getPrimeQ(), pkSpec.getPrimeExponentP(), pkSpec.getPrimeExponentQ(),
+                    pkSpec.getCrtCoefficient());
+            return priv;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    private static String decryptAES(String dataEncrypt, String key) throws Exception {
+        String dataDecrypted = new String();
+        try {
+            Cipher aesCipher = Cipher.getInstance("AES");
+            byte[] raw = hexToBytes(key);
+            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+            byte[] decordedValue = DatatypeConverter.parseBase64Binary(dataEncrypt);
+            aesCipher.init(Cipher.DECRYPT_MODE, skeySpec, aesCipher.getParameters());
+            byte[] byteDecryptedText = aesCipher.doFinal(decordedValue);
+            dataDecrypted = new String(byteDecryptedText);
+            return dataDecrypted;
+        } catch (Exception ex) {
+            log.error("Error decryptAES", ex);
+        }
+        return dataDecrypted;
+    }
+
+    public static String makeMpsRequestUrl(String pro, String service,
+            String subService, String cmd, String url, Map<String, String> params, String path) {
+        try {
+            String url_wap_mobile = url;
+            String dir = path == null ? "../etc/key/" : path;
+            String publicKeyViettel = getKeyFile(dir + "PublicKeyVT.pem");
+//            log.info("PublicKeyVT: " + publicKeyViettel);
+            String privateKeyCP = getKeyFile(dir + "PrivateKeyCP.pem");
+//            log.info("PrivateKeyCP: " + privateKeyCP);
+            String publicKeyCP = getKeyFile(dir + "PublicKeyCP.pem");
+//            log.info("PublicKeyCP: " + publicKeyCP);
+            String keyAES = AESKeyGen();
+            log.info("keyAES:" + keyAES);
+            StringBuffer input = new StringBuffer("");
+            int i = 0;
+            for (Map.Entry<String, String> entry : params.entrySet()) {
+                String key = entry.getKey();
+                String value = entry.getValue();
+                if (i > 0) {
+                    input.append("&");
+                }
+                input.append(key).append("=").append(value);
+                i++;
+            }
+            log.info("Input of request: " + input.toString());
+
+            String input_with_key_AES = "value=" + encryptAES(input.toString(), keyAES) + "&key=" + keyAES;
+            log.info("input_with_key_AES: " + input_with_key_AES);
+
+            String data_encrypted_RSA = (encryptRSA(input_with_key_AES, publicKeyViettel));
+            log.info("data_encrypted_RSA: " + data_encrypted_RSA);
+
+            String signature = URLEncoder.encode(createMsgSignature(data_encrypted_RSA, privateKeyCP));
+
+            boolean kq = verifyMsgSignature(URLDecoder.decode(signature), publicKeyCP, data_encrypted_RSA);
+
+            String url_request = url_wap_mobile + "PRO=" + pro + "&SER=" + service + "&SUB=" + subService + "&CMD="
+                    + cmd + "&DATA=" + URLEncoder.encode(data_encrypted_RSA) + "&SIG=" + signature;
+            return url_request;
+        } catch (Exception ex) {
+            log.error("Error makeMpsRequestUrl", ex);
+        }
+
+        return null;
+    }
+
+    public static String decodeMpsResponse(String strTemp, String path) throws Exception {
+        String dir = path == null ? "../etc/key/" : path;
+        String publicKeyViettel = getKeyFile(dir + "PublicKeyVT.pem");
+        String privateKeyCP = getKeyFile(dir + "PrivateKeyCP.pem");
+
+        String[] s = strTemp.split("&");
+
+        String dataN = s[0].substring(5);
+        String sigN = s[1].substring(4);
+
+        //boolean verify_return = verifyMsgSignature(URLDecoder.decode(sigN), publicKeyViettel, dataN);
+        String data_decrypt_RSAN = decryptRSA(dataN, privateKeyCP);
+        String value_return = data_decrypt_RSAN.split("&")[0].substring(6);
+        String key_return = data_decrypt_RSAN.split("&")[1].substring(4);
+        String data_complete = decryptAES(value_return, key_return);
+        return data_complete;
+    }
+
+    public static String analyseCodeReturn(String input) {
+        String value = "1|unknown";
+        String[] a = input.split("&");
+        for (String a1 : a) {
+            if (a1.split("=")[0].equals("RES")) {
+                String key = a1.split("=")[1];
+                value = key + "|" + StaticCode.getdiscription(key);
+                break;
+            }
+        }
+        return value;
+    }
+}

+ 84 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/MessageResponse.java

@@ -0,0 +1,84 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression;
+import java.util.HashMap;
+import java.util.List;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author TungTT
+ * @since Oct 25, 2010
+ */
+public class MessageResponse {
+
+    public static HashMap listMsg;
+    public static boolean init = false;
+    private static final Object lockMessage = new Object();
+    public static List<RegularExpression> listRegexSyntaxTopup;
+    public static List<RegularExpression> listRegexSyntaxCheck;
+
+    public static void setMessage(HashMap listMsg) {
+        synchronized (lockMessage) {
+            MessageResponse.listMsg = listMsg;
+            init = true;
+        }
+    }
+
+    public static String get(String key, Logger logger) {
+        synchronized (lockMessage) {
+            String value = (String) listMsg.get(key);
+            if (value == null || value.length() == 0) {
+                logger.error("Not yet config message " + key);
+                return "";
+            } else {
+                logger.info("Return message " + key);
+                return value;
+            }
+        }
+    }
+
+    public static String get(String key, String defaultKey, Logger logger) {
+        synchronized (lockMessage) {
+            String value = (String) listMsg.get(key);
+            if (value == null || value.length() == 0) {
+                logger.error("Not yet config message " + key);
+                if (defaultKey != null) {
+                    value = (String) listMsg.get(defaultKey);
+                } else {
+                    return "";
+                }
+            } else {
+                logger.info("Return message " + key);
+                return value;
+            }
+
+            if (value == null || value.length() == 0) {
+                logger.error("Not yet config message " + defaultKey);
+                value = "";
+            } else {
+                logger.info("Return message " + defaultKey);
+                return value;
+            }
+            return value;
+        }
+    }
+
+    public static String getDefaultMessage(String key, Logger logger) {
+        synchronized (lockMessage) {
+            String value = (String) listMsg.get(key);
+            if (value == null || value.length() == 0) {
+                logger.error("Not yet config message " + key);
+
+                return "";
+            } else {
+                return value;
+            }
+
+        }
+    }
+}

+ 76 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/RouteManager.java

@@ -0,0 +1,76 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import com.vas.kittyfallwsvas.wsfw.obj.Route;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import utils.Config;
+
+/**
+ *
+ * @author MinhNH
+ */
+public class RouteManager {
+
+    private static RouteManager instance;
+    private static List<Route> listRoute;
+    private Logger logger;
+
+    public RouteManager() throws Exception {
+
+        logger = Logger.getLogger(RouteManager.class);
+        String connectorsFile = Config.configDir + File.separator + "route.xml";
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        Document dc = db.parse(connectorsFile);
+        Element root = dc.getDocumentElement();
+
+        NodeList list = root.getElementsByTagName("route");
+        if (list.getLength() < 1) {
+            throw new Exception("No webservice to publish");
+        }
+        listRoute = new ArrayList<Route>();
+        for (int i = 0; i < list.getLength(); ++i) {
+            Element element = (Element) list.item(i);
+
+            String name = element.getAttribute("name");
+
+
+            Route route = new Route();
+
+            logger.info("===> get config for route to: " + name);
+            route.setName(name);
+            route.setListDbName(element.getAttribute("listDbName"));
+            route.setPrefixMsisdn(element.getAttribute("prefixMsisdn"));
+            listRoute.add(route);
+        }
+    }
+
+    public static RouteManager getInstance() throws Exception {
+        if (instance == null) {
+            instance = new RouteManager();
+        }
+        return instance;
+    }
+
+    public String getDbNamebyMsisdn(String msisdn) {
+        String result = "";
+        for (Route route : listRoute) {
+            result = route.getDbNamebyMsisdn(msisdn);
+            if (!result.equals("")) {
+                break;
+            }
+        }
+        return result;
+    }
+}

+ 445 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/SentEmail.java

@@ -0,0 +1,445 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+//import com.viettel.database.DAO.BaseDAOAction;
+import com.viettel.utility.PropertiesUtils;import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+import java.util.Date;
+import java.util.Properties;
+import javax.mail.Authenticator;
+import javax.mail.Message;
+import javax.mail.PasswordAuthentication;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeBodyPart;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeMultipart;
+import javax.mail.internet.MimeUtility;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author trungdh3_s
+ */
+//public class SentEmail extends BaseDAOAction {
+public class SentEmail {
+//    public static Logger logger;
+    public static int SendMail(String to, String pass, String account, String seconds, Logger logger) {
+        try {
+            if (to == null || to.trim().equals("")) {
+                return 0;
+            }
+            String smtpServer = "";
+            String from = "";
+            String subject = "";
+            String psw = "";
+            String body = "";
+            
+            PropertiesUtils pros = new PropertiesUtils();
+            pros.loadProperties("../etc/common.cfg", false);
+            
+            try {
+                smtpServer = pros.getProperty("smtpServer");
+                from = pros.getProperty("from");
+                psw = pros.getProperty("psw");
+                subject = pros.getProperty("subject");
+                body = pros.getProperty("body");
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                throw ex;
+            }
+            java.security.Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
+            Properties props = System.getProperties();
+            props.put("mail.smtp.host", smtpServer);
+            props.put("mail.smtp.socketFactory.port", "25");
+            props.put("mail.smtp.socketFactory.class", "");
+            props.put("mail.smtp.port", "25");
+            props.put("mail.smtp.socketFactory.fallback", "false");
+            props.put("mail.smtp.protocol", "smtp");
+            props.put("mail.smtp.starttls.enable", "false");
+            final String login = from;//"nth001@gmail.com";//usermail
+            final String pwd = psw;//"password cua ban o day";
+            Authenticator pa = null; //default: no authentication
+            if (login != null && pwd != null) { //authentication required?
+                props.put("mail.smtp.auth", "true");
+                pa = new Authenticator() {
+
+                    public PasswordAuthentication getPasswordAuthentication() {
+                        return new PasswordAuthentication(login, pwd);
+                    }
+                };
+            }
+            //chỗ này có thể cần thay đổi trung dh3
+            Session session1 = Session.getInstance(props, pa);
+            Message msg = new MimeMessage(session1);
+            msg.setFrom(new InternetAddress(from));
+            msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(
+                    to, false));
+
+            msg.setSubject(MimeUtility.encodeText(subject, "UTF-8", "B"));
+            MimeBodyPart messagePart = new MimeBodyPart();
+            MimeMultipart multipart = new MimeMultipart();
+            body = body.replace("%sec%", seconds);
+            body = body.replace("%acc%", account);
+            body = body.replace("%pwd%", pass);
+            messagePart.setText(body);
+//            messagePart.setHeader("Content-Type", "text/plain;  charset=\"utf-8\"");
+//            msg.setHeader("Content-Type", "text/plain; charset=utf-8");
+////            text/html;; x-java-content-handler=com.sun.mail.handlers.text_html
+//            messagePart.setHeader("Content-Transfer-Encoding", "Base64");
+            multipart.addBodyPart(messagePart);
+            msg.setContent(multipart);
+            msg.setHeader("X-Mailer", "LOTONtechEmail");
+            msg.setSentDate(new Date());
+            msg.saveChanges();
+            Transport.send(msg);
+            System.out.println("Message sent OK.");
+        } catch (Exception ex) {
+            logger.error("SentEmail: ex\n" + ex);
+            return -1;
+        }
+
+        return 1;
+    }
+}

+ 164 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/SmsSender.java

@@ -0,0 +1,164 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import com.viettel.utility.PropertiesUtils;
+import java.io.File;
+import java.util.ArrayList;
+import java.io.IOException;
+import java.util.List;
+import utils.Config;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author tungnv6
+ */
+public class SmsSender {
+    // Lay danh sach listStub
+
+    private int totalSmsWs;
+    private static int totalStub;
+    private ArrayList<SmsWs> listSmsWs;
+    private static final Object lock = new Object();
+    private static int roll = 0;
+    private static SmsSender instance;
+
+    public SmsSender() throws Exception {
+        // Lay danh sach listStub
+        ArrayList<SmsWs> listSmsInfo = initSmsWsInfo();
+
+        //So luong thread gui tin
+        totalStub = 1;
+
+        // <editor-fold defaultstate="expanded" desc="Khoi tao danh sach SmsWs">
+        int index = 0;
+        listSmsWs = new ArrayList<SmsWs>();
+        for (int i = 0; i < totalStub; i++) {
+            SmsWs smsWs = listSmsInfo.get(index);
+            listSmsWs.add(new SmsWs(smsWs.getId(), smsWs.getUrl(), smsWs.getXmlns(),
+                    smsWs.getUser(), smsWs.getPass(), true));
+
+            index++;
+            if (index >= listSmsInfo.size()) {
+                index = 0;
+            }
+        }
+        // </editor-fold>
+    }
+
+    public static SmsSender getInstance() throws IOException, Exception {
+        if (instance == null) {
+            instance = new SmsSender();
+        }
+        return instance;
+    }
+
+    // Ham load tham so smsgateway
+    private ArrayList<SmsWs> initSmsWsInfo() throws Exception {
+        ArrayList<SmsWs> listSmsInfo;
+        PropertiesUtils pro = new PropertiesUtils();
+        pro.loadPropertiesEpt(Config.configDir + File.separator + "smsgateway.cfg");
+        String[] properties = pro.getProperties();
+        int index = 0;
+        String line = properties[index++];
+
+        String url;
+        String user;
+        String pass;
+
+        listSmsInfo = new ArrayList<SmsWs>();
+        while (index <= properties.length) {
+            url = "";
+            user = "";
+            pass = "";
+
+            // Get config
+            while (index < properties.length && !line.trim().toUpperCase().equals("[SMSWS]")) {
+                line = properties[index++];
+            }
+            if (index >= properties.length) {
+                return listSmsInfo;
+            }
+            line = properties[index++];
+
+            while (index <= properties.length && line.trim().toUpperCase().indexOf("[SMSWS]") < 0) {
+                if (line.trim().length() > 0) {
+                    String info[] = line.split("=");
+                    if (info[0].trim().toUpperCase().equals("URL")) {
+                        url = info[1].trim();
+                    }
+                    if (info[0].trim().toUpperCase().equals("USERNAME")) {
+                        user = info[1].trim();
+                    }
+                    if (info[0].trim().toUpperCase().equals("PASSWORD")) {
+                        pass = info[1].trim();
+                    }
+                }
+                if (index >= properties.length) {
+                    break;
+                }
+                line = properties[index++];
+            }
+            // init client
+            SmsWs stub1 = new SmsWs(listSmsInfo.size(), url, "http://tempuri.org/", user, pass, false);
+            listSmsInfo.add(stub1);
+        }
+        totalSmsWs = listSmsInfo.size();
+        return listSmsInfo;
+    }
+
+    private int increaseRoll() {
+        synchronized (lock) {
+            roll++;
+            if (roll >= listSmsWs.size()) {
+                roll = 0;
+            }
+        }
+        return roll;
+    }
+
+    public int sendSmsAll(String message, String msisdn, String fromChannel, String msgType, Logger logger) {
+
+        int error = -1;
+
+        int index = increaseRoll();
+
+        //long timeSt = System.currentTimeMillis();
+        error = listSmsWs.get(index).send("0", "warning", fromChannel, msisdn, msgType, message, "1");
+        //logTime("Time to send sms", timeSt, listSmsWs.get(index), logger);
+        if (error == 0) {
+            return error;
+        }
+
+        List<Integer> listId = new ArrayList();
+        listId.add(listSmsWs.get(index).getId());
+
+        // <editor-fold defaultstate="expanded" desc="Loi, tiep tuc gui thong qua SMSGW tiep theo">
+        while (listId.size() < totalSmsWs) {
+            logger.error("Sender using SMSWS error: " + listSmsWs.get(index).getInfor());
+
+            index = increaseRoll();
+            int idNext = listSmsWs.get(index).getId();
+            while (listId.indexOf(idNext) >= 0) {
+                // Neu SMSWS tiep theo la SMSWS da gui thi lay SMSWS tiep theo
+                index = increaseRoll();
+                idNext = listSmsWs.get(index).getId();
+            }
+
+            //timeSt = System.currentTimeMillis();
+            error = listSmsWs.get(idNext).send("0", "warning", fromChannel, msisdn, "0", message, "1");
+            //logTime("Time to send sms", timeSt, listSmsWs.get(index), logger);
+            if (error == 0) {
+                return error;
+            }
+
+            // Add to list chua id SMSWS da gui
+            listId.add(listSmsWs.get(idNext).getId());
+        }
+        // </editor-fold>
+        return error;
+    }
+}

+ 114 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/SmsWs.java

@@ -0,0 +1,114 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import sendmt.MtStub;
+/**
+ *
+ * @author tungnv6
+ */
+public class SmsWs {
+
+    private int id;
+    private String url;
+    private String xmlns;
+    private String user;
+    private String pass;
+    private MtStub stub;
+
+    public SmsWs() {
+    }
+
+    public SmsWs(int id, String url, String xmlns, String user, String pass, boolean initStub) {
+        this.id = id;
+        this.url = url;
+        this.xmlns = xmlns;
+        this.user = user;
+        this.pass = pass;
+        if (initStub) {
+            this.stub = new MtStub(url, xmlns, user, pass);
+        }
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public String getPass() {
+        return pass;
+    }
+
+    public void setPass(String pass) {
+        this.pass = pass;
+    }
+
+    public MtStub getStub() {
+        return stub;
+    }
+
+    public void setStub(MtStub stub) {
+        this.stub = stub;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public String getXmlns() {
+        return xmlns;
+    }
+
+    public void setXmlns(String xmlns) {
+        this.xmlns = xmlns;
+    }
+
+    /**
+     * Ham gui sms
+     * @param sessionId
+     * @param serviceId
+     * @param sender
+     * @param receiver
+     * @param contentType
+     * @param content
+     * @param status
+     * @return
+     */
+    public int send(String sessionId, String serviceId,
+            String sender, String receiver, String contentType, String content, String status) {
+        return stub.send(sessionId, serviceId, sender, receiver, contentType, content, status);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append("URL = ");
+        buffer.append(url);
+        buffer.append("\r\n");
+        buffer.append("USER = ");
+        buffer.append(user);
+        buffer.append("\r\n");
+        return buffer.toString();
+    }
+
+    public String getInfor() {
+        return url;
+    }
+}

+ 118 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/StaticCode.java

@@ -0,0 +1,118 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * HashMap descriptions code return for CP
+ *
+ * @version 1.0
+ * @author langiac
+ * @since 10 10 2015
+ */
+public class StaticCode {
+
+    private static final String code0 = "Transaction success";
+    private static final String code1 = "msisdn not found";
+    private static final String code4 = "IP Cllient was wrong";
+    private static final String code11 = "missed parameter";
+    private static final String code13 = "missed parameter";
+    private static final String code14 = "cp request id not found";
+    private static final String code15 = "value is not found";
+    private static final String code16 = "aes key is not found";
+    private static final String code17 = "name item is not found";
+    private static final String code18 = "category item is not found";
+    private static final String code22 = "CP code is not valid or not active";
+    private static final String code23 = "Payment is not valid";
+    private static final String code24 = "transaction not confirm before";
+    private static final String code25 = "CP Request Id is not valid";
+    private static final String code503 = "MPS was error";
+    private static final String code101 = "transaction was error";
+    private static final String code102 = "transaction was error when register";
+    private static final String code103 = "got error when pay by mobile account";
+    private static final String code104 = "Error when cancelling service";
+    private static final String code201 = "Signal is not valid";
+    private static final String code202 = "transaction was error or password not valid";
+    private static final String code207 = "Conflict service when register";
+    private static final String code401 = "not enough balance";
+    private static final String code402 = "Thuê bao chưa đăng ký thanh toán";
+    private static final String code403 = "msisdn not existed";
+    private static final String code404 = "msisdn is not valid";
+    private static final String code405 = "msisdn was changed owner";
+    private static final String code406 = "not found mobile";
+    private static final String code407 = "missing parameters";
+    private static final String code408 = "msisdn is using service";
+    private static final String code409 = "msisdn was two ways blocked";
+    private static final String code410 = "msisdn is not valid";
+    private static final String code411 = "msisdn canceled service";
+    private static final String code412 = "msisdn not using service";
+    private static final String code413 = "parameter is not valid";
+    private static final String code414 = "msisdn in period recharge.(recharge time < next charge time)";
+    private static final String code415 = "OTP code is not valid";
+    private static final String code416 = "OTP not exist or timeout";
+    private static final String code417 = "Error USSD time out";
+    private static final String code440 = "System error";
+    private static final String code501 = "msisdn not register";
+    private static final String code203 = "MPS account not exist (msisdn/password not valid)";
+    private static final String code204 = "MPS acount is exist but msisdn not register CP service";
+    private static final String code205 = "MPS acount is exist and registed CP service";
+    private static final String code100 = "Transaction was proccessed ";
+    private static final Map<String, String> dictcode = new HashMap();
+
+    static {
+        dictcode.put("0", code0);
+        dictcode.put("100", code100);
+        dictcode.put("1", code1);
+        dictcode.put("4", code4);
+        dictcode.put("11", code11);
+        dictcode.put("13", code13);
+        dictcode.put("14", code14);
+        dictcode.put("15", code15);
+        dictcode.put("16", code16);
+        dictcode.put("17", code17);
+        dictcode.put("18", code18);
+        dictcode.put("22", code22);
+        dictcode.put("23", code23);
+        dictcode.put("24", code24);
+        dictcode.put("25", code25);
+        dictcode.put("101", code101);
+        dictcode.put("102", code102);
+        dictcode.put("103", code103);
+        dictcode.put("104", code104);
+        dictcode.put("201", code201);
+        dictcode.put("202", code202);
+        dictcode.put("207", code207);
+        dictcode.put("401", code401);
+        dictcode.put("402", code402);
+        dictcode.put("403", code403);
+        dictcode.put("405", code405);
+        dictcode.put("406", code406);
+        dictcode.put("407", code407);
+        dictcode.put("408", code408);
+        dictcode.put("404", code404);
+        dictcode.put("440", code440);
+        dictcode.put("410", code410);
+        dictcode.put("411", code411);
+        dictcode.put("412", code412);
+        dictcode.put("413", code413);
+        dictcode.put("414", code414);
+        dictcode.put("415", code415);
+        dictcode.put("416", code416);
+        dictcode.put("417", code417);
+        dictcode.put("503", code503);
+        dictcode.put("204", code204);
+        dictcode.put("205", code205);
+        dictcode.put("501", code501);
+        dictcode.put("203", code203);
+        dictcode.put("409", code409);
+    }
+
+    public static String getdiscription(String code) {
+        return dictcode.get(code);
+    }
+}

+ 96 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/WebserviceAbstract.java

@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+
+import com.sun.net.httpserver.HttpExchange;
+import com.vas.kittyfallwsvas.wsfw.obj.UserInfo;
+import javax.annotation.Resource;
+import javax.jws.WebService;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.handler.MessageContext;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 4, 2013
+ * @version 1.0
+ */
+@WebService
+public abstract class WebserviceAbstract {
+
+    public Logger logger;
+    //
+    public static String SUCCESS = "0";
+    public static String SYNTAX_ERROR = "1";
+    public static String WRONG_PASSWORD = "2";
+    public static String NOT_ALLOW = "3";
+    public static String MSISDN_NOT_VALID = "4";
+    public static String PARAM_NOT_ENOUGH = "-1";
+    public static String EXCEPTION = "6";
+    public static String PARAM_NOT_VALID = "7";
+    public static String NOT_CONFIG = "-1";
+    public static String NOT_SUPPORT = "-2";
+    public static String DUPLICATE_MESSAGE = "8";
+    public static String ACCOUNT_EXIST = "9";
+    public static String ACCOUNT_NOT_EXIST = "10";
+    public static String ACCOUNT_WAS_BLOCK = "11";
+    public static String ACCOUNT_WAS_UNBLOCK = "12";
+    public static String CHECK_ACC_BALANCE_FAIL = "13";
+    public static String NOT_ENOUGH_BALANCE = "14";
+    public static String CHARGE_BALANCE_FAIL = "15";
+    public static String EWALLET_ACCOUNT_NOT_EXISTED = "16";
+    public static String PIN_NOT_VALID = "17";
+    public static String NOT_CHANGE_PIN = "18";
+    public static String WRONG_PIN = "19";
+    public static String PAY_FAIL = "20";
+    public static String LIST_ID_MONEY="1|44|79|78|81|88|20|51|72|84|86|19|21|22|25|73|85|50|80|23|41|77";
+    public static String NO_DATA = "101";
+    public static String FAILURE = "102";
+    public static String NO_ACCOUNT_EXISTED = "103";
+    public static String OUT_OF_LIST_REWARD = "104";
+
+
+
+
+
+
+    //
+    @Resource
+    public WebServiceContext wsContext;
+
+    public WebserviceAbstract(String logName) {
+        logger = Logger.getLogger(logName);
+    }
+
+    /**
+     * *******************************************************
+     */
+    abstract public UserInfo authenticate(String userName, String password, String ipAddress);
+
+    /**
+     * ***********************************************************
+     */
+    public String getIpClient() {
+        MessageContext msgCtxt = wsContext.getMessageContext();
+        try {
+            HttpExchange httpEx = (HttpExchange) msgCtxt.get("com.sun.xml.ws.http.exchange");
+            return httpEx.getRemoteAddress().getAddress().getHostAddress();
+        } catch (Exception ex) {
+            HttpExchange httpEx = (HttpExchange) msgCtxt.get("com.sun.xml.internal.ws.http.exchange");
+            return httpEx.getRemoteAddress().getAddress().getHostAddress();
+        }
+    }
+
+    public boolean pair(String ipClient, String ipConfig) {
+        if (ipClient == null || ipClient.equals("") || ipConfig == null || ipConfig.equals("")) {
+            return false;
+        }
+        ipConfig = ipConfig.replaceAll("x", "\\\\d+");
+        return ipClient.matches(ipConfig);
+    }
+    
+}

+ 511 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/WebserviceManager.java

@@ -0,0 +1,511 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+import com.vas.kittyfallwsvas.wsfw.database.ConnectionPoolManager;
+import com.vas.kittyfallwsvas.wsfw.services.ExchangeClientChannel;
+import com.viettel.mmserver.base.ProcessThreadMX;
+import com.viettel.ussdfw.log.ProcessTransLog;
+import com.viettel.utility.PropertiesUtils;
+import java.io.File;
+import java.io.FileReader;
+import java.util.*;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.ws.Endpoint;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import utils.Config;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 3, 2013
+ * @version 1.0
+ */
+public class WebserviceManager extends ProcessThreadMX {
+
+    private static WebserviceManager instance;
+    //
+    private static List<WebserviceObject> listWS;
+    public static HashMap<String, Integer> listWSname;
+    private static List<Endpoint> listEndpoint;
+    private int[] idLogTransThread;
+    private String connectorsFile;
+    // Config
+    public static String processClass;
+    public static String appId;
+//    public static int maxRow;
+    public static int queryDbTimeout;
+    public static int breakQuery;
+    public static int dbTimeOut;
+    public static boolean exchangeEnable;
+    public static boolean enableQueryDbTimeout;
+    public static String pathDatabase;
+    public static String pathExch;
+    public static long[] timesDbLevel;
+    public static long[] timesOcsLevel;
+    public static long minTimeDb;
+    public static long minTimeOcs;
+    public static HashMap loggerDbMap;
+    public static HashMap loggerOcsMap;
+
+    public static boolean logToDatabase;
+    public static int numThreadLogTrans;
+    public static String logToDatabaseId;
+    public static String logDatabaseConf;
+    private boolean exception = false;
+    //
+    private StringBuffer br = new StringBuffer();
+//    private boolean exception = false;
+    //
+    //nang cap retry db
+    public static int BREAK_INSERT_REGISTER;
+    public static int RETRY_INSERT_REGISTER;
+    public static int LOG_RETRY_INSERT_REGISTER;
+    public static int BREAK_UPDATE_REGISTER;
+    public static int RETRY_UPDATE_REGISTER;
+    public static int LOG_RETRY_UPDATE_REGISTER;
+    public static int BREAK_DELETE_MO;
+    public static int RETRY_DELETE_MO;
+    public static int LOG_RETRY_DELETE_MO;
+    public static int DELAY_RETRY_DB;
+    public static long PROCESS_TIMEOUT;
+    // ma quoc gia
+    public static String countryCode;
+    // =====CHECK_PRODUCT==========================
+    // so tien trinh check product
+    public static int NUM_THREAD_CHECK_PRODUCT;
+    // thoi gian timeout khi xu ly check product
+    public static long TIMEOUT_THREAD_CHECK_PRODUCT;
+    public static int NUM_PRODUCT_PER_THREAD;
+    public static String MESSAGE;
+    public static String CHANNEL;
+    //=============================================
+
+    public static WebserviceManager getInstance() throws Exception {
+        if (instance == null) {
+            instance = new WebserviceManager();
+        }
+        return instance;
+    }
+
+    public WebserviceManager() throws Exception {
+        super("WebserviceManager");
+        registerAgent("WebserviceFW:type=WebserviceManager");
+        // get config
+        String config = Config.configDir + File.separator + "app.conf";
+        FileReader fileReader = null;
+        fileReader = new FileReader(config);
+        Properties pro = new Properties();
+        pro.load(fileReader);
+
+        br.setLength(0);
+        // Ma ung dung
+        try {
+            appId = pro.getProperty("APP_ID").toUpperCase();
+        } catch (Exception ex) {
+            br.append("APP_ID not found in app.conf\n");
+//            exception = true;
+        }
+
+        // Query db break
+        try {
+            breakQuery = 1000 * Integer.parseInt(pro.getProperty("breakQuery"));
+        } catch (Exception ex) {
+            breakQuery = 10000;
+            br.append("breakQuery not found in app.conf--> default: 60s\n");
+        }
+
+        // Query db break
+        try {
+            queryDbTimeout = Integer.parseInt(pro.getProperty("queryDbTimeout"));
+        } catch (Exception ex) {
+            queryDbTimeout = 18000;
+            br.append("queryDbTimeout not found in app.conf --> default: 18s\n");
+        }
+
+        // Ma quoc gia
+        try {
+            countryCode = pro.getProperty("COUNTRY_CODE");
+            if (countryCode == null || countryCode.length() == 0) {
+                br.append("COUNTRY_CODE not found in app.conf ==> default=84");
+                countryCode = "84";
+            }
+        } catch (Exception ex) {
+            br.append("COUNTRY_CODE not found in app.conf ==> default=84");
+            countryCode = "84";
+        }
+
+        // thoi gian break insert register
+        try {
+            BREAK_INSERT_REGISTER = Integer.parseInt(pro.getProperty("BREAK_INSERT_REGISTER"));
+        } catch (Exception ex) {
+            br.append("BREAK_INSERT_REGISTER not found in app.conf\n");
+        }
+
+        // thoi gian break update register
+        try {
+            BREAK_UPDATE_REGISTER = Integer.parseInt(pro.getProperty("BREAK_UPDATE_REGISTER"));
+        } catch (Exception ex) {
+            br.append("BREAK_UPDATE_REGISTER not found in app.conf\n");
+        }
+
+        // so lan retry insert register
+        try {
+            RETRY_INSERT_REGISTER = Integer.parseInt(pro.getProperty("RETRY_INSERT_REGISTER"));
+        } catch (Exception ex) {
+            br.append("RETRY_INSERT_REGISTER not found in app.conf\n");
+        }
+
+        // so lan retry de ghi log
+        try {
+            LOG_RETRY_INSERT_REGISTER = Integer.parseInt(pro.getProperty("LOG_RETRY_INSERT_REGISTER"));
+        } catch (Exception ex) {
+            br.append("LOG_RETRY_INSERT_REGISTER not found in app.conf\n");
+        }
+
+        // so lan retry update register
+        try {
+            RETRY_UPDATE_REGISTER = Integer.parseInt(pro.getProperty("RETRY_UPDATE_REGISTER"));
+        } catch (Exception ex) {
+            br.append("RETRY_UPDATE_REGISTER not found in app.conf\n");
+        }
+
+        // so lan retry de ghi log
+        try {
+            LOG_RETRY_UPDATE_REGISTER = Integer.parseInt(pro.getProperty("LOG_RETRY_UPDATE_REGISTER"));
+        } catch (Exception ex) {
+            br.append("LOG_RETRY_UPDATE_REGISTER not found in app.conf\n");
+        }
+
+        // thoi gian delay truoc khi retry db (s)
+        try {
+            DELAY_RETRY_DB = 1000 * Integer.parseInt(pro.getProperty("DELAY_RETRY_DB"));
+        } catch (Exception ex) {
+            br.append("DELAY_RETRY_DB not found in app.conf\n");
+        }
+
+        // thoi gian timeout xu ly (s)
+        try {
+            PROCESS_TIMEOUT = 1000 * Long.parseLong(pro.getProperty("PROCESS_TIMEOUT"));
+        } catch (Exception ex) {
+            br.append("PROCESS_TIMEOUT not found in app.conf\n");
+        }
+
+        //So tien trinh kiem tra danh sach goi duoc dang ky
+        try {
+            NUM_THREAD_CHECK_PRODUCT = Integer.parseInt(pro.getProperty("NUM_THREAD_CHECK_PRODUCT"));
+        } catch (Exception ex) {
+            br.append("NUM_THREAD_CHECK_PRODUCT not found in app.conf ==> default = 1\n");
+            NUM_THREAD_CHECK_PRODUCT = 1;
+        }
+        try {
+            NUM_PRODUCT_PER_THREAD = Integer.parseInt(pro.getProperty("NUM_PRODUCT_PER_THREAD"));
+        } catch (Exception ex) {
+            br.append("NUM_PRODUCT_PER_THREAD not found in app.conf ==> default = 100\n");
+            NUM_PRODUCT_PER_THREAD = 100;
+        }
+        //Thoi gian timeout khi kiem tra product duoc dang ky
+        try {
+            TIMEOUT_THREAD_CHECK_PRODUCT = 1000 * Integer.parseInt(pro.getProperty("TIMEOUT_THREAD_CHECK_PRODUCT"));
+        } catch (Exception ex) {
+            br.append("TIMEOUT_THREAD_CHECK_PRODUCT not found in app.conf ==> default = 30000ms\n");
+            TIMEOUT_THREAD_CHECK_PRODUCT = 30000;
+        }
+        //
+        // thoi gian break delete mo
+        try {
+            BREAK_DELETE_MO = Integer.parseInt(pro.getProperty("BREAK_DELETE_MO"));
+        } catch (Exception ex) {
+            br.append("BREAK_DELETE_MO not found in app.conf\n");
+        }
+
+        // so lan retry delete mo
+        try {
+            RETRY_DELETE_MO = Integer.parseInt(pro.getProperty("RETRY_DELETE_MO"));
+        } catch (Exception ex) {
+            br.append("RETRY_DELETE_MO not found in app.conf\n");
+        }
+
+        // so lan retry ghi log
+        try {
+            LOG_RETRY_DELETE_MO = Integer.parseInt(pro.getProperty("LOG_RETRY_DELETE_MO"));
+        } catch (Exception ex) {
+            br.append("LOG_RETRY_DELETE_MO not found in app.conf\n");
+        }
+
+        /**
+         * EXCHANGE
+         */
+        try {
+            exchangeEnable = Boolean.parseBoolean(pro.getProperty("EXCHANGE_ENABLE"));
+        } catch (Exception ex) {
+            br.append("EXCHANGE_ENABLE not found in app.conf => Default value: false\n");
+            exchangeEnable = false;
+        }
+        try {
+            MESSAGE = pro.getProperty("MESSAGE");
+        } catch (Exception ex) {
+            br.append("MESSAGE not found in app.conf ==> default = null\n");
+            MESSAGE = null;
+        }
+        try {
+            CHANNEL = pro.getProperty("CHANNEL");
+        } catch (Exception ex) {
+            br.append("CHANNEL not found in app.conf ==> default = null\n");
+            CHANNEL = "154";
+        }
+        if (exchangeEnable) {
+            try {
+                pathExch = "../etc/exchange_client.cfg";
+            } catch (Exception ex) {
+                br.append("PATH_EXCH not found in app.conf\n");
+//                exception = true;
+            }
+        }
+        try {
+            logToDatabase = Boolean.parseBoolean(pro.getProperty("LOG_TO_DATABASE"));
+        } catch (Exception ex) {
+            this.br.append("LOG_TO_DATABASE not found in app.conf, default=false \n");
+            logToDatabase = false;
+        }
+        if (logToDatabase) {
+            try {
+                logToDatabaseId = pro.getProperty("LOG_TO_DATABASE_ID");
+                if ((logToDatabaseId == null) || (logToDatabaseId.length() <= 0)) {
+                    this.br.append("LOG_TO_DATABASE_ID need config in app.conf\n");
+                }
+            } catch (Exception ex) {
+                this.br.append("LOG_TO_DATABASE_ID not found in app.conf\n");
+                this.exception = true;
+            }
+            try {
+                logDatabaseConf = pro.getProperty("LOG_DATABASE_CONF");
+                if ((logDatabaseConf == null) || (logDatabaseConf.length() <= 0)) {
+                    this.br.append("LOG_DATABASE_CONF need config in app.conf\n");
+                    this.exception = true;
+                }
+            } catch (Exception ex) {
+                this.br.append("LOG_DATABASE_CONF not found in app.conf\n");
+                this.exception = true;
+            }
+
+            try {
+                numThreadLogTrans = Integer.parseInt(pro.getProperty("NUM_THREAD_LOG_TRANS"));
+                if (numThreadLogTrans <= 0) {
+                    this.br.append("NUM_THREAD_LOG_TRANS need config in app.conf\n");
+                    numThreadLogTrans = 1;
+                }
+            } catch (Exception ex) {
+                this.br.append("NUM_THREAD_LOG_TRANS not found in app.conf,default=1\n");
+                numThreadLogTrans = 1;
+            }
+
+        }
+
+        if (this.exception) {
+            throw new Exception(this.br.toString());
+        }
+        if (this.br.length() > 0) {
+            this.logger.warn(this.br);
+        }
+
+        /**
+         * DATABASE
+         */
+        pathDatabase = "../etc/database.xml";
+
+        fileReader.close();
+        // Load log warning
+        loadLogLevelWarnning();
+        connectorsFile = Config.configDir + File.separator + "webservices.xml";
+        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+        DocumentBuilder db = dbf.newDocumentBuilder();
+        Document dc = db.parse(connectorsFile);
+        Element root = dc.getDocumentElement();
+
+        NodeList list = root.getElementsByTagName("webservice");
+        if (list.getLength() < 1) {
+            throw new Exception("No webservice to publish");
+        }
+
+        listWS = new ArrayList<WebserviceObject>();
+        listWSname = new HashMap<String, Integer>();
+
+        for (int i = 0; i < list.getLength(); ++i) {
+            Element element = (Element) list.item(i);
+
+            String name = element.getAttribute("name");
+
+            if (listWSname.containsKey(name)) {
+                throw new Exception("same webservice name: " + name);
+            }
+            WebserviceObject webserviceObject = new WebserviceObject();
+
+            logger.info("===> get config for webservice: " + name);
+            webserviceObject.setName(name);
+            webserviceObject.setIp(element.getAttribute("ip"));
+            webserviceObject.setPort(element.getAttribute("port"));
+            webserviceObject.setPath(element.getAttribute("path"));
+            webserviceObject.setImplementClass(element.getAttribute("implementClass"));
+            webserviceObject.makeUrl();
+            listWSname.put(name, 1);
+            listWS.add(webserviceObject);
+        }
+        ConnectionPoolManager.loadConfig(pathDatabase);
+        if (exchangeEnable) {
+            ExchangeClientChannel.getInstance();
+        }
+
+        this.idLogTransThread = new int[WebserviceManager.numThreadLogTrans];
+        for (int i = 0; i < WebserviceManager.numThreadLogTrans; i++) {
+            ProcessTransLog log = new ProcessTransLog("ProcessTransLog" + i,
+                    WebserviceManager.logToDatabase, WebserviceManager.logDatabaseConf, WebserviceManager.logToDatabaseId);
+            this.idLogTransThread[i] = log.getId().intValue();
+        }
+
+    }
+
+    @Override
+    protected void process() {
+        try {
+            Thread.sleep(10000);
+        } catch (InterruptedException ex) {
+        }
+    }
+
+    @Override
+    public void start() {
+        super.start();
+        ClassLoader cl = new ClassLoader() {
+        };
+        listEndpoint = new ArrayList<Endpoint>();
+        for (WebserviceObject webserviceObject : listWS) {
+            try {
+
+                Class c = cl.loadClass(webserviceObject.getImplementClass());
+                logger.info("===> Load class: " + c.getName());
+                WebserviceAbstract webserviceAbstract = (WebserviceAbstract) c.newInstance();
+                Endpoint service = Endpoint.publish(webserviceObject.getUrl(), webserviceAbstract);
+
+                logger.info("Publish service " + webserviceObject.getName() + " success!");
+                logger.info("URL: " + webserviceObject.getUrl() + "?wsdl");
+                listEndpoint.add(service);
+            } catch (Exception e) {
+                logger.error("Publish service " + webserviceObject.getName() + " error!", e);
+            }
+
+        }
+
+        for (int i = 0; i < this.idLogTransThread.length; i++) {
+            com.viettel.mmserver.base.ProcessManager.getInstance().getMmProcess(Integer.valueOf(this.idLogTransThread[i])).start();
+        }
+
+        logger.info("+++ SYSTEM PROCESS STARTED  +++");
+    }
+
+    @Override
+    public void stop() {
+
+        for (Endpoint endpoint : listEndpoint) {
+            try {
+                endpoint.stop();
+            } catch (Exception e) {
+                logger.error("Stop endpoint " + endpoint.getClass().toString() + " error!", e);
+            }
+        }
+
+        for (int i = 0; i < this.idLogTransThread.length; i++) {
+            com.viettel.mmserver.base.ProcessManager.getInstance().getMmProcess(Integer.valueOf(this.idLogTransThread[i])).stop();
+        }
+
+        super.stop();
+        logger.info("+++ SYSTEM PROCESS STOPPED  +++");
+    }
+
+    /**
+     * Doc thong tin file loglevel.conf
+     */
+    private void loadLogLevelWarnning() throws Exception {
+        PropertiesUtils pros = new PropertiesUtils();
+        pros.loadProperties("../etc/loglevel.conf", false);
+        try {
+            String[] dbTimes = pros.getProperty("DB_TIMES").split(",");
+            String[] dbKey = pros.getProperty("DB_MESSAGE_KEY").split(",");
+
+            loggerDbMap = new HashMap();
+            timesDbLevel = new long[dbTimes.length];
+            minTimeDb = Long.parseLong(dbTimes[0].trim());
+            for (int i = 0; i < dbTimes.length; i++) {
+                timesDbLevel[i] = Long.parseLong(dbTimes[i].trim());
+                loggerDbMap.put(i, dbKey[i].trim());
+            }
+        } catch (Exception ex) {
+            logger.error("Loi lay thong tin DB_TIMES, DB_MESSAGE_KEY trong loglevel.conf");
+            loggerDbMap = null;
+            throw ex;
+        }
+
+        if (exchangeEnable) {
+            try {
+                String[] ocsTimes = pros.getProperty("OCS_TIMES").split(",");
+                String[] ocsKey = pros.getProperty("OCS_MESSAGE_KEY").split(",");
+
+                loggerOcsMap = new HashMap();
+                timesOcsLevel = new long[ocsTimes.length];
+                minTimeOcs = Long.parseLong(ocsTimes[0].trim());
+                for (int i = 0; i < ocsTimes.length; i++) {
+                    timesOcsLevel[i] = Long.parseLong(ocsTimes[i].trim());
+                    loggerOcsMap.put(i, ocsKey[i].trim());
+                }
+            } catch (Exception ex) {
+                logger.error("Loi lay thong tin OCS_TIMES, OCS_MESSAGE_KEY trong loglevel.conf");
+                loggerOcsMap = null;
+                throw ex;
+            }
+        }
+    }
+
+    /**
+     * Log cham database
+     *
+     * @param times
+     * @return
+     */
+    public static String getTimeLevelDb(long times) {
+        if (loggerDbMap != null) {
+            int key = Arrays.binarySearch(timesDbLevel, times);
+            if (key < 0) {
+                key = -key - 2;
+            }
+
+            String label = (String) loggerDbMap.get(key);
+
+            return (label == null) ? "-" : label;
+        }
+        return null;
+    }
+
+    /**
+     * Log cham ocs, hlr
+     *
+     * @param times
+     * @return
+     */
+    public static String getTimeLevelOcs(long times) {
+        if (loggerOcsMap != null) {
+            int key = Arrays.binarySearch(timesOcsLevel, times);
+            if (key < 0) {
+                key = -key - 2;
+            }
+
+            String label = (String) loggerOcsMap.get(key);
+            return (label == null) ? "-" : label;
+        }
+        return null;
+    }
+}

+ 73 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/common/WebserviceObject.java

@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.common;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 3, 2013
+ * @version 1.0
+ */
+public class WebserviceObject {
+
+    private String name;
+    private String ip;
+    private String port;
+    private String path;
+    private String implementClass;
+    private String url;
+
+    public String getIp() {
+        return ip;
+    }
+
+    public void setIp(String ip) {
+        this.ip = ip;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getPort() {
+        return port;
+    }
+
+    public void setPort(String port) {
+        this.port = port;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getImplementClass() {
+        return implementClass;
+    }
+
+    public void setImplementClass(String implementClass) {
+        this.implementClass = implementClass;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public void makeUrl() {
+        this.url = "http://" + this.ip + ":" + this.port + "/" + this.path;
+    }
+}

+ 225 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/ConnectionPoolManager.java

@@ -0,0 +1,225 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.database;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+import com.viettel.utility.PropertiesUtils;
+import java.io.StringReader;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.*;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
+/**
+ *
+ * @author MinhNH
+ */
+public class ConnectionPoolManager {
+
+    private static Logger logger = Logger.getLogger(ConnectionPoolManager.class);
+    private static HashMap<String, ComboPooledDataSource> connectionMap = null;
+
+    /**
+     * *
+     *
+     * @param dbConfigXml
+     * @throws Exception
+     */
+    public static void loadConfig(String dbConfigXml) throws Exception {
+
+        if (connectionMap == null) {
+            connectionMap = new HashMap();
+            try {
+                PropertiesUtils proUtils = new PropertiesUtils();
+                proUtils.loadPropertiesEpt(dbConfigXml);
+                StringBuilder build = new StringBuilder();
+                String[] proStr = proUtils.getProperties();
+                //
+                for (int i = 0; i < proStr.length; i++) {
+                    build.append(proStr[i]);
+                }
+                InputSource is = new InputSource(new StringReader(build.toString()));
+                DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
+                DocumentBuilder db = df.newDocumentBuilder();
+                Document dc = db.parse(is);
+                Element root = dc.getDocumentElement();
+                HashMap connectors = new HashMap();
+                int index = 0;
+                //load cac time out
+                NodeList listTimeOut = root.getElementsByTagName("timeout-config");
+                for (int i = 0; i < listTimeOut.getLength(); i++) {
+                    Element ele = (Element) listTimeOut.item(i);
+                    NodeList listProperty = ele.getElementsByTagName("property");
+                    for (int j = 0; j < listProperty.getLength(); j++) {
+                        Element elePro = (Element) listProperty.item(j);
+                        String name = elePro.getAttribute("name");
+                        String value = elePro.getTextContent();
+                        if (name.equals("queryDbTimeout")) {
+                            try {
+                                DbProcessorAbstract.QUERY_TIMEOUT = Integer.parseInt(value);
+                            } catch (Exception e) {
+                                DbProcessorAbstract.QUERY_TIMEOUT = 60;
+                            }
+
+                        } else if (name.equals("timeBreak")) {
+                            try {
+                                DbProcessorAbstract.TIME_BREAK = Integer.parseInt(value);
+                            } catch (Exception e) {
+                                DbProcessorAbstract.TIME_BREAK = 90000;
+                            }
+                        } else if (name.equals("timeBreakDeleteRecordTimeOut")) {
+                            try {
+                                DbProcessorAbstract.TIME_BREAK_DELETE_RECORD_TIMEOUT = Integer.parseInt(value);
+                            } catch (Exception e) {
+                                DbProcessorAbstract.TIME_BREAK_DELETE_RECORD_TIMEOUT = 120000;
+                            }
+                        }
+                    }
+                }
+
+                //
+                NodeList list = root.getElementsByTagName("named-config");
+                if (list.getLength() < 1) {
+                    throw new Exception("No named-config");
+                }
+                //
+                for (int i = 0; i < list.getLength(); ++i) {
+                    Element ele = (Element) list.item(i);
+                    String dbName = ele.getAttribute("name");
+
+                    NodeList listProperty = ele.getElementsByTagName("property");
+                    if (listProperty.getLength() < 1) {
+                        throw new Exception("No property");
+                    }
+                    //doc list
+                    Properties pro = new Properties();
+                    for (int j = 0; j < listProperty.getLength(); j++) {
+                        Element elePro = (Element) listProperty.item(j);
+                        String name = elePro.getAttribute("name");
+                        String value = elePro.getTextContent();
+                        pro.setProperty(name, value);
+                    }
+
+                    // init pool Database
+                    ConnectionPoolObject obj = new ConnectionPoolObject(pro);
+                    obj.setId(dbName);
+                    try {
+                        connectionMap.put(dbName, obj.createPoolConnection());
+                    } catch (Exception e) {
+                        logger.error("==> ERROR WHEN INIT DATABASE ID=" + dbName, e);
+                    }
+                }
+            } catch (Exception ex) {
+                logger.error("==> ERROR INIT DATABASE LIST", ex);
+                throw ex;
+            }
+        }
+    }
+
+    public static void reLoadConfig(String dbConfigXml) throws Exception {
+        connectionMap = new HashMap();
+        try {
+            PropertiesUtils proUtils = new PropertiesUtils();
+            proUtils.loadPropertiesEpt(dbConfigXml);
+            StringBuilder build = new StringBuilder();
+            String[] proStr = proUtils.getProperties();
+            //
+            for (int i = 0; i < proStr.length; i++) {
+                build.append(proStr[i]);
+            }
+            InputSource is = new InputSource(new StringReader(build.toString()));
+            DocumentBuilderFactory df = DocumentBuilderFactory.newInstance();
+            DocumentBuilder db = df.newDocumentBuilder();
+            Document dc = db.parse(is);
+            Element root = dc.getDocumentElement();
+            HashMap connectors = new HashMap();
+            int index = 0;
+            //
+            NodeList list = root.getElementsByTagName("named-config");
+            if (list.getLength() < 1) {
+                throw new Exception("No named-config");
+            }
+            //
+            for (int i = 0; i < list.getLength(); ++i) {
+                Element ele = (Element) list.item(i);
+                String dbName = ele.getAttribute("name");
+
+                NodeList listProperty = ele.getElementsByTagName("property");
+                if (listProperty.getLength() < 1) {
+                    throw new Exception("No property");
+                }
+                //doc list
+                Properties pro = new Properties();
+                for (int j = 0; j < listProperty.getLength(); j++) {
+                    Element elePro = (Element) listProperty.item(j);
+                    String name = elePro.getAttribute("name");
+                    String value = elePro.getTextContent();
+                    pro.setProperty(name, value);
+                }
+
+                // init pool Database
+                ConnectionPoolObject obj = new ConnectionPoolObject(pro);
+                obj.setId(dbName);
+                try {
+                    connectionMap.put(dbName, obj.createPoolConnection());
+                } catch (Exception e) {
+                    logger.error("==> ERROR WHEN INIT DATABASE ID=" + dbName, e);
+                }
+            }
+        } catch (Exception ex) {
+            logger.error("==> ERROR INIT DATABASE LIST", ex);
+            throw ex;
+        }
+    }
+
+    /**
+     * @param id
+     * @return **
+     *
+     */
+    public static synchronized Connection getConnection(String id) {
+        Connection conn = null;
+        try {
+            if (connectionMap.containsKey(id)) {
+                conn = ((ComboPooledDataSource) connectionMap.get(id)).getConnection();
+            } else {
+                logger.warn("PooledDataSource don't have ID: " + id);
+            }
+        } catch (SQLException ex) {
+            logger.error("Can't connect DB, with ID: " + id, ex);
+        }
+
+        return conn;
+    }
+
+    public static HashMap<String, ComboPooledDataSource> getConnectionMap() {
+        return connectionMap;
+    }
+
+    public static void setConnectionMap(HashMap<String, ComboPooledDataSource> connectionMap) {
+        ConnectionPoolManager.connectionMap = connectionMap;
+    }
+
+    public static List<String> getListDatabaseName() {
+
+        List<String> listTemp = new ArrayList<String>();
+        List<String> listReturn = new ArrayList<String>();
+        for (Map.Entry<String, ComboPooledDataSource> entry : connectionMap.entrySet()) {
+            String databaseName = entry.getKey();
+            listTemp.add(databaseName);
+        }
+        //dao nguoc chuoi cho dung thu tu
+        for (int i = listTemp.size(); i > 0; i--) {
+            listReturn.add(listTemp.get(i - 1));
+        }
+        return listReturn;
+    }
+}

+ 347 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/ConnectionPoolObject.java

@@ -0,0 +1,347 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.database;
+
+import com.mchange.v2.c3p0.ComboPooledDataSource;
+import java.util.Properties;
+
+/**
+ *
+ * @author MinhNH
+ */
+public class ConnectionPoolObject {
+
+    private Properties pro;
+    private String id;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public ComboPooledDataSource createPoolConnection() throws Exception {
+        ComboPooledDataSource cpds = new ComboPooledDataSource();
+
+        // <editor-fold defaultstate="collapsed" desc="Cau hinh bat buoc">
+        //
+        if (getProperty("driver") != null && !getProperty("driver").equals("")) {
+            try {
+                cpds.setDriverClass(getProperty("driver"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: driver");
+            }
+        } else {
+            throw new Exception("ERROR in property: driver is null");
+        }
+        //
+        if (getProperty("connection") != null && !getProperty("connection").equals("")) {
+            try {
+                cpds.setJdbcUrl(getProperty("connection"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: connection");
+            }
+        } else {
+            throw new Exception("ERROR in property: connection is null");
+        }
+        //
+        if (getProperty("username") != null && !getProperty("username").equals("")) {
+            try {
+                cpds.setUser(getProperty("username"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: username");
+            }
+        } else {
+            throw new Exception("ERROR in property: username is null");
+        }
+        //
+        if (getProperty("password") != null && !getProperty("password").equals("")) {
+            try {
+                cpds.setPassword(getProperty("password"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: password");
+            }
+        } else {
+            throw new Exception("ERROR in property: password is null");
+        }
+        //set readtimeout
+        if (getProperty("readTimeout") != null) {
+            try {
+                int readTimeout = Integer.parseInt(getProperty("readTimeout"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: readTimeout must be an Integer");
+            }
+            Properties prop = new Properties();
+            prop.setProperty("oracle.jdbc.ReadTimeout", getProperty("readTimeout"));
+            prop.setProperty("user", getProperty("username"));
+            prop.setProperty("password", getProperty("password"));
+            cpds.setProperties(prop);
+        } else {
+            throw new Exception("ERROR in property: readTimeout is null");
+        }
+        // </editor-fold>
+
+        // <editor-fold defaultstate="collapsed" desc="Cau hinh khong bat buoc">
+        //
+        if (getProperty("checkoutTimeout") != null) {
+            try {
+                cpds.setCheckoutTimeout(Integer.parseInt(getProperty("checkoutTimeout")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: checkoutTimeout");
+            }
+        }
+        //
+        if (getProperty("acquireIncrement") != null) {
+            try {
+                cpds.setAcquireIncrement(Integer.parseInt(getProperty("acquireIncrement")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: acquireIncrement");
+            }
+        }
+        if (getProperty("acquireRetryAttempts") != null) {
+            try {
+                cpds.setAcquireRetryAttempts(Integer.parseInt(getProperty("acquireRetryAttempts")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: acquireRetryAttempts");
+            }
+        }
+        if (getProperty("acquireRetryDelay") != null) {
+            try {
+                cpds.setAcquireRetryDelay(Integer.parseInt(getProperty("acquireRetryDelay")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: acquireRetryDelay");
+            }
+        }
+        if (getProperty("autoCommitOnClose") != null) {
+            try {
+                cpds.setAutoCommitOnClose(Boolean.parseBoolean(getProperty("autoCommitOnClose")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: autoCommitOnClose");
+            }
+        }
+        if (getProperty("automaticTestTable") != null) {
+            try {
+                cpds.setAutomaticTestTable(getProperty("automaticTestTable"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: automaticTestTable");
+            }
+        }
+        if (getProperty("breakAfterAcquireFailure") != null) {
+            try {
+                cpds.setBreakAfterAcquireFailure(Boolean.parseBoolean("breakAfterAcquireFailure"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: breakAfterAcquireFailure");
+            }
+        }
+        if (getProperty("checkoutTimeout") != null) {
+            try {
+                cpds.setCheckoutTimeout(Integer.parseInt(getProperty("checkoutTimeout")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: checkoutTimeout");
+            }
+        }
+        if (getProperty("connectionCustomizerClassName") != null) {
+            try {
+                cpds.setConnectionCustomizerClassName(getProperty("connectionCustomizerClassName"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: connectionCustomizerClassName");
+            }
+        }
+        if (getProperty("connectionTesterClassName") != null) {
+            try {
+                cpds.setConnectionTesterClassName(getProperty("connectionTesterClassName"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: connectionTesterClassName");
+            }
+        }
+        if (getProperty("dataSourceName") != null) {
+            try {
+                cpds.setDataSourceName(getProperty("dataSourceName"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: dataSourceName");
+            }
+        }
+        if (getProperty("debugUnreturnedConnectionStackTraces") != null) {
+            try {
+                cpds.setDebugUnreturnedConnectionStackTraces(Boolean.parseBoolean(getProperty("debugUnreturnedConnectionStackTraces")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: debugUnreturnedConnectionStackTraces");
+            }
+        }
+        if (getProperty("factoryClassLocation") != null) {
+            try {
+                cpds.setFactoryClassLocation(getProperty("factoryClassLocation"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: factoryClassLocation");
+            }
+        }
+        if (getProperty("forceIgnoreUnresolvedTransactions") != null) {
+            try {
+                cpds.setForceIgnoreUnresolvedTransactions(Boolean.parseBoolean(getProperty("forceIgnoreUnresolvedTransactions")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: forceIgnoreUnresolvedTransactions");
+            }
+        }
+        if (getProperty("idleConnectionTestPeriod") != null) {
+            try {
+                cpds.setIdleConnectionTestPeriod(Integer.parseInt(getProperty("idleConnectionTestPeriod")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: idleConnectionTestPeriod");
+            }
+        }
+        if (getProperty("initialPoolSize") != null) {
+            try {
+                cpds.setInitialPoolSize(Integer.parseInt(getProperty("initialPoolSize")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: initialPoolSize");
+            }
+        }
+        if (getProperty("maxAdministrativeTaskTime") != null) {
+            try {
+                cpds.setMaxAdministrativeTaskTime(Integer.parseInt(getProperty("maxAdministrativeTaskTime")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxAdministrativeTaskTime");
+            }
+        }
+        if (getProperty("maxConnectionAge") != null) {
+            try {
+                cpds.setMaxConnectionAge(Integer.parseInt(getProperty("maxConnectionAge")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxConnectionAge");
+            }
+        }
+        if (getProperty("maxIdleTime") != null) {
+            try {
+                cpds.setMaxIdleTime(Integer.parseInt(getProperty("maxIdleTime")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxIdleTime");
+            }
+        }
+        if (getProperty("maxIdleTimeExcessConnections") != null) {
+            try {
+                cpds.setMaxIdleTimeExcessConnections(Integer.parseInt(getProperty("maxIdleTimeExcessConnections")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxIdleTimeExcessConnections");
+            }
+        }
+        if (getProperty("maxPoolSize") != null) {
+            try {
+                cpds.setMaxPoolSize(Integer.parseInt(getProperty("maxPoolSize")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxPoolSize");
+            }
+        }
+        if (getProperty("maxStatements") != null) {
+            try {
+                cpds.setMaxStatements(Integer.parseInt(getProperty("maxStatements")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxStatements");
+            }
+        }
+        if (getProperty("maxStatementsPerConnection") != null) {
+            try {
+                cpds.setMaxStatementsPerConnection(Integer.parseInt(getProperty("maxStatementsPerConnection")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: maxStatementsPerConnection");
+            }
+        }
+        if (getProperty("minPoolSize") != null) {
+            try {
+                cpds.setMinPoolSize(Integer.parseInt(getProperty("minPoolSize")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: minPoolSize");
+            }
+        }
+        if (getProperty("numHelperThreads") != null) {
+            try {
+                cpds.setNumHelperThreads(Integer.parseInt(getProperty("numHelperThreads")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: numHelperThreads");
+            }
+        }
+        if (getProperty("overrideDefaultUser") != null) {
+            try {
+                cpds.setOverrideDefaultUser(getProperty("overrideDefaultUser"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: overrideDefaultUser");
+            }
+        }
+        if (getProperty("overrideDefaultPassword") != null) {
+            try {
+                cpds.setOverrideDefaultPassword(getProperty("overrideDefaultPassword"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: overrideDefaultPassword");
+            }
+        }
+        if (getProperty("preferredTestQuery") != null) {
+            try {
+                cpds.setPreferredTestQuery(getProperty("preferredTestQuery"));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: preferredTestQuery");
+            }
+        }
+        if (getProperty("propertyCycle") != null) {
+            try {
+                cpds.setPropertyCycle(Integer.parseInt(getProperty("propertyCycle")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: propertyCycle");
+            }
+        }
+        if (getProperty("statementCacheNumDeferredCloseThreads") != null) {
+            try {
+                cpds.setStatementCacheNumDeferredCloseThreads(Integer.parseInt(getProperty("statementCacheNumDeferredCloseThreads")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: statementCacheNumDeferredCloseThreads");
+            }
+        }
+        if (getProperty("testConnectionOnCheckin") != null) {
+            try {
+                cpds.setTestConnectionOnCheckin(Boolean.parseBoolean(getProperty("testConnectionOnCheckin")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: testConnectionOnCheckin");
+            }
+        }
+        if (getProperty("testConnectionOnCheckout") != null) {
+            try {
+                cpds.setTestConnectionOnCheckout(Boolean.parseBoolean(getProperty("testConnectionOnCheckout")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: testConnectionOnCheckout");
+            }
+
+        }
+        if (getProperty("unreturnedConnectionTimeout") != null) {
+            try {
+                cpds.setUnreturnedConnectionTimeout(Integer.parseInt(getProperty("unreturnedConnectionTimeout")));
+            } catch (Exception ex) {
+                throw new Exception("ERROR in property: unreturnedConnectionTimeout");
+            }
+        }
+        // </editor-fold>
+
+        return cpds;
+    }
+
+    public ConnectionPoolObject(Properties pro) {
+        this.pro = pro;
+    }
+
+    public Properties getPro() {
+        return pro;
+    }
+
+    public void setPro(Properties pro) {
+        this.pro = pro;
+    }
+
+    public String getProperty(String key) {
+        return this.pro.getProperty(key);
+    }
+
+    public void setProperty(String key, String value) {
+        this.pro.setProperty(key, value);
+    }
+}

+ 110 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/DbProcessorAbstract.java

@@ -0,0 +1,110 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.database;
+
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Date;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author MinhNH
+ */
+public class DbProcessorAbstract {
+
+    public String dbName;
+    //
+    private Logger logger;
+    private String loggerLabel = "DbProcessorAbstract: ";
+    public static int SUCCESS = 0;
+    public static int FAIL = -1;
+    //
+    public StringBuffer br = new StringBuffer();
+    //
+    public static int QUERY_TIMEOUT = 300; // Time out query
+    public static int TIME_BREAK = 0;
+    public static int TIME_BREAK_DELETE_RECORD_TIMEOUT = 0;
+    //
+
+    public DbProcessorAbstract() {
+    }
+
+    public void init(String dbName, Logger logger) {
+        try {
+            this.logger = logger;
+            this.dbName = dbName;
+        } catch (Exception ex) {
+            logger.error(loggerLabel + new Date() + "\nLoi khoi tao DbProcessor() Framework", ex);
+        }
+    }
+
+    public void closeConnection(Connection conn) {
+        if (conn != null) {
+            try {
+                conn.close();
+                conn = null;
+            } catch (SQLException ex) {
+                logger.warn(loggerLabel + "Close Statement: " + ex);
+                conn = null;
+            }
+        }
+    }
+
+    public void closeStatement(PreparedStatement stmt) {
+        if (stmt != null) {
+            try {
+                stmt.close();
+                stmt = null;
+            } catch (SQLException ex) {
+                logger.warn(loggerLabel + "ERROR close Statement: " + ex.getMessage());
+                stmt = null;
+            }
+        }
+    }
+
+    public void closeResultSet(ResultSet rs) {
+        if (rs != null) {
+            try {
+                rs.close();
+                rs = null;
+            } catch (SQLException ex) {
+                logger.warn(loggerLabel + "ERROR close ResultSet: " + ex.getMessage());
+                rs = null;
+            }
+        }
+    }
+
+    public Connection getConnection(String dbName) {
+        return ConnectionPoolManager.getConnection(dbName);
+    }
+
+    public void logTime(String strLog, long timeSt) {
+        long timeEx = System.currentTimeMillis() - timeSt;
+        if (timeEx >= WebserviceManager.minTimeDb && WebserviceManager.loggerDbMap != null) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(WebserviceManager.getTimeLevelDb(timeEx)).append(": ").
+                    append(strLog).
+                    append(": ").
+                    append(timeEx).
+                    append(" ms");
+
+            logger.warn(br);
+        } else {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(strLog).
+                    append(": ").
+                    append(timeEx).
+                    append(" ms");
+
+            logger.info(br);
+        }
+    }
+}

+ 7056 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/database/WsProcessUtils.java

@@ -0,0 +1,7056 @@
+/*
+ * @DbProcess.java	version 1.0	27/02/2010
+ *
+ * Copyright 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.database;
+
+import com.vas.kittyfallwsvas.wsfw.obj.Configuration;
+import com.vas.kittyfallwsvas.wsfw.obj.Game;
+import com.vas.kittyfallwsvas.wsfw.obj.ChargeLog;
+import com.vas.kittyfallwsvas.wsfw.obj.RankingObj;
+import com.vas.kittyfallwsvas.wsfw.obj.ProductInfo;
+import com.vas.kittyfallwsvas.wsfw.obj.TopPlayer;
+import com.vas.kittyfallwsvas.wsfw.obj.PlayingTimeRewrad;
+import com.vas.kittyfallwsvas.wsfw.obj.MpsConfigObj;
+import com.vas.kittyfallwsvas.wsfw.obj.ListPrize;
+import com.vas.kittyfallwsvas.wsfw.obj.SmsMtObj;
+import com.vas.kittyfallwsvas.wsfw.obj.HistoryPrize;
+import com.vas.kittyfallwsvas.wsfw.obj.WebServiceLog;
+import com.vas.kittyfallwsvas.wsfw.obj.SpinRecharge;
+import com.vas.kittyfallwsvas.wsfw.obj.FqInviting;
+import com.vas.kittyfallwsvas.wsfw.obj.PointTotalObj;
+import com.vas.kittyfallwsvas.wsfw.obj.UserInfo;
+import com.vas.kittyfallwsvas.wsfw.obj.TransactionLog;
+import com.vas.kittyfallwsvas.wsfw.obj.MinigameReward;
+import com.vas.kittyfallwsvas.wsfw.obj.AccountInfo;
+import com.vas.kittyfallwsvas.wsfw.obj.HistoryPlay;
+import com.vas.kittyfallwsvas.wsfw.obj.PlayingTimeHistory;
+import com.vas.kittyfallwsvas.wsfw.obj.SpinGift;
+import com.vas.kittyfallwsvas.wsfw.obj.RegisterInfo;
+import com.vas.kittyfallwsvas.wsfw.common.Common;
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+
+import static com.vas.kittyfallwsvas.wsfw.database.DbProcessorAbstract.TIME_BREAK;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.LuckySprin;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.PrizeObj;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.PrizeWinner;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.SpinResultObj;
+
+
+import java.sql.*;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import oracle.jdbc.OracleTypes;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Cac truy van de CSDL he thong
+ *
+ * @author NhungTTT3
+ * @since 27-02-2010
+ */
+public class WsProcessUtils extends DbProcessorAbstract {
+
+    //    private long TIME_LAST_QUERY;
+    private Logger logger;
+    private String loggerLabel = "WsProcessUtils: ";
+    private int ERRORTIME = 3;
+//    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+//    private String schema;
+    private SimpleDateFormat fullDf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
+
+    // user profile
+    private final String SQL_GET_USER_PROFILE_BY_MSISDN
+            = "select * from fq_user_info WHERE msisdn = ?";
+
+    // Them phan check user
+    private final String SQL_GET_USER_BY_MSISDN
+            = "select * from account_user WHERE msisdn = ? and status <> 0";
+    
+    private final String SQL_GET_LISTPRIZE_BY_ACTIONTYPE
+            = "select * from list_prize WHERE action_type = ? and status <> 0 ";
+    private final String SQL_GET_USER_BY_MSISDN_AND_PASSWORD
+            = "select * from account_user WHERE msisdn = ? and pass = ? and service_id = ? and status <> 0";
+    private final String SQL_CHECK_USED_MSISDN = "select * from REG_INFO WHERE msisdn = ? and product_name = ?";
+    private final String sqlGetUser = "select * from ws_user where username = ?";
+    private final String sqlCheckUser = "select * from ws_user where username = ? and password=?";
+    private final String sqlCheckCheckPass = "SELECT * FROM blacklist_Password WHERE password = ?";
+    
+    private final String SQL_GET_MSISDN_TOOL = "SELECT * from tool_sim_play where msisdn = ? ";
+    private final String sqlLuckySprin = "select * from lucky_spin where msisdn = ? ";
+    
+
+    
+    //    private final String SQL_GET_REGISTER_INFO
+//            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1";
+//    private final String SQL_GET_REGISTER_INFO_ALL
+//            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1";
+//    private final String SQL_GET_REGISTER_IN_DAY
+//            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and expire_time > sysdate order by register_time desc";
+    private final String SQL_GET_TOTAL_MONEY_PAID
+            = "select nvl(sum(money),0) money from history_play where money is not null and play_day > trunc(sysdate)";
+    private final String SQL_LOAD_PRIZE
+            = "SELECT * FROM LIST_PRIZE WHERE status = 1 ";
+    private final String SQL_SELECT_PRIZE
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_PRIZE_NOTX2
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where type <> 2 or type_add <> 2 ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_WINNER_NO_REGISTER
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where type <> 4 or number_add = 0 ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_WINNER_NO_REGISTER_NOTX2
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (type <> 4 or number_add = 0) and (type <> 2 or type_add <> 2) ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_WINNER_NO_MONEY
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where type <> 2 or (type = 2 and type_add = 1 and number_add < 2) ORDER BY DBMS_RANDOM.RANDOM) "
+            + "WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_WINNER_NO_MONEY_NOTX2
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (type <> 2 or (type = 2 and type_add = 1 and number_add < 2)) and (type <> 2 or type_add <> 2) ORDER BY DBMS_RANDOM.RANDOM) "
+            + "WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (number_add <= 0) or (type = 1) or (type = 2 and type_add = 1 and number_add < 2) ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
+    private final String SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY_NOTX2
+            = "SELECT * FROM (SELECT * FROM  LIST_PRIZE where (number_add <= 0 or (type = 1) or (type = 2 and type_add = 1 and number_add < 2)) and (type <> 2 or type_add <> 2) ORDER BY DBMS_RANDOM.RANDOM) WHERE status = 1 and rownum <= 1";
+    private final String SQL_GET_CURRENT_RANK
+            = "select no, spin_count from (select msisdn, spin_count, rownum no from "
+            + "(select * from ranking where sub_type = ? and rank_type = ? and period = ? and end_time > sysdate order by spin_count desc, last_update)) "
+            + "where msisdn = ?";
+    //    private final String SQL_GET_CURRENT_RANK_UNSUB
+//            = "select no, spin_count from (select msisdn, spin_count, rownum no from "
+//            + "(select * from ranking where sub_type = 0 and end_time > sysdate order by spin_count desc)) "
+//            + "where msisdn = ?";
+    private static final String SQL_CHECK_TIMES_PLAY
+            = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1";
+    private static final String SQL_INSERT_HISTORY_PLAY_WINNER
+            = "insert into history_play(id,list_id, register_id,MSISDN,product_name, play_day,spin_times,played_times,type,type_add,number_add, money, balance_id,note) "
+            + "values(history_play_seq.NEXTVAL, ?,?,?,?, sysdate, ?, ?, ?,?,?,?,?,?)";
+    private static final String SQL_TRANS_LOG
+            = "INSERT INTO TRANSACTION_LOG(TRANSACTION_ID, TYPE, MSISDN, REQUEST, RESPONSE,"
+            + "ERROR_CODE, COMMAND, REQUEST_TIME, RESPONSE_TIME, CHANNEL) "
+            + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
+
+    public WsProcessUtils(String dbName, Logger logger) {
+        this.logger = logger;
+        this.dbName = dbName;
+        init(dbName, logger);
+    }
+
+    public WsProcessUtils() {
+        super();
+    }
+
+    /**
+     * Close Statement
+     *
+     * @param stmt
+     * @param smName
+     */
+    private void closeStatement(PreparedStatement stmt, String smName) {
+        if (stmt != null) {
+            try {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("Close Statement: ").
+                        append(smName);
+                logger.debug(br);
+                stmt.close();
+                stmt = null;
+            } catch (SQLException ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR close Statement ").
+                        append(smName).
+                        append(": ").
+                        append(ex.getMessage());
+                logger.warn(br);
+                stmt = null;
+            }
+        }
+    }
+
+    public void setDbName(String dbName) {
+        this.dbName = dbName;
+//        schema = ConnectionPoolManager.getConnectionMap().get(dbName).getUser() + ".";
+    }
+
+    public String getDbName() {
+        return this.dbName;
+    }
+
+    public HashMap getConfig(String module) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        ResultSet rs = null;
+        HashMap listMessage = new HashMap();
+        PreparedStatement getConfigSt = null;
+        String sql = "select PARAM_NAME, PARAM_VALUE, PARAM_VALUE_FR from CONFIG where upper(module)=?";
+
+        br.setLength(0);
+        br.append(loggerLabel).
+                append(" GET CONFIG: ").
+                append(sql);
+        logger.info(br);
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            getConfigSt = connection.prepareStatement(sql);
+            getConfigSt.setString(1, module.toUpperCase());
+            rs = getConfigSt.executeQuery();
+            while (rs.next()) {
+                listMessage.put(rs.getString("PARAM_NAME"), rs.getString("PARAM_VALUE"));
+                listMessage.put(rs.getString("PARAM_NAME") + "_FR", rs.getString("PARAM_VALUE_FR"));
+            }
+        } catch (Exception ex) {
+            logger.error(loggerLabel + "ERROR getListMessage", ex);
+
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(getConfigSt, sql);
+            closeConnection(connection);
+            logTime("Time to getConfig", timeStart);
+        }
+        return listMessage;
+    }
+
+    protected void closeResource(ResultSet rs) {
+        try {
+            if (rs != null) {
+                rs.close();
+                rs = null;
+            }
+        } catch (SQLException e) {
+            this.logger.warn(e);
+            rs = null;
+        }
+    }
+
+    protected void closeResource(Statement stmt) {
+        try {
+            if (stmt != null) {
+                stmt.close();
+                stmt = null;
+            }
+        } catch (SQLException e) {
+            this.logger.warn(e);
+            stmt = null;
+        }
+    }
+
+    protected void closeResource(Connection conn) {
+        try {
+            if (conn != null) {
+                conn.close();
+                conn = null;
+            }
+        } catch (SQLException e) {
+            this.logger.warn(e);
+            conn = null;
+        }
+    }
+
+    /**
+     * Kiem tra thue bao dang su dung dich vu hay khong
+     *
+     * @param msisdn
+     * @param productName
+     * @return
+     */
+    /**
+     * Ghi log webservice
+     *
+     * @param ws
+     * @return
+     */
+    public boolean iInsertWsLog(WebServiceLog ws) {
+        long timeSt = System.currentTimeMillis();
+        boolean result = false;
+
+        while (true) {
+            result = insertWsLog(ws);
+            if (result != true) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK iInsertWsLog ==> ERROR DATABASE\n").
+                            append(ws.toString());
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private boolean insertWsLog(WebServiceLog ws) {
+
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        String sqlInsertWSLog = "insert into ws_log (ID,REQUEST,RESPONSE,REQUESTTIME,RESPONSETIME,RESPONSECODE,USERID,CHANNEL,IPCLIENT,MSISDN,FEE,WS_NAME)"
+                + "values ( WS_LOG_SEQ.NEXTVAL,?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
+
+        br.setLength(0);
+        br.append(loggerLabel).
+                append("Insert WEBSERVICE_LOG:\n").
+                append(ws.toString());
+        logger.debug(br);
+
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sqlInsertWSLog);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, ws.getRequest().toString());
+            ps.setString(2, ws.getResponse().toString());
+            ps.setTimestamp(3, ws.getRequestTime());
+            ps.setTimestamp(4, ws.getResponseTime());
+            ps.setString(5, ws.getResponseCode());
+            ps.setLong(6, ws.getUserId());
+            ps.setString(7, ws.getChannel());
+            ps.setString(8, ws.getIpClient());
+            ps.setString(9, ws.getMsisdn());
+            ps.setDouble(10, ws.getFee());
+            ps.setString(11, ws.getWsName());
+            return ps.execute();
+
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR Insert to WEBSERVICE_LOG: ").
+                    append(ex.toString()).
+                    append("\n").
+                    append(ws.toString());
+            logger.error(br, ex);
+        } finally {
+            closeStatement(ps, sqlInsertWSLog);
+            closeConnection(connection);
+            logTime("Time to iInsertWsLog", timeStart);
+        }
+        return false;
+    }
+
+    public Boolean updateAddMoreTimes(long registerId, int times) {
+
+        try {
+            return iUpdateAddMoreTimes(registerId, times);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateAddMoreTimes");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdateAddMoreTimes(long registerId, int times) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE reg_info SET number_spin = number_spin + ? WHERE register_id = ? AND status = 1";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setInt(1, times);
+            ps.setLong(2, registerId);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateAddMoreTimes");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateAddMoreTimes", timeStart);
+        }
+    }
+
+    public Boolean updateRenewReg(RegisterInfo regInfo) {
+
+        try {
+            return iUpdateRenewReg(regInfo);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateRegisterInfo");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdateRenewReg(RegisterInfo regInfo) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "update reg_info set expire_time=?, number_spin=? , extend_status=?, status = ?, played_times = ?, last_extend = sysdate "
+                + "  where register_id=?";
+        ;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setTimestamp(1, regInfo.getExpireTime());
+            ps.setInt(2, regInfo.getNumberSpin());
+            ps.setInt(3, regInfo.getExtendStatus());
+            ps.setInt(4, regInfo.getStatus());
+            ps.setInt(5, regInfo.getPlayedTimes());
+            ps.setLong(6, regInfo.getRegisterId());
+
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateRenewReg");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateRenewReg", timeStart);
+        }
+    }
+
+    public boolean iInsertChargeLog(ChargeLog ws) {
+        long timeSt = System.currentTimeMillis();
+        boolean result = false;
+
+        while (true) {
+            result = insertChargeLog(ws);
+            if (result != true) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK iInsertChargeLog ==> ERROR DATABASE\n").
+                            append(ws.toString());
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private boolean insertChargeLog(ChargeLog ws) {
+
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        String sql = "INSERT INTO charge_log (ID,MSISDN,FEE,CHARGE_TIME,INSERT_TIME,DESCRIPTION,ACCOUNT_ID, STATUS) \n"
+                + "VALUES(charge_log_seq.nextval, ?, ?, ?, sysdate, ?, ?, ?)";
+
+        br.setLength(0);
+        br.append(loggerLabel).
+                append("Insert WEBSERVICE_LOG:\n").
+                append(ws.toString());
+        logger.debug(br);
+
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, ws.getMsisdn());
+            ps.setDouble(2, ws.getFee());
+            ps.setTimestamp(3, ws.getChargeTime());
+            ps.setString(4, ws.getDescription());
+            ps.setString(5, ws.getAccountId());
+            ps.setInt(6, ws.getStatus());
+            return ps.execute();
+
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR insertChargeLog: ").
+                    append(ex.toString()).
+                    append("\n").
+                    append(ws.toString());
+            logger.error(br, ex);
+        } finally {
+            closeStatement(ps, sql);
+            closeConnection(connection);
+            logTime("Time to insertChargeLog", timeStart);
+        }
+        return false;
+    }
+
+    public UserInfo iGetUser(String userName) {
+        UserInfo user = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (user == null) {
+            try {
+                user = getUserInfo(userName);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query select VTFREE_USER\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return user;
+    }
+
+    /**
+     * Lay thong tin nguoi dung
+     *
+     * @param userName
+     * @return
+     * @throws SQLException
+     */
+    private UserInfo getUserInfo(String userName) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        UserInfo user = null;
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sqlGetUser);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, userName);
+            rs = ps.executeQuery();
+            user = new UserInfo();
+
+            if (rs.next()) {
+                logger.info("result: " + rs);
+                user.setWsUserId(rs.getLong(UserInfo.WS_USER_ID));
+                user.setUser(userName);
+                user.setPass(rs.getString(UserInfo.PASS));
+                user.setIp(rs.getString(UserInfo.IP));
+            }
+            logger.info("user: " + user);
+            return user;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps, sqlGetUser);
+            closeConnection(connection);
+            logTime("Time to getUserInfo", timeStart);
+        }
+    }
+
+    /**
+     * Lay mo_seq de insert db
+     *
+     * @return
+     */
+    public Long iGetMoSequence() {
+        long timeSt = System.currentTimeMillis();
+        Long result = null;
+
+        while (true) {
+            result = getMoSequence();
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK getMoSequence ==> ERROR DATABASE\n");
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Long getMoSequence() {
+        long timeStart = System.currentTimeMillis();
+        String sqlGetMoSeq = "select mo_seq.nextval SEQ from dual";
+
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sqlGetMoSeq);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            rs = ps.executeQuery();
+            //check MSISDN
+            while (rs.next()) {
+                return rs.getLong("SEQ");
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getMoSequence").
+                    append(ex.toString());
+
+            logger.error(br, ex);
+        } finally {
+            closeStatement(ps, sqlGetMoSeq);
+            closeResultSet(rs);
+            closeConnection(connection);
+            logTime("Time to getMoSequence", timeStart);
+        }
+        return null;
+    }
+
+    public int[] insertMt(SmsMtObj mt) {
+        long timeBegin = System.currentTimeMillis();
+        int count = 0;
+        int[] result = null;
+        while (result == null) {
+            try {
+                count++;
+                result = iInsertMt(mt);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR insert insertMt");
+                logger.error(br, ex);
+            }
+            if (result == null && ((System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) || (count > 3))) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK query insertMt\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private int[] iInsertMt(SmsMtObj mt) throws Exception {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sqlInsertMt = "insert into MT(MT_ID, MO_HIS_ID,MSISDN,MESSAGE,RECEIVE_TIME,RETRY_NUM,CHANNEL) "
+                + "values(MT_SEQ.NEXTVAL, 0, ?, ?, sysdate, 0, ?)";
+        long startTime = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sqlInsertMt);
+            ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            ps.clearParameters();
+            ps.setString(1, mt.getMsisdn());
+            ps.setString(2, mt.getMessage());
+            ps.setString(3, mt.getChannel());
+            ps.addBatch();
+            return ps.executeBatch();
+
+        } catch (Exception ex) {
+            logger.error("Exception : ", ex);
+        } finally {
+            closeStatement(ps);
+            closeConnection(connection);
+            logTime("Time to insertMt", startTime);
+        }
+        return null;
+    }
+
+    public int[] insertMt(String msisdn, String message, String channel) {
+        long timeBegin = System.currentTimeMillis();
+        int count = 0;
+        int[] result = null;
+        while (result == null) {
+            try {
+                count++;
+                result = iInsertMt(msisdn, message, channel);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR insert insertMt");
+                logger.error(br, ex);
+            }
+            if (result == null && ((System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) || (count > 3))) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK query insertMt\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private int[] iInsertMt(String msisdn, String message, String channel) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sqlInsertMt = "insert into MT(MT_ID,MO_HIS_ID,MSISDN,MESSAGE,RECEIVE_TIME,RETRY_NUM,CHANNEL) "
+                + "values(MT_SEQ.NEXTVAL, 0, ?, ?, sysdate, 0, ?)";
+        long startTime = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sqlInsertMt);
+            ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            ps.clearParameters();
+            ps.setString(1, msisdn);
+            ps.setString(2, message);
+            ps.setString(3, channel);
+            ps.addBatch();
+            return ps.executeBatch();
+
+        } catch (Exception ex) {
+            logger.error("Exception : ", ex);
+        } finally {
+            closeStatement(ps);
+            closeConnection(connection);
+            logTime("Time to insertMt", startTime);
+        }
+        return null;
+    }
+
+    public Boolean getMsisdnTool(String msisdn ) {
+        long timeBegin = System.currentTimeMillis();
+        Boolean result = null;
+        int count = 0;
+        while (result == null) {
+            try {
+                result = iGetMsisdnTool(msisdn);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR getMsisdnTool");
+                logger.error(br, ex);
+                count++;
+            }
+            if ((result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery)
+                    || count >= 3) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK getMsisdnTool\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+    
+    private Boolean iGetMsisdnTool(String msisdn) throws SQLException {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        ResultSet rs = null;            
+        long startTime = System.currentTimeMillis();
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_GET_MSISDN_TOOL);
+           if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+
+            // Kiểm tra có dữ liệu hay không
+            return rs.next();
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetMsisdnTool",startTime);
+        }
+    }
+    
+    public boolean iInsertRegisterInfo(RegisterInfo regInfo) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertRegisterInfo(regInfo);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR iInsertRegisterInfo ");
+                logger.error(br, ex);
+                count++;
+            }
+            if ((result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery)
+                    || count >= 3) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK iInsertRegisterInfo\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+    
+    private boolean insertRegisterInfo(RegisterInfo regInfo) throws Exception {
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "insert into reg_info (register_id, msisdn, product_name, register_time, number_spin, played_times, extend_status, status, expire_time, renew, service_id, channel) "
+                + "values (register_seq.nextval, ?, ?, sysdate, ?, ?, 0, 1, ?, ?, ?, ?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, regInfo.getMsisdn());
+            ps.setString(2, regInfo.getProductName());
+            ps.setInt(3, regInfo.getNumberSpin());
+            ps.setInt(4, regInfo.getPlayedTimes());
+            ps.setTimestamp(5, regInfo.getExpireTime());
+            ps.setInt(6, regInfo.getRenew());
+            ps.setInt(7, regInfo.getServiceId());
+            ps.setString(8, regInfo.getChannel());
+
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to insertRegisterInfo", startTime);
+        }
+        return rs;
+    }
+
+    public Boolean checkRegistered(String msisdn, String packName) {
+        Boolean registered = null;
+        try {
+            registered = iCheckRegistered(msisdn, packName);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkRegistered");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private Boolean iCheckRegistered(String msisdn, String packName) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_CHECK_USED_MSISDN);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, packName);
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                return true;
+            }
+            return false;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iCheckRegistered");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check registered", startTime);
+        }
+    }
+
+    public Boolean checkRegisteredForTheFirstTime(String msisdn, String serviceId) {
+        Boolean registered = null;
+        try {
+            registered = iCheckRegisteredForTheFirstTime(msisdn, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkRegistered");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private Boolean iCheckRegisteredForTheFirstTime(String msisdn, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "select * from REG_INFO WHERE msisdn = ? and renew = 1 and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                return true;
+            }
+            return false;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iCheckRegistered");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check registered", startTime);
+        }
+    }
+
+    public int getTotalMoneyPaid() {
+        try {
+            return iGetTotalMoneyPaid();
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getTotalMoneyPaid");
+            logger.error(br, ex);
+        }
+        return 3000;
+    }
+
+    private int iGetTotalMoneyPaid() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_GET_TOTAL_MONEY_PAID);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            //ps.setInt(1, questionLevel);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                return rs.getInt("money");
+            }
+            return 0;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetTotalMoneyPaid");
+            logger.error(br, ex);
+            return 3000;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetTotalMoneyPaid", startTime);
+        }
+    }
+
+    public HashMap<String, ListPrize> loadPrize() {
+        HashMap<String, ListPrize> mapQuestion = new HashMap();
+        try {
+            mapQuestion = iLoadPrize();
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR loadPrize");
+            logger.error(br, ex);
+        }
+        return mapQuestion;
+    }
+
+    private HashMap iLoadPrize() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        HashMap result = new HashMap();
+        long startTime = System.currentTimeMillis();
+
+        try {
+            connection = getConnection(dbName);
+
+            ps = connection.prepareStatement(SQL_LOAD_PRIZE);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            //ps.setInt(1, questionLevel);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                ListPrize prize = new ListPrize();
+                prize.setPrizeId(rs.getInt("PRIZE_ID"));
+                prize.setType(rs.getInt("type"));
+                prize.setTypeAdd(rs.getInt("TYPE_ADD"));
+                prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
+                prize.setMoney(rs.getDouble("MONEY"));
+                prize.setBalanceId(rs.getString("BALANCE_ID"));
+                prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
+                prize.setResetBalance(rs.getInt("RESET_BALANCE"));
+                prize.setDescription(rs.getString("DESCRIPTION"));
+                prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
+                prize.setUnit(rs.getString("UNIT"));
+                result.put(prize.getPrizeId() + "", prize);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetRandomPrize");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iLoadPrize", startTime);
+        }
+        return result;
+
+    }
+
+    public List<ListPrize> getRandomPrize(int type, boolean notX2) {
+        List<ListPrize> questionList = new ArrayList<ListPrize>();
+        try {
+            questionList = iGetRandomPrize(type, notX2);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRandomPrize");
+            logger.error(br, ex);
+        }
+        return questionList;
+    }
+
+    private List<ListPrize> iGetRandomPrize(int type, boolean notX2) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<ListPrize> prizeList = new ArrayList<ListPrize>();
+        long startTime = System.currentTimeMillis();
+        if (type == 1) {
+            try {
+                connection = getConnection(dbName);
+
+                ps = connection.prepareStatement(notX2 ? SQL_SELECT_PRIZE_NOTX2 : SQL_SELECT_PRIZE);
+                if (WebserviceManager.queryDbTimeout > 0) {
+                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+                }
+                //ps.setInt(1, questionLevel);
+                rs = ps.executeQuery();
+                while (rs.next()) {
+                    ListPrize prize = new ListPrize();
+                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
+                    prize.setType(rs.getInt("type"));
+                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
+                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
+                    prize.setMoney(rs.getDouble("MONEY"));
+                    prize.setBalanceId(rs.getString("BALANCE_ID"));
+                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
+                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
+                    prize.setDescription(rs.getString("DESCRIPTION"));
+                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
+                    prize.setUnit(rs.getString("UNIT"));
+                    prizeList.add(prize);
+                }
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR iGetRandomPrize");
+                logger.error(br, ex);
+                return null;
+            } finally {
+                closeResource(rs);
+                closeResource(ps);
+                closeResource(connection);
+                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
+            }
+            return prizeList;
+        } else if (type == 2) {
+            // get all, except add money
+            try {
+                connection = getConnection(dbName);
+
+                ps = connection.prepareStatement(notX2 ? SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY_NOTX2 : SQL_SELECT_WINNER_NO_REGISTER_NO_MONEY);
+                if (WebserviceManager.queryDbTimeout > 0) {
+                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+                }
+                //ps.setInt(1, questionLevel);
+                rs = ps.executeQuery();
+                while (rs.next()) {
+                    ListPrize prize = new ListPrize();
+                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
+                    prize.setType(rs.getInt("type"));
+                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
+                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
+                    prize.setMoney(rs.getDouble("MONEY"));
+                    prize.setBalanceId(rs.getString("BALANCE_ID"));
+                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
+                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
+                    prize.setDescription(rs.getString("DESCRIPTION"));
+                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
+                    prize.setUnit(rs.getString("UNIT"));
+                    prizeList.add(prize);
+                }
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR iGetRandomPrize");
+                logger.error(br, ex);
+                return null;
+            } finally {
+                closeResource(rs);
+                closeResource(ps);
+                closeResource(connection);
+                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
+            }
+            return prizeList;
+        } else if (type == 3) {
+            // get all, except add money
+            try {
+                connection = getConnection(dbName);
+                ps = connection.prepareStatement(notX2 ? SQL_SELECT_WINNER_NO_MONEY_NOTX2 : SQL_SELECT_WINNER_NO_MONEY);
+                if (WebserviceManager.queryDbTimeout > 0) {
+                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+                }
+                //ps.setInt(1, questionLevel);
+                rs = ps.executeQuery();
+                while (rs.next()) {
+                    ListPrize prize = new ListPrize();
+                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
+                    prize.setType(rs.getInt("type"));
+                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
+                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
+                    prize.setMoney(rs.getDouble("MONEY"));
+                    prize.setBalanceId(rs.getString("BALANCE_ID"));
+                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
+                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
+                    prize.setDescription(rs.getString("DESCRIPTION"));
+                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
+                    prize.setUnit(rs.getString("UNIT"));
+                    prizeList.add(prize);
+                }
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR iGetRandomPrize");
+                logger.error(br, ex);
+                return null;
+            } finally {
+                closeResource(rs);
+                closeResource(ps);
+                closeResource(connection);
+                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
+            }
+            return prizeList;
+        } else {
+            // not register --> only lose turn + add money
+            try {
+                connection = getConnection(dbName);
+                ps = connection.prepareStatement(notX2 ? SQL_SELECT_WINNER_NO_REGISTER_NOTX2 : SQL_SELECT_WINNER_NO_REGISTER);
+                if (WebserviceManager.queryDbTimeout > 0) {
+                    ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+                }
+                //ps.setInt(1, questionLevel);
+                rs = ps.executeQuery();
+                while (rs.next()) {
+                    ListPrize prize = new ListPrize();
+                    prize.setPrizeId(rs.getInt("PRIZE_ID"));
+                    prize.setType(rs.getInt("type"));
+                    prize.setTypeAdd(rs.getInt("TYPE_ADD"));
+                    prize.setNumberAdd(rs.getInt("NUMBER_ADD"));
+                    prize.setMoney(rs.getDouble("MONEY"));
+                    prize.setBalanceId(rs.getString("BALANCE_ID"));
+                    prize.setExpireDays(rs.getInt("EXPIRE_DAY"));
+                    prize.setResetBalance(rs.getInt("RESET_BALANCE"));
+                    prize.setDescription(rs.getString("DESCRIPTION"));
+                    prize.setRatioMoney(rs.getInt("RATIO_MONEY"));
+                    prize.setUnit(rs.getString("UNIT"));
+                    prizeList.add(prize);
+                }
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append(new Date()).
+                        append("\nERROR iGetRandomPrize");
+                logger.error(br, ex);
+                return null;
+            } finally {
+                closeResource(rs);
+                closeResource(ps);
+                closeResource(connection);
+                logTime("Time to iGetRandomPrize (" + type + "," + notX2 + ")", startTime);
+            }
+            return prizeList;
+        }
+
+    }
+
+    public List<HistoryPrize> getMyPrizes(String msisdn) {
+        try {
+            return iGetMyPrizes(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getMyPrizes");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private List<HistoryPrize> iGetMyPrizes(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        List<HistoryPrize> result = null;
+        String sql = "select * from (Select msisdn, to_char(play_day,'dd/MM/yyyy HH24:mi:ss') play_day, play_day play_time, note from history_play "
+                + "where msisdn = ? order by play_time desc) where rownum <= 10";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            result = new ArrayList();
+            while (rs.next()) {
+                HistoryPrize obj = new HistoryPrize();
+                obj.setMsisdn(rs.getString("MSISDN"));
+                obj.setPlayDay(rs.getString("play_day"));
+                obj.setNote(rs.getString("note"));
+                result.add(obj);
+            }
+            return result;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetMyPrizes");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetMyPrizes", startTime);
+        }
+    }
+
+    public List<TopPlayer> getCurrentTopPlayer(int subType, int rankType, int period) {
+        try {
+            return iGetCurrentTopPLayer(subType, rankType, period);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getCurrentTopPlayer");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private List<TopPlayer> iGetCurrentTopPLayer(int subType, int rankType, int period) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        List<TopPlayer> result = null;
+        String sql = "Select a.* , rownum from (select * from ranking where sub_type = ? and rank_type = ? and period = ? "
+                + "and end_time > sysdate order by spin_count desc,last_update) a "
+                + "where end_time > sysdate and rownum <= 10";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, subType);
+            ps.setInt(2, rankType);
+            ps.setInt(3, period);
+            rs = ps.executeQuery();
+            result = new ArrayList();
+            while (rs.next()) {
+                TopPlayer obj = new TopPlayer();
+                obj.setMsisdn(rs.getString("MSISDN"));
+                obj.setSpinCount(rs.getInt("SPIN_COUNT"));
+                obj.setRank(rs.getInt("ROWNUM"));
+                result.add(obj);
+            }
+            return result;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetCurrentTopPLayer");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetCurrentTopPLayer", startTime);
+        }
+    }
+
+    /**
+     * @param msisdn
+     * @return Integer[order, spin_count]
+     */
+    public Integer[] iGetCurrentRank(String msisdn, int subType, int rankType, int period) {
+        try {
+            return getCurrentRank(msisdn, subType, rankType, period);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR iGetCurrentRank");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Integer[] getCurrentRank(String msisdn, int subType, int rankType, int period) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_GET_CURRENT_RANK);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, subType);
+            ps.setInt(2, rankType);
+            ps.setInt(3, period);
+            ps.setString(4, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                int no = rs.getInt("NO");
+                int spin = rs.getInt("spin_count");
+                return new Integer[]{no, spin};
+            }
+            return new Integer[]{0, 0};
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getCurrentRank");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to get current rank", startTime);
+        }
+    }
+
+    //    public Integer[] iGetCurrentRankUnsub(String msisdn) {
+//        try {
+//            return getCurrentRankUnsub(msisdn);
+//        } catch (Exception ex) {
+//            br.append(loggerLabel).append(new Date()).append("\nERROR iGetCurrentRankUnsub");
+//            logger.error(br, ex);
+//        }
+//
+//        return null;
+//    }
+//
+//    private Integer[] getCurrentRankUnsub(String msisdn) {
+//        PreparedStatement ps = null;
+//        ResultSet rs = null;
+//        Connection connection = null;
+//        long startTime = System.currentTimeMillis();
+//
+//        try {
+//            connection = getConnection(dbName);
+//            ps = connection.prepareStatement(SQL_GET_CURRENT_RANK_UNSUB);
+//            if (WebserviceManager.queryDbTimeout > 0) {
+//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            ps.setString(1, msisdn);
+//            rs = ps.executeQuery();
+//            while (rs.next()) {
+//                int no = rs.getInt("NO");
+//                int spin = rs.getInt("spin_count");
+//                return new Integer[]{no, spin};
+//            }
+//            return new Integer[]{0, 0};
+//        } catch (Exception ex) {
+//            br.setLength(0);
+//            br.append(loggerLabel).
+//                    append(new Date()).
+//                    append("\nERROR getCurrentRankUnsub");
+//            logger.error(br, ex);
+//            return null;
+//        } finally {
+//            closeResource(rs);
+//            closeResource(ps);
+//            closeResource(connection);
+//            logTime("Time to get current rank unsub", startTime);
+//        }
+//    }
+//    public List<RegisterInfo> getTimesPlay(String msisdn) {
+//        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
+//        try {
+//            questionNumberTimesPlay = iGetTimesPlay(msisdn);
+//        } catch (Exception ex) {
+//            br.append(loggerLabel).append(new Date()).append("\nERROR getTimesPlay");
+//            logger.error(br, ex);
+//        }
+//
+//        return questionNumberTimesPlay;
+//    }
+//
+//    private List<RegisterInfo> iGetTimesPlay(String msisdn) {
+//        PreparedStatement ps = null;
+//        ResultSet rs = null;
+//        Connection connection = null;
+//        List<RegisterInfo> questionNumberTimesPlayList = new ArrayList<RegisterInfo>();
+//
+//        long startTime = System.currentTimeMillis();
+//        try {
+//            connection = getConnection(dbName);
+//            ps = connection.prepareStatement(SQL_CHECK_TIMES_PLAY);
+//            if (WebserviceManager.queryDbTimeout > 0) {
+//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            ps.setString(1, msisdn);
+//            rs = ps.executeQuery();
+//            while (rs.next()) {
+//                RegisterInfo regInfo = new RegisterInfo();
+//                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
+//                regInfo.setMsisdn(rs.getString("MSISDN"));
+//                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
+//                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+//                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+////                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+//                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
+//                regInfo.setStatus(rs.getInt("STATUS"));
+//                questionNumberTimesPlayList.add(regInfo);
+//            }
+//        } catch (Exception ex) {
+//            br.setLength(0);
+//            br.append(loggerLabel).
+//                    append(new Date()).
+//                    append("\nERROR iGetTimesPlay");
+//            logger.error(br, ex);
+//            return null;
+//        } finally {
+//            closeResource(rs);
+//            closeResource(ps);
+//            closeResource(connection);
+//            logTime("Time to iGetTimesPlay", startTime);
+//        }
+//        return questionNumberTimesPlayList;
+//    }
+    public Boolean updatePlayedTimes(int newSpinTimes, long registerId) {
+
+        try {
+            return iUpdatePlayedTimes(newSpinTimes, registerId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updatePlayedTimes");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdatePlayedTimes(int newSpinTimes, long registerId) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE reg_info SET played_times = played_times + 1, number_spin = ? WHERE register_id = ? AND status = 1";
+
+        long startTime = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, newSpinTimes);
+            ps.setLong(2, registerId);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdatePlayedTimes");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdatePlayedTimes " + registerId, startTime);
+        }
+    }
+
+    public boolean iInsertHistoryPlayWinner(HistoryPlay historyWinner) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertHistoryPlayWinner(historyWinner);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).
+                        append("\n").append(SQL_INSERT_HISTORY_PLAY_WINNER);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK iInsertHistoryPlayWinner\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertHistoryPlayWinner(HistoryPlay historyWinner) throws Exception {
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        try {
+
+            connection = getConnection(dbName);
+
+            ps = connection.prepareStatement(SQL_INSERT_HISTORY_PLAY_WINNER);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setLong(1, historyWinner.getListId());
+            ps.setLong(2, historyWinner.getRegisterId());
+            ps.setString(3, historyWinner.getMsisdn());
+            ps.setString(4, historyWinner.getProductName());
+            ps.setInt(5, historyWinner.getSpinedTime());
+            ps.setInt(6, historyWinner.getPlayedTimes());
+            ps.setInt(7, historyWinner.getType());
+            ps.setInt(8, historyWinner.getTypeAdd());
+            ps.setInt(9, historyWinner.getNumberAdd());
+            ps.setDouble(10, historyWinner.getMoney());
+            ps.setString(11, historyWinner.getBalanceId());
+            ps.setString(12, historyWinner.getNote());
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to insertHistoryPlayWinner", startTime);
+        }
+        return rs;
+    }
+
+    public AccountInfo iGetAccountByMsisdn(String msisdn, String productName) {
+        AccountInfo user = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (user == null) {
+            try {
+                user = getAccountByMsisdn(msisdn, productName);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return user;
+    }
+    
+
+    private AccountInfo getAccountByMsisdn(String msisdn, String productName) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        AccountInfo user = null;
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_GET_USER_BY_MSISDN);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+//            ps.setString(2, productName);
+            rs = ps.executeQuery();
+            user = new AccountInfo();
+            logTime("getAccountByMsisdn", timeStart);
+            if (rs.next()) {
+                logTime("next", timeStart);
+                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+                user.setUsers(rs.getString(AccountInfo.USERS));
+                user.setPassword(rs.getString(AccountInfo.PASSWORD));
+                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
+                user.setChannel(rs.getString(AccountInfo.CHANNEL));
+                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+                user.setRole(rs.getString(AccountInfo.ROLE));
+                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
+                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
+                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
+                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
+                user.setStatus(rs.getString(AccountInfo.STATUS));
+                user.setPoint(rs.getString(AccountInfo.POINT));
+                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
+                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
+                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                user.setEmail(rs.getString(AccountInfo.EMAIL));
+                user.setPicture(rs.getString(AccountInfo.PICTURE));
+                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+            }
+            return user;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps, SQL_GET_USER_BY_MSISDN);
+            closeConnection(connection);
+            logTime("Time to getAccountByMsisdn", timeStart);
+        }
+    }
+
+     public PrizeObj igetListPrizeByActionType(String ActionType) {
+        PrizeObj mPrizeObj = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (mPrizeObj == null) {
+            try {
+                mPrizeObj = getListPrizeByActionType(ActionType);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (mPrizeObj == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return mPrizeObj;
+    }
+    
+    private PrizeObj getListPrizeByActionType(String ActionType) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        PrizeObj mPrizeObj = null;
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_GET_LISTPRIZE_BY_ACTIONTYPE);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, ActionType);
+            rs = ps.executeQuery();
+            mPrizeObj = new PrizeObj();
+            logTime("getListPrizeByActionType", timeStart);
+            if (rs.next()) {
+                logTime("next", timeStart);
+                mPrizeObj.setId(rs.getLong(PrizeObj.ID));
+                mPrizeObj.setActionType(rs.getString(PrizeObj.ACTION_TYPE));
+                mPrizeObj.setActionCode(rs.getString(PrizeObj.ACTION_CODE));
+                mPrizeObj.setStatus(rs.getInt(PrizeObj.STATUS));
+                mPrizeObj.setDescription(rs.getString(PrizeObj.DESCRIPTION));
+                mPrizeObj.setPeriod(rs.getInt(PrizeObj.PERIOD));
+                mPrizeObj.setMoneyConverted(rs.getInt(PrizeObj.MONEY_CONVERTED));
+                mPrizeObj.setValuePrize(rs.getInt(PrizeObj.VALUE_PRIZE));
+            }
+            return mPrizeObj;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps, SQL_GET_LISTPRIZE_BY_ACTIONTYPE);
+            closeConnection(connection);
+            logTime("Time to getListPrizeByActionType", timeStart);
+        }
+    }
+    
+    public Boolean updatePointAccountUser(String msisdn, String point, String serviceId) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iUpdatePointAccountUser(msisdn, point, serviceId);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK updatePointAccountUser ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iUpdatePointAccountUser(String msisdn, String point, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "update account_user set point_ = point_ - ? where msisdn = ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, point);
+            ps.setString(2, msisdn);
+            ps.setString(3, serviceId);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iUpdatePointAccountUser: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iUpdatePointAccountUser", timeStart);
+        }
+    }
+
+    public Boolean returnPointAccountUser(String msisdn, String point, String serviceId) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iReturnPointAccountUser(msisdn, point, serviceId);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK returnPointAccountUser ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iReturnPointAccountUser(String msisdn, String point, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "update account_user set point_ = point_ + ? where msisdn = ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, point);
+            ps.setString(2, msisdn);
+            ps.setString(3, serviceId);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iReturnPointAccountUser: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iReturnPointAccountUser", timeStart);
+        }
+    }
+
+    public AccountInfo getUserProfile(String msisdn, String serviceId) {
+        AccountInfo user = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (user == null) {
+            try {
+                user = iGetUserProfile(msisdn, serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query getUserProfile\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return user;
+    }
+
+    private AccountInfo iGetUserProfile(String msisdn, String serviceId) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        AccountInfo user = null;
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement("select MSISDN, PICTURE, BIRTHDAY, FULLNAME, EMAIL, POINT_ from account_user WHERE msisdn = ? and status <> 0 and service_id = ?");
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, serviceId);
+            rs = ps.executeQuery();
+            user = new AccountInfo();
+            logTime("iGetUserProfile", timeStart);
+            if (rs.next()) {
+                logTime("next", timeStart);
+                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                user.setEmail(rs.getString(AccountInfo.EMAIL));
+                user.setPicture(rs.getString(AccountInfo.PICTURE));
+                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+                user.setPoint(rs.getString(AccountInfo.POINT));
+
+            }
+            return user;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps, SQL_GET_USER_BY_MSISDN);
+            closeConnection(connection);
+            logTime("Time to iGetUserProfile", timeStart);
+        }
+    }
+
+    public AccountInfo iGetAccountByMsisdnAndPassword(String msisdn, String password, String serviceId) {
+        AccountInfo user = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (user == null) {
+            try {
+                user = getAccountByMsisdnAndPassword(msisdn, password, serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return user;
+    }
+
+    private AccountInfo getAccountByMsisdnAndPassword(String msisdn, String password, String serviceId) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        AccountInfo user = null;
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_GET_USER_BY_MSISDN_AND_PASSWORD);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, password);
+            ps.setString(3, serviceId);
+            rs = ps.executeQuery();
+            user = new AccountInfo();
+            logTime("getAccountByMsisdnAndPassword", timeStart);
+            if (rs.next()) {
+                logTime("next", timeStart);
+                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+                user.setUsers(rs.getString(AccountInfo.USERS));
+                user.setPassword(rs.getString(AccountInfo.PASSWORD));
+                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
+                user.setChannel(rs.getString(AccountInfo.CHANNEL));
+                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+                user.setRole(rs.getString(AccountInfo.ROLE));
+                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
+                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
+                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
+                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
+                user.setStatus(rs.getString(AccountInfo.STATUS));
+                user.setPoint(rs.getString(AccountInfo.POINT));
+                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
+                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
+                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                user.setEmail(rs.getString(AccountInfo.EMAIL));
+                user.setPicture(rs.getString(AccountInfo.PICTURE));
+                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+            }
+            return user;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps, SQL_GET_USER_BY_MSISDN_AND_PASSWORD);
+            closeConnection(connection);
+            logTime("Time to getAccountByMsisdnAndPassword", timeStart);
+        }
+    }
+
+    public Boolean resetSpins(String serviceId, Timestamp lastUpdate) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iResetSpins(serviceId, lastUpdate);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK updateAccountAndSpin ==> ERROR DATABASE\n").
+                            append(lastUpdate);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iResetSpins(String serviceId, Timestamp lastUpdate) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "update account_user set last_update = ?, total_spin = 0, free_spin = 0 where service_id = ? and last_update <= sysdate";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, lastUpdate);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iResetSpins: ").
+                    append(sql).append("\n").
+                    append(lastUpdate);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql);
+            closeConnection(connection);
+            logTime("Time to iResetSpins", timeStart);
+        }
+    }
+
+//    public AccountInfo getAccountAndSpin(String id, String serviceId) {
+//        AccountInfo user = null;
+//        long timeBegin = System.currentTimeMillis();
+//        int count = 1;
+//        while (user == null) {
+//            try {
+//                user = iGetAccountAndSpin(id);
+//            } catch (Exception ex) {
+//                br.setLength(0);
+//                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+//                logger.error(br, ex);
+//                count++;
+//            }
+//            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+//                br.setLength(0);
+//                br.append(loggerLabel).append(new Date()).append("==>BREAK query iGetAccountByMsisdn\n");
+//                logger.error(br);
+//                break;
+//            }
+//        }
+//        return user;
+//    }
+//
+//    private AccountInfo iGetAccountAndSpin(String id) throws SQLException {
+//        ResultSet rs = null;
+//        PreparedStatement ps = null;
+//        AccountInfo user = null;
+//        long timeStart = System.currentTimeMillis();
+//        Connection connection = null;
+//        String sql = "select * from account_user WHERE ID = ? and last_update > sysdate";
+//        try {
+//            connection = getConnection(dbName);
+//            ps = connection.prepareStatement(sql);
+//            if (WebserviceManager.enableQueryDbTimeout) {
+//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            ps.setInt(1, Integer.parseInt(id));
+//            rs = ps.executeQuery();
+//            user = new AccountInfo();
+//            logTime("iUpdateAccountAndSpin", timeStart);
+//            if (rs.next()) {
+//                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+//                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+//                user.setUsers(rs.getString(AccountInfo.USERS));
+//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
+//                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+//                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+//                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+//                user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
+//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
+//                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+//                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+//                user.setRole(rs.getString(AccountInfo.ROLE));
+//                user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
+//                user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
+//                user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
+//                user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
+//                user.setStatus(rs.getString(AccountInfo.STATUS));
+//                user.setPoint(rs.getString(AccountInfo.POINT));
+//                user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
+//                user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
+//                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+//                user.setEmail(rs.getString(AccountInfo.EMAIL));
+//                user.setPicture(rs.getString(AccountInfo.PICTURE));
+//                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+//                logger.info("last update: " + user.getLastUpdate());
+//
+//            }
+//            return user;
+//        } catch (SQLException ex) {
+//            throw ex;
+//        } finally {
+//            closeResultSet(rs);
+//            closeStatement(ps);
+//            closeConnection(connection);
+//            logTime("Time to iUpdateAccountAndSpin", timeStart);
+//        }
+//    }
+
+    public List<AccountInfo> getAccountByUserWonMiniGame(String fromDate, String toDate, String serviceId) {
+        List<AccountInfo> user = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (user == null) {
+            try {
+                user = iGetAccountByUserWonMiniGame(fromDate, toDate, serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (user == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query getAccountByUserWonMiniGame\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return user;
+    }
+
+    private List<AccountInfo> iGetAccountByUserWonMiniGame(String fromDate, String toDate, String serviceId) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        List<MinigameReward> rewards = new ArrayList<>();
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        String sql = "select * from minigame_reward WHERE created_date >= to_date(? || ' 00:00:00', 'MM/DD/YYYY HH24:MI:SS') AND created_date <= to_date(? || ' 23:59:59', 'MM/DD/YYYY HH24:MI:SS') AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, fromDate);
+            ps.setString(2, toDate);
+            ps.setInt(3, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            logTime("iGetAccountByUserWonMiniGame", timeStart);
+            while (rs.next()) {
+                MinigameReward reward = new MinigameReward();
+                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
+                reward.setStatus(rs.getInt(MinigameReward.STATUS));
+                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
+                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
+                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
+                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
+                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
+                reward.setId(rs.getInt(MinigameReward.ID));
+                rewards.add(reward);
+            }
+
+            // get account
+            List<AccountInfo> listAccountWon = new ArrayList<>();
+            String sql2 = "select * from account_user WHERE msisdn = ? AND service_id = ?";
+            for (int i = 0; i < rewards.size(); i++) {
+                ps = connection.prepareStatement(sql2);
+                ps.setString(1, rewards.get(i).getMsisdn());
+                ps.setInt(2, Integer.parseInt(serviceId));
+                rs = ps.executeQuery();
+                AccountInfo user = new AccountInfo();
+                if (rs.next()) {
+                    user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+                    user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+                    user.setUsers(rs.getString(AccountInfo.USERS));
+                    user.setPassword(rs.getString(AccountInfo.PASSWORD));
+                    user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+                    user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+                    user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+                    user.setIsActive(rs.getString(AccountInfo.IS_ACTIVE));
+                    user.setChannel(rs.getString(AccountInfo.CHANNEL));
+                    user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+                    user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+                    user.setRole(rs.getString(AccountInfo.ROLE));
+                    user.setLanguage(rs.getString(AccountInfo.LANGUAGE));
+                    user.setIsLock(rs.getString(AccountInfo.IS_LOCK));
+                    user.setTotalFalse(rs.getString(AccountInfo.TOTAL_FALSE));
+                    user.setTimeLock(rs.getString(AccountInfo.TIME_LOCK));
+                    user.setStatus(rs.getString(AccountInfo.STATUS));
+                    user.setPoint(rs.getString(AccountInfo.POINT));
+                    user.setLastUpdate(rs.getString(AccountInfo.LAST_UPDATE));
+                    user.setLastLogin(rs.getString(AccountInfo.LAST_LOGIN));
+                    user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                    user.setEmail(rs.getString(AccountInfo.EMAIL));
+                    user.setPicture(rs.getString(AccountInfo.PICTURE));
+                    user.setFullName(rs.getString(AccountInfo.FULLNAME));
+                    listAccountWon.add(user);
+                }
+            }
+            return listAccountWon;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps);
+            closeConnection(connection);
+            logTime("Time to iGetAccountByUserWonMiniGame", timeStart);
+        }
+    }
+
+    public Boolean updateAccountAndSpin(String id, Timestamp lastUpdate) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iUpdateAccountAndSpin(id, lastUpdate);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK updateAccountAndSpin ==> ERROR DATABASE\n").
+                            append(id);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iUpdateAccountAndSpin(String id, Timestamp lastUpdate) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "update account_user set last_update = ?, total_spin = 0, free_spin = 0 where ID = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, lastUpdate);
+            ps.setInt(2, Integer.parseInt(id));
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iUpdateAccountAndSpin: ").
+                    append(sql1).append("\n").
+                    append(id);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iUpdateAccountAndSpin", timeStart);
+        }
+    }
+
+    public Boolean iAddPointToAccountByMsisdn(String msisdn, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "update account_user set POINT_ = POINT_ + 3 where msisdn = ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR addPointToAccountByMsisdn: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to addPointToAccountByMsisdn", timeStart);
+        }
+    }
+
+    public Boolean insertAccountUser(String msisdn, String password, String channel, String productName) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iInsertAccountUser(msisdn, password, channel, productName);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK insertAccountUser ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iInsertAccountUser(String msisdn, String password, String channel, String productName) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "insert into account_user (id, msisdn, users, pass, channel, free_spin, service_id) \n"
+                + "values(account_seq.nextval, ?, ?, ?, ?, ?, ?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, msisdn);
+            ps.setString(3, password);
+            ps.setString(4, channel);
+            ps.setInt(5, Common.Constant.SPIN_FREE);
+            ps.setString(6, productName);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iInsertAccountUser: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iInsertAccountUser", timeStart);
+        }
+    }
+
+    public Boolean insertUserProfile(String msisdn) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iInsertUserProfile(msisdn);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK insertAccountUser ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iInsertUserProfile(String msisdn) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "insert into fq_user_info (id, msisdn) \n"
+                + "values(users_seq.nextval, ?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iInsertUserProfile: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iInsertUserProfile", timeStart);
+        }
+    }
+
+    public Boolean createAccountUser(String msisdn, String password, String channel, String serviceId) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iCreateAccountUser(msisdn, password, channel, serviceId);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK insertAccountUser ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iCreateAccountUser(String msisdn, String password, String channel, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "insert into account_user (id, msisdn, users, pass, channel, service_Id) \n"
+                + "values(account_seq.nextval, ?, ?, ?, ?, ?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, msisdn);
+            ps.setString(3, password);
+            ps.setString(4, channel);
+            ps.setString(5, serviceId);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iCreateAccountUser: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iCreateAccountUser", timeStart);
+        }
+    }
+
+    public Boolean createInviting(String msisdn, String friendMsisdn, String channel, String serviceId) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iCreateInviting(msisdn, friendMsisdn, channel, serviceId);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK createInviting ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iCreateInviting(String msisdn, String friendMsisdn, String channel, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "insert into fq_inviting (id, owner_msisdn, friend_msisdn, channel, service_Id, status) \n"
+                + "values(inviting_seq.nextval, ?, ?, ?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, friendMsisdn);
+            ps.setString(3, channel);
+            ps.setString(4, serviceId);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iCreateInviting: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iCreateInviting", timeStart);
+        }
+    }
+
+    public Boolean updateAccountUser(String msisdn, String password) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iUpdateAccountUser(msisdn, password);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK updateAccountUser ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iUpdateAccountUser(String msisdn, String password) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "update account_user set pass = ? where msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, password);
+            ps.setString(2, msisdn);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iUpdateAccountUser: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iUpdateAccountUser", timeStart);
+        }
+    }
+
+    public Boolean createUserInfo(String msisdn) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iCreateUserInfo(msisdn);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK createUserInfo ==> ERROR DATABASE\n").
+                            append(msisdn);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iCreateUserInfo(String msisdn) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "insert into fq_user_info (id, msisdn) \n"
+                + "values(users_seq.nexval, ?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iCreateUserInfo: ").
+                    append(sql1).append("\n").
+                    append(msisdn);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iCreateUserInfo", timeStart);
+        }
+    }
+
+    public List<SpinRecharge> checkValidSpinRecharge(String msisdn) {
+        List<SpinRecharge> result = new ArrayList<SpinRecharge>();
+        try {
+            result = iCheckValidSpinRecharge(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkValidSpinRecharge");
+            logger.error(br, ex);
+        }
+
+        return result;
+    }
+
+    private List<SpinRecharge> iCheckValidSpinRecharge(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<SpinRecharge> listReg = new ArrayList<SpinRecharge>();
+        String sql = "select * from spin_recharge where msisdn = ? and charge_time >= trunc(sysdate) and status = 0";
+        long timeStart = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                SpinRecharge spinRecharge = new SpinRecharge();
+                spinRecharge.setId(rs.getLong("ID"));
+                spinRecharge.setMsisdn(rs.getString("MSISDN"));
+                spinRecharge.setChargeTime(rs.getTimestamp("CHARGE_TIME"));
+                spinRecharge.setMoney(rs.getDouble("MONEY"));
+                spinRecharge.setSpinAdded(rs.getInt("SPIN_ADDED"));
+                spinRecharge.setStatus(rs.getInt("STATUS"));
+                spinRecharge.setLastUpdate(rs.getTimestamp("LAST_UPDATE"));
+                listReg.add(spinRecharge);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR checkValidSpinRecharge");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check valid spin recharge " + msisdn, timeStart);
+        }
+        return listReg;
+    }
+
+    public Boolean iUpdateClaimSpinRecharge(long id) {
+
+        try {
+            return updateClaimSpinRecharge(id);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateClaimSpinRecharge");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean updateClaimSpinRecharge(long id) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE spin_recharge SET status = 1, last_update = sysdate WHERE id = ?";
+        long timeStart = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setLong(1, id);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updateClaimSpinRecharge");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updateClaimSpinRecharge", timeStart);
+        }
+    }
+
+    public List<SpinGift> getSpinGift(String msisdn) {
+        List<SpinGift> questionNumberTimesPlay = new ArrayList<SpinGift>();
+        try {
+            questionNumberTimesPlay = iGetSpinGift(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getSpinGift");
+            logger.error(br, ex);
+        }
+
+        return questionNumberTimesPlay;
+    }
+
+    private List<SpinGift> iGetSpinGift(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long timeStart = System.currentTimeMillis();
+        List<SpinGift> listReg = new ArrayList<SpinGift>();
+        String sql = "select * from spin_gift where msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                SpinGift spinGift = new SpinGift();
+                spinGift.setId(rs.getLong("ID"));
+                spinGift.setMsisdn(rs.getString("MSISDN"));
+                spinGift.setGiftMsisdn(rs.getString("GIFT_MSISDN"));
+                spinGift.setGiftTime(rs.getTimestamp("GIFT_TIME"));
+                spinGift.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                spinGift.setLastUpdate(rs.getTimestamp("LAST_UPDATE"));
+                listReg.add(spinGift);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetSpinGift");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetSpinGift", timeStart);
+        }
+        return listReg;
+    }
+
+    public Boolean iUpdateSpinGift(SpinGift sg) {
+
+        try {
+            return updateSpinGift(sg);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateSpinGift");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean updateSpinGift(SpinGift sg) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        long timeStart = System.currentTimeMillis();
+        String sql = "UPDATE spin_gift SET gift_msisdn=?, number_spin = ?, last_update = sysdate WHERE msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, sg.getGiftMsisdn());
+            ps.setInt(2, sg.getNumberSpin());
+            ps.setString(3, sg.getMsisdn());
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updateSpinGift");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updateSpinGift", timeStart);
+        }
+    }
+
+    public Boolean iUpdatePassword(String msisdn, String newPassword) {
+        try {
+            return updatePassword(msisdn, newPassword);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR iUpdatePassword");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean updatePassword(String msisdn, String newPassword) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        long timeStart = System.currentTimeMillis();
+        String sql = "UPDATE account_user SET password=?,  last_update = sysdate WHERE msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, newPassword);
+            ps.setString(2, msisdn);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updatePassword");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updatePassword", timeStart);
+        }
+    }
+
+    public Boolean iUpdateLastLogin(String msisdn) {
+        try {
+            return updateLastLogin(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateLastLogin");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean updateLastLogin(String msisdn) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        long timeStart = System.currentTimeMillis();
+        String sql = "UPDATE account_user SET  last_update = sysdate, last_login = sysdate WHERE msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updateLastLogin");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updateLastLogin", timeStart);
+        }
+    }
+
+    public boolean iInsertSpinGift(SpinGift sg) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertSpinGift(sg);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertSpinGift - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertSpinGift\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertSpinGift(SpinGift sg) throws Exception {
+        boolean rs = false;
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "INSERT INTO spin_gift (ID,MSISDN,GIFT_MSISDN,GIFT_TIME,NUMBER_SPIN,LAST_UPDATE) \n"
+                + "VALUES(spin_gift_seq.nextval, ?, ?, sysdate, ?, sysdate)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, sg.getMsisdn());
+            ps.setString(2, sg.getGiftMsisdn());
+            ps.setInt(3, sg.getNumberSpin());
+
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to insertSpinGift", timeStart);
+        }
+        return rs;
+    }
+
+    public Boolean disableAutoExtend(long registerId) {
+        long timeSt = System.currentTimeMillis();
+        Boolean result = false;
+
+        while (true) {
+            result = iDisableAutoExtend(registerId);
+            if (result != null) {
+                break;
+            } else {
+                if (TIME_BREAK <= 0 || (System.currentTimeMillis() - timeSt) > TIME_BREAK) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("BREAK disableAutoExtend ==> ERROR DATABASE\n").
+                            append(registerId);
+                    logger.error(br);
+                    break;
+                }
+                try {
+                    Thread.sleep(1000);
+                } catch (Exception e) {
+                }
+            }
+        }
+        return result;
+    }
+
+    private Boolean iDisableAutoExtend(long registerId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql1 = "update reg_info set status = 0, end_time = sysdate where register_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql1);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setLong(1, registerId);
+            ps.execute();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).append(new Date()).
+                    append("\nERROR iDisableAutoExtend: ").
+                    append(sql1).append("\n").
+                    append(registerId);
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeStatement(ps, sql1);
+            closeConnection(connection);
+            logTime("Time to iDisableAutoExtend", timeStart);
+        }
+    }
+
+    public List<RankingObj> getRankObj(String msisdn, int rankType, int period) {
+        List<RankingObj> rankList = new ArrayList<RankingObj>();
+        try {
+            rankList = iGetRankObj(msisdn, rankType, period);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRankObj");
+            logger.error(br, ex);
+        }
+
+        return rankList;
+    }
+
+    private List<RankingObj> iGetRankObj(String msisdn, int rankType, int period) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RankingObj> listRanking = new ArrayList<RankingObj>();
+        String sql = "select * from ranking where msisdn = ? and rank_type = ? and period = ? and end_time > sysdate";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, rankType);
+            ps.setInt(3, period);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RankingObj rankObj = new RankingObj();
+                rankObj.setId(rs.getLong("ID"));
+                rankObj.setMsisdn(rs.getString("MSISDN"));
+                rankObj.setStartTime(rs.getTimestamp("START_TIME"));
+                rankObj.setEndTime(rs.getTimestamp("END_TIME"));
+                rankObj.setSpintCount(rs.getInt("SPIN_COUNT"));
+                rankObj.setRankType(rs.getInt("RANK_TYPE"));
+                listRanking.add(rankObj);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetRankObj");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetRankObj", timeStart);
+        }
+        return listRanking;
+    }
+
+    public Boolean iUpdateRanking(long id, int subType, int count) {
+
+        try {
+            return updateRanking(id, subType, count);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateRanking");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean updateRanking(long id, int subType, int count) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE ranking  SET spin_count=spin_count+ ? ,last_update = sysdate, sub_type = ? WHERE id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, count);
+            ps.setInt(2, subType);
+            ps.setLong(3, id);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updateRanking");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updateRanking", timeStart);
+        }
+    }
+
+    public boolean iInsertRanking(RankingObj ranking) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertRanking(ranking);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR InsertRanking - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK InsertRanking\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertRanking(RankingObj ranking) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+//        PreparedStatement ps2 = null;
+        Connection connection = null;
+        String sql = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+                + "VALUES(ranking_seq.nextval, ?, ?, ?, ?, sysdate, sysdate,?, ?, 0)";
+//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, ranking.getMsisdn());
+            ps.setTimestamp(2, ranking.getStartTime());
+            ps.setTimestamp(3, ranking.getEndTime());
+            ps.setInt(4, ranking.getSpintCount());
+            ps.setInt(5, ranking.getSubType());
+            ps.setInt(6, ranking.getRankType());
+            ps.executeUpdate();
+
+//            ps2 = connection.prepareStatement(sqlWeek);
+//            if (WebserviceManager.enableQueryDbTimeout) {
+//                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            ps2.setString(1, ranking.getMsisdn());
+//            ps2.setTimestamp(2, ranking.getStartTime());
+//            ps2.setInt(3, ranking.getSpintCount());
+//            ps2.setInt(4, ranking.getSubType());
+//            ps2.setInt(5, ranking.getRankType());
+//            ps2.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to insertRanking", timeStart);
+        }
+        return rs;
+    }
+
+    public boolean iInsertRankingWeekly(RankingObj ranking) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertRankingWeekly(ranking);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertRankingWeekly - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertRankingWeekly\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertRankingWeekly(RankingObj ranking) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps2 = null;
+        Connection connection = null;
+        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+
+            ps2 = connection.prepareStatement(sqlWeek);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps2.setString(1, ranking.getMsisdn());
+            ps2.setTimestamp(2, ranking.getStartTime());
+            ps2.setInt(3, ranking.getSpintCount());
+            ps2.setInt(4, ranking.getSubType());
+            ps2.setInt(5, ranking.getRankType());
+            ps2.executeUpdate();
+
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to insertRankingWeekly", timeStart);
+        }
+        return rs;
+    }
+
+    public boolean iInsertRankingMonth(RankingObj ranking) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertRankingMonth(ranking);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR iInsertRankingMonth - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK iInsertRankingMonth\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertRankingMonth(RankingObj ranking) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps2 = null;
+        Connection connection = null;
+        String sqlMonth = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+                + "VALUES(ranking_seq.nextval, ?, ?, add_months(trunc(sysdate,'MM'),1) - 1/86400, ?, sysdate, sysdate,?, ?, 2)";
+        try {
+            connection = getConnection(dbName);
+            ps2 = connection.prepareStatement(sqlMonth);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps2.setString(1, ranking.getMsisdn());
+            ps2.setTimestamp(2, ranking.getStartTime());
+//            ps2.setTimestamp(3, ranking.getEndTime());
+            ps2.setInt(3, ranking.getSpintCount());
+            ps2.setInt(4, ranking.getSubType());
+            ps2.setInt(5, ranking.getRankType());
+            ps2.executeUpdate();
+
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to insertRankingMonth", timeStart);
+        }
+        return rs;
+    }
+
+    public boolean iInsertInviteTemp(String msisdn) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertInviteTemp(msisdn);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertInviteTemp - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertInviteTemp\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertInviteTemp(String msisdn) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "INSERT INTO invite_temp (MSISDN) \n"
+                + "VALUES(?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to insertInviteTemp", timeStart);
+        }
+        return rs;
+    }
+
+    public boolean iInsertInviteHistory(String msisdn, String friend) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertInviteHistory(msisdn, friend);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertInviteHistory - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertInviteHistory\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertInviteHistory(String msisdn, String friend) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "INSERT INTO invite_history (ID,MSISDN,INVITED_MSISDN,INVITE_DATE) \n"
+                + "VALUES(invite_history_seq.nextval, ?, ?, sysdate)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, friend);
+
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to insertInviteHistory", timeStart);
+        }
+        return rs;
+    }
+
+    public Boolean checkInviteHistory(String msisdn, String friendMsisdn) {
+        Boolean registered = null;
+        try {
+            registered = iCheckInviteHistory(msisdn, friendMsisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkInviteHistory");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private Boolean iCheckInviteHistory(String msisdn, String friendMsisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "Select * from invite_history where msisdn = ? and invited_msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, friendMsisdn);
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                return true;
+            }
+            return false;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR checkInviteHistory");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check checkInviteHistory", startTime);
+        }
+    }
+
+    public String checkPresentInvite(String friendMsisdn) {
+        String registered = null;
+        try {
+            registered = iCheckPresentInvite(friendMsisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkPresentInvite");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private String iCheckPresentInvite(String friendMsisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "Select * from invite_history where invited_msisdn = ? and get_present = 0";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, friendMsisdn);
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                return rs.getString("msisdn");
+            }
+            return "";
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iCheckPresentInvite");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check iCheckPresentInvite", startTime);
+        }
+    }
+
+    public Boolean updatePresentInvite(String friendMsisdn) {
+        Boolean registered = null;
+        try {
+            registered = iUpdatePresentInvite(friendMsisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updatePresentInvite");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private Boolean iUpdatePresentInvite(String friendMsisdn) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "update invite_history set get_present = 1 where invited_msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, friendMsisdn);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updatePresentInvite");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check updatePresentInvite", startTime);
+        }
+    }
+
+    public Boolean deleteInviteTemp(String msisdn) {
+
+        try {
+            return iDeleteInviteTemp(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR deleteInviteTemp");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iDeleteInviteTemp(String msisdn) {
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "DELETE from invite_temp where msisdn = ?";
+
+        long startTime = System.currentTimeMillis();
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR deleteInviteTemp");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to deleteInviteTemp", startTime);
+        }
+    }
+
+    public Boolean checkInvited(String msisdn) {
+        Boolean registered = null;
+        try {
+            registered = iCheckInvited(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkInvited");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private Boolean iCheckInvited(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "Select * from invite_temp where msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                return true;
+            }
+            return false;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iCheckInvited");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to check iCheckInvited", startTime);
+        }
+    }
+
+    public List<PointTotalObj> getPointTotal(String msisdn) {
+        List<PointTotalObj> rankList = new ArrayList<PointTotalObj>();
+        try {
+            rankList = iGetPointTotal(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getPointTotal");
+            logger.error(br, ex);
+        }
+
+        return rankList;
+    }
+
+    private List<PointTotalObj> iGetPointTotal(String msisdn) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<PointTotalObj> listPoint = new ArrayList<PointTotalObj>();
+        String sql = "select * from point_total where msisdn = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                PointTotalObj pointTotalObj = new PointTotalObj();
+                pointTotalObj.setId(rs.getLong("ID"));
+                pointTotalObj.setMsisdn(rs.getString("MSISDN"));
+                pointTotalObj.setLastUpdate(rs.getTimestamp("LAST_UPDATE"));
+                pointTotalObj.setPoint(rs.getInt("POINT"));
+                listPoint.add(pointTotalObj);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetRankObj");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetPointTotal", timeStart);
+        }
+        return listPoint;
+    }
+
+    public Integer getChangedPoint(String msisdn) {
+        Integer result = null;
+        try {
+            result = iGetChangedPoint(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getChangedPoint");
+            logger.error(br, ex);
+        }
+
+        return result;
+    }
+
+    private Integer iGetChangedPoint(String msisdn) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        Integer result = null;
+        String sql = "select nvl(-sum(fee),0) * 10 point from charge_log where msisdn = ? and charge_time > trunc(sysdate) and description = 'Change point'";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                result = rs.getInt("point");
+            }
+            return result;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getChangedPoint");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to getChangedPoint", timeStart);
+        }
+    }
+
+    public Boolean iUpdatePointTotal(long id, int pointAdded) {
+
+        try {
+            return updatePointTotal(id, pointAdded);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updatePointTotal");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean updatePointTotal(long id, int pointAdded) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE point_total SET point=point+? ,last_update = sysdate WHERE id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, pointAdded);
+            ps.setLong(2, id);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updatePointTotal");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updatePointTotal", timeStart);
+        }
+    }
+
+    public boolean iInsertPointTotal(PointTotalObj pointTotal) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = insertPointTotal(pointTotal);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR iInsertPointTotal - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK iInsertPointTotal\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean insertPointTotal(PointTotalObj pointObj) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "INSERT INTO point_total (ID,MSISDN,POINT,LAST_UPDATE,SUB_TYPE) \n"
+                + "VALUES(point_total_seq.nextval,?,?,sysdate,?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, pointObj.getMsisdn());
+            ps.setInt(2, pointObj.getPoint());
+            ps.setInt(3, pointObj.getSubType());
+
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to insertPointTotal", timeStart);
+        }
+        return rs;
+    }
+
+    public List iLoadPackage() {
+        List mConfig = null;
+        long timeBegin = System.currentTimeMillis();
+        while (mConfig == null) {
+            try {
+                mConfig = loadPackage();
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - iLoadPackage");
+                logger.error(br, ex);
+            }
+            if (mConfig == null && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK iLoadPackage");
+                logger.error(br);
+                break;
+            }
+        }
+        return mConfig;
+    }
+
+    private List loadPackage() throws SQLException {
+        long timeStart = System.currentTimeMillis();
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        List listConfig = null;
+        String sql = "SELECT * FROM PACKG";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            rs = ps.executeQuery();
+            listConfig = new ArrayList();
+            while (rs.next()) {
+                ProductInfo prize = new ProductInfo();
+                prize.setProductId(rs.getInt("PRODUCT_ID"));
+                prize.setFee(rs.getDouble("FEE"));
+                prize.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                prize.setProductName(rs.getString("PRODUCT_NAME"));
+                prize.setSmsSyntax(rs.getString("SMS_SYNTAX"));
+                prize.setBizId(rs.getInt("BIZ_ID"));
+                prize.setExpireDays(rs.getInt("EXPIRE_DAYS"));
+                prize.setRenew(rs.getInt("RENEW"));
+                listConfig.add(prize);
+            }
+            logger.error("result: " + listConfig);
+
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to loadPackage", timeStart);
+        }
+        return listConfig;
+    }
+
+    public FqInviting getInvitingActive(String msisdn) {
+        FqInviting inviter = null;
+        try {
+            inviter = iGetInvitingActive(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getInviting");
+            logger.error(br, ex);
+        }
+
+        return inviter;
+    }
+
+    private FqInviting iGetInvitingActive(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        FqInviting inviting = new FqInviting();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM FQ_INVITING WHERE FRIEND_MSISDN = ? and status = 1";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                inviting.setId(rs.getInt("ID"));
+                inviting.setSvId(rs.getInt("SERVICE_ID"));
+                inviting.setCreatedDate(rs.getTimestamp("CREATED_DATE"));
+                inviting.setOwnerMsisdn(rs.getString("OWNER_MSISDN"));
+                inviting.setFriendMsisdn(rs.getString("FRIEND_MSISDN"));
+                inviting.setUpdateDate(rs.getTimestamp("UPDATE_DATE"));
+                inviting.setStatus(rs.getInt("STATUS"));
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetInviting");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetInviting", startTime);
+        }
+        return inviting;
+    }
+
+    public FqInviting getInviting(String msisdn) {
+        FqInviting inviter = null;
+        try {
+            inviter = iGetInviting(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getInviting");
+            logger.error(br, ex);
+        }
+
+        return inviter;
+    }
+
+    private FqInviting iGetInviting(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        FqInviting inviting = new FqInviting();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM FQ_INVITING WHERE FRIEND_MSISDN = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                inviting.setId(rs.getInt("ID"));
+                inviting.setSvId(rs.getInt("SERVICE_ID"));
+                inviting.setCreatedDate(rs.getTimestamp("CREATED_DATE"));
+                inviting.setOwnerMsisdn(rs.getString("OWNER_MSISDN"));
+                inviting.setFriendMsisdn(rs.getString("FRIEND_MSISDN"));
+                inviting.setUpdateDate(rs.getTimestamp("UPDATE_DATE"));
+                inviting.setStatus(rs.getInt("STATUS"));
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetInviting");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetInviting", startTime);
+        }
+        return inviting;
+    }
+
+    public Boolean updateStatusInvitingFriend(String ownerMsisdn, String friendMsisdn, String serviceId) {
+
+        try {
+            Boolean update = iUpdateStatusInvitingFriend(ownerMsisdn, friendMsisdn, serviceId);
+            return update;
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateStatusInvitingFriend");
+            logger.error(br, ex);
+        }
+        return null;
+    }
+
+    private Boolean iUpdateStatusInvitingFriend(String ownerMsisdn, String friendMsisdn, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE fq_inviting SET status = 0 WHERE FRIEND_MSISDN = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, friendMsisdn);
+            //ps.setInt(2, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateStatusInvitingFriend");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateStatusInvitingFriend", timeStart);
+        }
+    }
+
+    public List<RegisterInfo> getRegisterInfo(String msisdn, String packName) {
+        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
+        try {
+            questionNumberTimesPlay = iGetRegisterInfo(msisdn, packName);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInfo");
+            logger.error(br, ex);
+        }
+
+        return questionNumberTimesPlay;
+    }
+
+    // case the user can play, don't care about the expire date, for renewMps
+    private List<RegisterInfo> iGetRegisterInfo(String msisdn, String packName) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+//        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1";
+        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1 and renew = 1";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, packName);
+
+//            ps.setString(2, packName);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo regInfo = new RegisterInfo();
+                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
+                regInfo.setMsisdn(rs.getString("MSISDN"));
+                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
+                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
+                regInfo.setStatus(rs.getInt("STATUS"));
+                listReg.add(regInfo);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetRegisterInfo");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to get reg info", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getRegisterNotCheckStatusInfo(String msisdn, String packName) {
+        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
+        try {
+            questionNumberTimesPlay = iGetRegisterNotCheckStatusInfo(msisdn, packName);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInfo");
+            logger.error(br, ex);
+        }
+
+        return questionNumberTimesPlay;
+    }
+
+    // case the user can play, don't care about the expire date, for renewMps
+    private List<RegisterInfo> iGetRegisterNotCheckStatusInfo(String msisdn, String packName) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+//        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and status = 1";
+        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and renew = 1 and end_time is null ORDER BY expire_time DESC";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, packName);
+
+//            ps.setString(2, packName);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo regInfo = new RegisterInfo();
+                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
+                regInfo.setMsisdn(rs.getString("MSISDN"));
+                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
+                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
+                regInfo.setStatus(rs.getInt("STATUS"));
+                listReg.add(regInfo);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetRegisterInfo");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to get reg info", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getRegisterInfoAll(String msisdn) {
+        List<RegisterInfo> questionNumberTimesPlay = new ArrayList<RegisterInfo>();
+        try {
+            questionNumberTimesPlay = iGetRegisterInfoAll(msisdn);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInfoAll");
+            logger.error(br, ex);
+        }
+
+        return questionNumberTimesPlay;
+    }
+
+    private List<RegisterInfo> iGetRegisterInfoAll(String msisdn) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo regInfo = new RegisterInfo();
+                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
+                regInfo.setMsisdn(rs.getString("MSISDN"));
+                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
+                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
+                regInfo.setStatus(rs.getInt("STATUS"));
+                listReg.add(regInfo);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getRegisterInfoAll");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to get reg info all", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getRegisterInday(String msisdn, String productName) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGetRegisterInday(msisdn, productName);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    // get active package by product. A user can register other packages while this package is still active.
+    private List<RegisterInfo> iGetRegisterInday(String msisdn, String productName) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and product_name = ? and renew = 1 and status = 1 and expire_time > sysdate order by register_time desc";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, productName);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo regInfo = new RegisterInfo();
+                regInfo.setRegisterId(rs.getLong("REGISTER_ID"));
+                regInfo.setMsisdn(rs.getString("MSISDN"));
+                regInfo.setProductName(rs.getString("PRODUCT_NAME"));
+                regInfo.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                regInfo.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                regInfo.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+                regInfo.setExtendStatus(rs.getInt("EXTEND_STATUS"));
+                regInfo.setStatus(rs.getInt("STATUS"));
+                regInfo.setRenew(rs.getInt("RENEW"));
+                listReg.add(regInfo);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getRegisterInDay");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to get reg info in day", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getUserServices(String msisdn, String serviceId) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGetUserServices(msisdn, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getUserServices");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<RegisterInfo> iGetUserServices(String msisdn, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1 and service_id = ? and expire_time > sysdate order by register_time desc";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, serviceId);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo info = new RegisterInfo();
+                info.setRegisterId(rs.getLong("REGISTER_ID"));
+                info.setMsisdn(rs.getString("MSISDN"));
+                info.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+                info.setProductName(rs.getString("PRODUCT_NAME"));
+                info.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                info.setStatus(rs.getInt("STATUS"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetUserServices");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetUserServices", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getUserServicesRenew(String msisdn, String serviceId) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGetUserServicesRenew(msisdn, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getUserServices");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<RegisterInfo> iGetUserServicesRenew(String msisdn, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE MSISDN = ? and status = 1 and renew = 1 and service_id = ? and expire_time > sysdate order by register_time desc";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setString(2, serviceId);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo info = new RegisterInfo();
+                info.setRegisterId(rs.getLong("REGISTER_ID"));
+                info.setMsisdn(rs.getString("MSISDN"));
+                info.setPlayedTimes(rs.getInt("PLAYED_TIMES"));
+                info.setProductName(rs.getString("PRODUCT_NAME"));
+                info.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                info.setStatus(rs.getInt("STATUS"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetUserServices");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetUserServices", startTime);
+        }
+        return listReg;
+    }
+
+    public List<Game> getDataByParentId(String parentId, String seqPage, String rowOnPage, String serviceId) {
+        List<Game> listGames = new ArrayList<Game>();
+        try {
+            listGames = iGetDataByParentId(parentId, seqPage, rowOnPage, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
+            logger.error(br, ex);
+        }
+
+        return listGames;
+    }
+
+    private List<Game> iGetDataByParentId(String parentId, String seqPage, String rowOnPage, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<Game> listGames = new ArrayList<Game>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM (SELECT ID, code, content_type, content_, created_date, description_global, " +
+                "description_local, from_date, icon, introduction_global, introduction_local, is_played, level_, " +
+                "logo, name_global, name_local, parent_id, service_id, status, to_date_, type_of, update_date," +
+                "ROW_NUMBER() OVER (ORDER BY update_date) R FROM FQ_GAMES where PARENT_ID = ? AND service_id = ?) where R BETWEEN ? and ?";
+//        SELECT last_name FROM
+//                (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
+//        WHERE R BETWEEN 51 and 100;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            int seq = Integer.parseInt(seqPage);
+            int row = Integer.parseInt(rowOnPage);
+            int from = (seq - 1) * row + 1;
+            int to = (seq) * row;
+
+
+            ps.setString(1, parentId);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.setInt(3, from);
+            ps.setInt(4, to);
+//            ps.setInt(3, to);
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                Game game = new Game();
+                game.setId(rs.getString(Game.ID));
+                game.setCode(rs.getString(Game.CODE));
+                game.setContent(rs.getString(Game.CONTENT));
+                game.setContentType(rs.getString(Game.CONTENT_TYPE));
+                game.setCreatedDate(rs.getString(Game.CREATED_DATE));
+                game.setDescriptionGlobal(rs.getString(Game.DESCRIPTION_GLOBAL));
+                game.setDescriptionLocal(rs.getString(Game.DESCRIPTION_LOCAL));
+                game.setFromDate(rs.getString(Game.FROM_DATE));
+                game.setIcon(rs.getString(Game.ICON));
+                game.setIntroductionGlobal(rs.getString(Game.INTRODUCTION_GLOBAL));
+                game.setIntroductionLocal(rs.getString(Game.INTRODUCTION_LOCAL));
+                game.setIsPlayed(rs.getString(Game.IS_PLAYED));
+                game.setLevel(rs.getString(Game.LEVEL));
+                game.setLogo(rs.getString(Game.LOGO));
+                game.setNameGlobal(rs.getString(Game.NAME_GLOBAL));
+                game.setNameLocal(rs.getString(Game.NAME_LOCAL));
+                game.setParentId(rs.getString(Game.PARENT_ID));
+                game.setServiceId(rs.getString(Game.SERVICE_ID));
+                game.setStatus(rs.getString(Game.STATUS));
+                game.setToDate(rs.getString(Game.TO_DATE));
+                game.setTypeOf(rs.getString(Game.TYPE_OF));
+                game.setUpdateDate(rs.getString(Game.UPDATE_DATE));
+                listGames.add(game);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetDataByParentId");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetDataByParentId", startTime);
+        }
+        return listGames;
+    }
+
+    public int getTotalPage(String parentId, String seqPage, String rowOnPage, String serviceId) {
+        int totalpage = 0;
+        try {
+            totalpage = iGetTotalPage(parentId, seqPage, rowOnPage, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
+            logger.error(br, ex);
+        }
+
+        return totalpage;
+    }
+
+    private int iGetTotalPage(String parentId, String seqPage, String rowOnPage, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        int totalPage = 0;
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT COUNT(*) FROM fq_games where PARENT_ID = ? AND service_id = ?";
+//        SELECT last_name FROM
+//                (SELECT last_name, ROW_NUMBER() OVER (ORDER BY last_name) R FROM employees)
+//        WHERE R BETWEEN 51 and 100;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, parentId);
+            ps.setInt(2, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            int total = 0;
+            while (rs.next()) {
+                total = rs.getInt("COUNT(*)");
+            }
+
+            totalPage = total / Integer.parseInt(rowOnPage);
+            if (total % Integer.parseInt(rowOnPage) != 0) {
+                totalPage += 1;
+            }
+            logger.error("total page: " + totalPage);
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetTotalPage");
+            logger.error(br, ex);
+            return 0;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetTotalPage", startTime);
+        }
+        return totalPage;
+    }
+
+    public List<Game> getDataById(String id, String seqPage, String rowOnPage, String serviceId) {
+        List<Game> listGames = new ArrayList<Game>();
+        try {
+            listGames = iGetDataById(id, seqPage, rowOnPage, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRegisterInDay");
+            logger.error(br, ex);
+        }
+
+        return listGames;
+    }
+
+    private List<Game> iGetDataById(String id, String seqPage, String rowOnPage, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<Game> listGames = new ArrayList<Game>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM FQ_GAMES WHERE ID = ? AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            int seq = Integer.parseInt(seqPage);
+            int row = Integer.parseInt(rowOnPage);
+            int from = (seq - 1) * row;
+            int to = (seq) * row;
+
+            ps.setInt(1, Integer.parseInt(id));
+            ps.setInt(2, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                Game game = new Game();
+                game.setId(rs.getString(Game.ID));
+                game.setCode(rs.getString(Game.CODE));
+                game.setContent(rs.getString(Game.CONTENT));
+                game.setContentType(rs.getString(Game.CONTENT_TYPE));
+                game.setCreatedDate(rs.getString(Game.CREATED_DATE));
+                game.setDescriptionGlobal(rs.getString(Game.DESCRIPTION_GLOBAL));
+                game.setDescriptionLocal(rs.getString(Game.DESCRIPTION_LOCAL));
+                game.setFromDate(rs.getString(Game.FROM_DATE));
+                game.setIcon(rs.getString(Game.ICON));
+                game.setIntroductionGlobal(rs.getString(Game.INTRODUCTION_GLOBAL));
+                game.setIntroductionLocal(rs.getString(Game.INTRODUCTION_LOCAL));
+                game.setIsPlayed(rs.getString(Game.IS_PLAYED));
+                game.setLevel(rs.getString(Game.LEVEL));
+                game.setLogo(rs.getString(Game.LOGO));
+                game.setNameGlobal(rs.getString(Game.NAME_GLOBAL));
+                game.setNameLocal(rs.getString(Game.NAME_LOCAL));
+                game.setParentId(rs.getString(Game.PARENT_ID));
+                game.setServiceId(rs.getString(Game.SERVICE_ID));
+                game.setStatus(rs.getString(Game.STATUS));
+                game.setToDate(rs.getString(Game.TO_DATE));
+                game.setTypeOf(rs.getString(Game.TYPE_OF));
+                game.setUpdateDate(rs.getString(Game.UPDATE_DATE));
+                listGames.add(game);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetDataByParentId");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetDataByParentId", startTime);
+        }
+        return listGames;
+    }
+
+    public Boolean updateUserPlaying(long registerId, String msisdn, String serviceId) {
+
+        try {
+            Boolean playing = iUpdateUserPlaying(registerId);
+            Boolean spin = iUpdateTotalSpin(msisdn, serviceId);
+            if (playing && spin)
+                return true;
+            else
+                return false;
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateUserPlaying");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdateUserPlaying(long registerId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE reg_info SET PLAYED_TIMES=PLAYED_TIMES+1 WHERE register_id = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setLong(1, registerId);
+            ps.executeUpdate();
+
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR updateUserPlaying");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to updateUserPlaying", timeStart);
+        }
+    }
+
+    private Boolean iUpdateTotalSpin(String msisdn, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE account_user SET TOTAL_SPIN=TOTAL_SPIN+1 WHERE msisdn = ? and service_id = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateTotalSpin");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateTotalSpin", timeStart);
+        }
+    }
+
+    public Boolean reduceFreeSpin(String msisdn, String serviceId) {
+
+        try {
+            return iReduceFreeSpin(msisdn, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR reduceFreeSpin");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iReduceFreeSpin(String msisdn, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE account_user SET FREE_SPIN=FREE_SPIN-1, TOTAL_SPIN=TOTAL_SPIN+1 WHERE msisdn = ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iReduceFreeSpin");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iReduceFreeSpin", timeStart);
+        }
+    }
+
+    public Boolean updateUserPoint(String msisdn, String point, String serviceId) {
+
+        try {
+            return iUpdateUserPoint(msisdn, point, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateUserPoint");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdateUserPoint(String msisdn, String point, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE account_user SET point_=point_+? WHERE msisdn = ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(point));
+            ps.setString(2, msisdn);
+            ps.setInt(2, Integer.parseInt(serviceId));
+
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateUserPoint");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateUserPoint", timeStart);
+        }
+    }
+
+    public List<AccountInfo> getAccounts(String msisdn, String seqPage, String rowOnPage, String serviceId) {
+        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
+        try {
+            listAccounts = iGetAccounts(msisdn, seqPage, rowOnPage, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getRanking");
+            logger.error(br, ex);
+        }
+
+        return listAccounts;
+    }
+
+    private List<AccountInfo> iGetAccounts(String msisdn, String seqPage, String rowOnPage, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
+        long startTime = System.currentTimeMillis();
+//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
+        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY POINT_ DESC";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                AccountInfo user = new AccountInfo();
+                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+//                user.setUsers(rs.getString(AccountInfo.USERS));
+//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
+                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+//                user.setIsActive(rs.getInt(AccountInfo.IS_ACTIVE));
+//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
+                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+//                user.setRole(rs.getString(AccountInfo.ROLE));
+//                user.setLanguage(rs.getInt(AccountInfo.LANGUAGE));
+//                user.setIsLock(rs.getInt(AccountInfo.IS_LOCK));
+//                user.setTotalFalse(rs.getInt(AccountInfo.TOTAL_FALSE));
+//                user.setTimeLock(rs.getTimestamp(AccountInfo.TIME_LOCK));
+//                user.setStatus(rs.getInt(AccountInfo.STATUS));
+                user.setPoint(rs.getString(AccountInfo.POINT));
+//                user.setLastUpdate(rs.getTimestamp(AccountInfo.LAST_UPDATE));
+//                user.setLastLogin(rs.getTimestamp(AccountInfo.LAST_LOGIN));
+                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                user.setEmail(rs.getString(AccountInfo.EMAIL));
+                user.setPicture(rs.getString(AccountInfo.PICTURE));
+                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+                listAccounts.add(user);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetAccounts");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetAccounts", startTime);
+        }
+        return listAccounts;
+    }
+
+    public List<AccountInfo> getAccountsByPlayedTime(String msisdn, String seqPage, String rowOnPage, String serviceId) {
+        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
+        try {
+            listAccounts = iGetAccountsByPlayedTime(msisdn, seqPage, rowOnPage, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getAccountsByPlayedTime");
+            logger.error(br, ex);
+        }
+
+        return listAccounts;
+    }
+
+    private List<AccountInfo> iGetAccountsByPlayedTime(String msisdn, String seqPage, String rowOnPage, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
+        long startTime = System.currentTimeMillis();
+//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
+//        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY total_spin DESC";
+
+        String sql = "SELECT * FROM (SELECT ID, msisdn, service_id, created_date, update_date, free_spin," +
+                "total_spin, point_, birthday, email, picture, fullname," +
+                "ROW_NUMBER() OVER (ORDER BY total_spin) R FROM account_user where total_spin > ? and service_id = ?) where R BETWEEN ? and ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            int seq = Integer.parseInt(seqPage);
+            int row = Integer.parseInt(rowOnPage);
+            int from = (seq - 1) * row + 1;
+            int to = (seq) * row;
+
+            ps.setInt(1, Common.Constant.SPIN_FREE);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.setInt(3, from);
+            ps.setInt(4, to);
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                AccountInfo user = new AccountInfo();
+                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+//                user.setUsers(rs.getString(AccountInfo.USERS));
+//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
+                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+//                user.setIsActive(rs.getInt(AccountInfo.IS_ACTIVE));
+//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
+                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+//                user.setRole(rs.getString(AccountInfo.ROLE));
+//                user.setLanguage(rs.getInt(AccountInfo.LANGUAGE));
+//                user.setIsLock(rs.getInt(AccountInfo.IS_LOCK));
+//                user.setTotalFalse(rs.getInt(AccountInfo.TOTAL_FALSE));
+//                user.setTimeLock(rs.getTimestamp(AccountInfo.TIME_LOCK));
+//                user.setStatus(rs.getInt(AccountInfo.STATUS));
+                user.setPoint(rs.getString(AccountInfo.POINT));
+//                user.setLastUpdate(rs.getTimestamp(AccountInfo.LAST_UPDATE));
+//                user.setLastLogin(rs.getTimestamp(AccountInfo.LAST_LOGIN));
+                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                user.setEmail(rs.getString(AccountInfo.EMAIL));
+                user.setPicture(rs.getString(AccountInfo.PICTURE));
+                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+                listAccounts.add(user);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetAccountsByPlayedTime");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetAccountsByPlayedTime", startTime);
+        }
+        return listAccounts;
+    }
+
+    public List<AccountInfo> getAccountsByHighestPlayedTime(int max, String serviceId) {
+        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
+        try {
+            listAccounts = iGetAccountsByHighestPlayedTime(max, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getAccountsByHighestPlayedTime");
+            logger.error(br, ex);
+        }
+
+        return listAccounts;
+    }
+
+    private List<AccountInfo> iGetAccountsByHighestPlayedTime(int max, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<AccountInfo> listAccounts = new ArrayList<AccountInfo>();
+        long startTime = System.currentTimeMillis();
+//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
+//        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY total_spin DESC";
+
+        String sql = "SELECT * FROM (SELECT ID, msisdn, service_id, created_date, update_date, free_spin," +
+                "total_spin, point_, birthday, email, picture, fullname," +
+                "ROW_NUMBER() OVER (ORDER BY total_spin) R FROM account_user where total_spin > ? and service_id = ?) where R BETWEEN 0 and ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setInt(1, Common.Constant.SPIN_FREE);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.setInt(3, max);
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                AccountInfo user = new AccountInfo();
+                user.setAccountId(rs.getString(AccountInfo.ACCOUNT_ID));
+                user.setMsisdn(rs.getString(AccountInfo.MSISDN));
+//                user.setUsers(rs.getString(AccountInfo.USERS));
+//                user.setPassword(rs.getString(AccountInfo.PASSWORD));
+                user.setServiceId(rs.getString(AccountInfo.SERVICE_ID));
+                user.setCreateDate(rs.getString(AccountInfo.CREATE_DATE));
+                user.setUpdateDate(rs.getString(AccountInfo.UPDATE_DATE));
+//                user.setIsActive(rs.getInt(AccountInfo.IS_ACTIVE));
+//                user.setChannel(rs.getString(AccountInfo.CHANNEL));
+                user.setFreeSpin(rs.getString(AccountInfo.FREE_SPIN));
+                user.setTotalSpin(rs.getString(AccountInfo.TOTAL_SPIN));
+//                user.setRole(rs.getString(AccountInfo.ROLE));
+//                user.setLanguage(rs.getInt(AccountInfo.LANGUAGE));
+//                user.setIsLock(rs.getInt(AccountInfo.IS_LOCK));
+//                user.setTotalFalse(rs.getInt(AccountInfo.TOTAL_FALSE));
+//                user.setTimeLock(rs.getTimestamp(AccountInfo.TIME_LOCK));
+//                user.setStatus(rs.getInt(AccountInfo.STATUS));
+                user.setPoint(rs.getString(AccountInfo.POINT));
+//                user.setLastUpdate(rs.getTimestamp(AccountInfo.LAST_UPDATE));
+//                user.setLastLogin(rs.getTimestamp(AccountInfo.LAST_LOGIN));
+                user.setBirthday(rs.getString(AccountInfo.BIRTHDAY));
+                user.setEmail(rs.getString(AccountInfo.EMAIL));
+                user.setPicture(rs.getString(AccountInfo.PICTURE));
+                user.setFullName(rs.getString(AccountInfo.FULLNAME));
+                listAccounts.add(user);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetAccountsByHighestPlayedTime");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetAccountsByHighestPlayedTime", startTime);
+        }
+        return listAccounts;
+    }
+
+    public boolean insertHighestPlayingTimes(String msisdn, String totalSpin, String serviceId) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = iInsertHighestPlayingTimes(msisdn, totalSpin, serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertHighestPlayingTimes - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertHighestPlayingTimes\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean iInsertHighestPlayingTimes(String msisdn, String totalSpin, String serviceId) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+//        PreparedStatement ps2 = null;
+        Connection connection = null;
+        String sql = "INSERT INTO playing_times_reward (ID,MSISDN,TOTAL_SPIN,CREATED_DATE,UPDATE_DATE,SERVICE_ID) \n"
+                + "VALUES(playing_times_reward_seq.nextval, ?, ?, sysdate, sysdate, ?)";
+//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, Integer.parseInt(totalSpin));
+            ps.setInt(3, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+
+//            ps2 = connection.prepareStatement(sqlWeek);
+//            if (WebserviceManager.enableQueryDbTimeout) {
+//                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            ps2.setString(1, ranking.getMsisdn());
+//            ps2.setTimestamp(2, ranking.getStartTime());
+//            ps2.setInt(3, ranking.getSpintCount());
+//            ps2.setInt(4, ranking.getSubType());
+//            ps2.setInt(5, ranking.getRankType());
+//            ps2.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to iInsertHighestPlayingTimes", timeStart);
+        }
+        return rs;
+    }
+
+    public List<PlayingTimeRewrad> getHighestPlayedTime(String serviceId) {
+        List<PlayingTimeRewrad> playingTimeRewrads = new ArrayList<PlayingTimeRewrad>();
+        try {
+            playingTimeRewrads = iGetHighestPlayedTime(serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getHighestPlayedTime");
+            logger.error(br, ex);
+        }
+
+        return playingTimeRewrads;
+    }
+
+    private List<PlayingTimeRewrad> iGetHighestPlayedTime(String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<PlayingTimeRewrad> playingTimeRewrads = new ArrayList<PlayingTimeRewrad>();
+        long startTime = System.currentTimeMillis();
+//        String sql = "SELECT msisdn, created_date, update_date, point_, picture, fullname, email, birthday FROM ACCOUNT_USER  WHERE service_id = ?";
+//        String sql = "SELECT * FROM ACCOUNT_USER WHERE service_id = ? ORDER BY total_spin DESC";
+
+        String sql = "SELECT * FROM playing_times_reward where service_id = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setInt(1, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                PlayingTimeRewrad playingTimeRewrad = new PlayingTimeRewrad();
+                playingTimeRewrad.setId(rs.getInt(PlayingTimeRewrad.ID));
+                playingTimeRewrad.setMsisdn(rs.getString(PlayingTimeRewrad.MSISDN));
+                playingTimeRewrad.setServiceId(rs.getInt(PlayingTimeRewrad.SERVICE_ID));
+                playingTimeRewrad.setCreatedDate(rs.getTimestamp(PlayingTimeRewrad.CREATED_DATE));
+                playingTimeRewrad.setUpdateDate(rs.getTimestamp(PlayingTimeRewrad.UPDATE_DATE));
+                playingTimeRewrad.setStatus(rs.getInt(PlayingTimeRewrad.STATUS));
+                playingTimeRewrad.setTotalSpin(rs.getInt(PlayingTimeRewrad.TOTAL_SPIN));
+                playingTimeRewrad.setChannel(rs.getString(PlayingTimeRewrad.CHANNEL));
+                playingTimeRewrads.add(playingTimeRewrad);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetHighestPlayedTime");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetHighestPlayedTime", startTime);
+        }
+        return playingTimeRewrads;
+    }
+
+    public boolean deleteHighestPlayedTime(String serviceId) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = ideleteHighestPlayedTime(serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR deleteHighestPlayedTime - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK deleteHighestPlayedTime\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean ideleteHighestPlayedTime(String serviceId) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "DELETE from playing_times_reward WHERE service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to ideleteHighestPlayedTime", timeStart);
+        }
+        return rs;
+    }
+
+    public List<PlayingTimeHistory> getPlayedTimeHistory(String serviceId) {
+        List<PlayingTimeHistory> playingTimeHistories = new ArrayList<PlayingTimeHistory>();
+        try {
+            playingTimeHistories = iGetPlayedTimeHistory(serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getPlayedTimeHistory");
+            logger.error(br, ex);
+        }
+        return playingTimeHistories;
+    }
+
+    private List<PlayingTimeHistory> iGetPlayedTimeHistory(String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<PlayingTimeHistory> playingTimeHistories = new ArrayList<PlayingTimeHistory>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM playing_times_history where service_id = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                PlayingTimeHistory playingTimeHistory = new PlayingTimeHistory();
+                playingTimeHistory.setId(rs.getInt(PlayingTimeHistory.ID));
+                playingTimeHistory.setChannel(rs.getString(PlayingTimeHistory.CHANNEL));
+                playingTimeHistory.setServiceId(rs.getInt(PlayingTimeHistory.SERVICE_ID));
+                playingTimeHistory.setCreatedDate(rs.getTimestamp(PlayingTimeHistory.CREATED_DATE));
+                playingTimeHistory.setUpdateDate(rs.getTimestamp(PlayingTimeHistory.UPDATE_DATE));
+                playingTimeHistory.setStatus(rs.getInt(PlayingTimeHistory.STATUS));
+                playingTimeHistories.add(playingTimeHistory);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetPlayedTimeHistory");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetPlayedTimeHistory", startTime);
+        }
+        return playingTimeHistories;
+    }
+
+    public boolean insertPlayingTimesHistory(String serviceId) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = iInsertPlayingTimesHistory(serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertPlayingTimesHistory - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertPlayingTimesHistory\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean iInsertPlayingTimesHistory(String serviceId) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+//        PreparedStatement ps2 = null;
+        Connection connection = null;
+        String sql = "INSERT INTO playing_times_history (ID,CREATED_DATE,UPDATE_DATE,SERVICE_ID) \n"
+                + "VALUES(playing_times_history_seq.nextval, sysdate, sysdate, ?)";
+//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+
+//            ps2 = connection.prepareStatement(sqlWeek);
+//            if (WebserviceManager.enableQueryDbTimeout) {
+//                ps2.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            ps2.setString(1, ranking.getMsisdn());
+//            ps2.setTimestamp(2, ranking.getStartTime());
+//            ps2.setInt(3, ranking.getSpintCount());
+//            ps2.setInt(4, ranking.getSubType());
+//            ps2.setInt(5, ranking.getRankType());
+//            ps2.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to iInsertPlayingTimesHistory", timeStart);
+        }
+        return rs;
+    }
+
+    public Boolean updatePlayingTimesHistory(int id) {
+
+        try {
+            return iUpdatePlayingTimesHistory(id);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updatePlayingTimesHistory");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdatePlayingTimesHistory(int id) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE playing_times_history SET update_date = sysdate WHERE id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, id);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdatePlayingTimesHistory");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdatePlayingTimesHistory", timeStart);
+        }
+    }
+
+    public Boolean updateUserProfile(String msisdn, String fullName, String picture, String birthday, String serviceId) {
+
+        try {
+            return iUpdateUserProfile(msisdn, fullName, picture, birthday, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateUserProfile");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdateUserProfile(String msisdn, String fullName, String picture, String birthday, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE account_user SET fullname = ?, picture = ?, birthday = TO_DATE(?, 'MM/DD/YYYY') WHERE MSISDN = ? AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, fullName);
+            ps.setString(2, picture);
+            ps.setString(3, birthday);
+            ps.setString(4, msisdn);
+            ps.setString(5, serviceId);
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateUserProfile");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateUserProfile", timeStart);
+        }
+    }
+
+    public List<Game> getMiniGames(String parentId, String isPlayed, String fromDate, String toDate, String serviceId) {
+        List<Game> listGames = new ArrayList<Game>();
+        try {
+            listGames = iGetMiniGames(parentId, isPlayed, fromDate, toDate, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getMiniGames");
+            logger.error(br, ex);
+        }
+        return listGames;
+    }
+
+    private List<Game> iGetMiniGames(String parentId, String isPlayed, String fromDate, String toDate, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<Game> listGames = new ArrayList<Game>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM FQ_GAMES WHERE parent_id = ? AND is_played = ? AND to_date_ >= to_date(? || ' 00:00:00', 'MM/DD/YYYY HH24:MI:SS')\n" +
+                " AND to_date_ <= to_date(? || ' 23:59:59', 'MM/DD/YYYY HH24:MI:SS') AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(parentId));
+            ps.setInt(2, Integer.parseInt(isPlayed));
+            ps.setString(3, fromDate);
+            ps.setString(4, toDate);
+            ps.setInt(5, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                Game game = new Game();
+                game.setId(rs.getString(Game.ID));
+                game.setCode(rs.getString(Game.CODE));
+                game.setContent(rs.getString(Game.CONTENT));
+                game.setContentType(rs.getString(Game.CONTENT_TYPE));
+                game.setCreatedDate(rs.getTimestamp(Game.CREATED_DATE).toString());
+                game.setDescriptionGlobal(rs.getString(Game.DESCRIPTION_GLOBAL));
+                game.setDescriptionLocal(rs.getString(Game.DESCRIPTION_LOCAL));
+                game.setFromDate(rs.getTimestamp(Game.FROM_DATE).toString());
+                game.setIcon(rs.getString(Game.ICON));
+                game.setIntroductionGlobal(rs.getString(Game.INTRODUCTION_GLOBAL));
+                game.setIntroductionLocal(rs.getString(Game.INTRODUCTION_LOCAL));
+                game.setIsPlayed(rs.getString(Game.IS_PLAYED));
+                game.setLevel(rs.getString(Game.LEVEL));
+                game.setLogo(rs.getString(Game.LOGO));
+                game.setNameGlobal(rs.getString(Game.NAME_GLOBAL));
+                game.setNameLocal(rs.getString(Game.NAME_LOCAL));
+                game.setParentId(rs.getString(Game.PARENT_ID));
+                game.setServiceId(rs.getString(Game.SERVICE_ID));
+                game.setStatus(rs.getString(Game.STATUS));
+                game.setToDate(rs.getTimestamp(Game.TO_DATE).toString());
+                game.setTypeOf(rs.getString(Game.TYPE_OF));
+                game.setUpdateDate(rs.getTimestamp(Game.UPDATE_DATE).toString());
+                listGames.add(game);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetMiniGames");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetMiniGames", startTime);
+        }
+        return listGames;
+    }
+
+    public List<MinigameReward> getMiniGameRewards(String minigameId, String serviceId) {
+        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
+        try {
+            listRewards = iGetMiniGameRewards(minigameId, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getMiniGameRewards");
+            logger.error(br, ex);
+        }
+        return listRewards;
+    }
+
+    private List<MinigameReward> iGetMiniGameRewards(String minigameId, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM minigame_reward WHERE minigame_id = ? AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(minigameId));
+            ps.setInt(2, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                MinigameReward reward = new MinigameReward();
+                reward.setId(rs.getInt(MinigameReward.ID));
+                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
+                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
+                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
+                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
+                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
+                reward.setStatus(rs.getInt(MinigameReward.STATUS));
+                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
+                listRewards.add(reward);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetMiniGameRewards");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetMiniGameRewards", startTime);
+        }
+        return listRewards;
+    }
+
+    public List<MinigameReward> getUserRewardByTime(String fromDate, String toDate, String serviceId) {
+        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
+        try {
+            listRewards = iGetUserRewardByTime(fromDate, toDate, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getMiniGameRewards");
+            logger.error(br, ex);
+        }
+        return listRewards;
+    }
+
+    private List<MinigameReward> iGetUserRewardByTime(String fromDate, String toDate, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<MinigameReward> listRewards = new ArrayList<MinigameReward>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM minigame_reward WHERE update_date >= to_date(? || ' 00:00:00', 'MM/DD/YYYY HH24:MI:SS')" +
+                " AND update_date <= to_date(? || ' 23:59:59', 'MM/DD/YYYY HH24:MI:SS') AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, fromDate);
+            ps.setString(2, toDate);
+            ps.setInt(3, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                MinigameReward reward = new MinigameReward();
+                reward.setId(rs.getInt(MinigameReward.ID));
+                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
+                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
+                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
+                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
+                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
+                reward.setStatus(rs.getInt(MinigameReward.STATUS));
+                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
+                listRewards.add(reward);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetMiniGameRewards");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetMiniGameRewards", startTime);
+        }
+        return listRewards;
+    }
+
+    public MinigameReward getUserReward(String minigameId, String msisdn, String serviceId) {
+        MinigameReward reward = null;
+        try {
+            reward = iGetUserReward(minigameId, msisdn, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getUserReward");
+            logger.error(br, ex);
+        }
+        return reward;
+    }
+
+    private MinigameReward iGetUserReward(String minigameId, String msisdn, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        MinigameReward reward = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM minigame_reward WHERE minigame_id = ? AND msisdn = ? AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(minigameId));
+            ps.setString(2, msisdn);
+            ps.setInt(3, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            reward = new MinigameReward();
+            while (rs.next()) {
+                reward.setId(rs.getInt(MinigameReward.ID));
+                reward.setMinigameId(rs.getInt(MinigameReward.MINIGAME_ID));
+                reward.setMsisdn(rs.getString(MinigameReward.MSISDN));
+                reward.setCreatedDate(rs.getTimestamp(MinigameReward.CREATED_DATE));
+                reward.setUpdateDate(rs.getTimestamp(MinigameReward.UPDATE_DATE));
+                reward.setChannel(rs.getString(MinigameReward.CHANNEL));
+                reward.setStatus(rs.getInt(MinigameReward.STATUS));
+                reward.setServiceId(rs.getInt(MinigameReward.SERVICE_ID));
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetUserReward");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetMiniGameRewards", startTime);
+        }
+        return reward;
+    }
+
+    public boolean insertMiniGameReward(String minigameId, String msisdn, String serviceId) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = iInsertMiniGameReward(minigameId, msisdn, serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertInviteHistory - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertMiniGameReward\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean iInsertMiniGameReward(String minigameId, String msisdn, String serviceId) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "INSERT INTO minigame_reward (id, msisdn, minigame_id, service_id) \n"
+                + "VALUES(minigame_reward_seq.nextval, ?, ?, ?)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            ps.setInt(2, Integer.parseInt(minigameId));
+            ps.setInt(3, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iInsertMiniGameReward", timeStart);
+        }
+        return rs;
+    }
+
+    public int insertTransLog1(TransactionLog log) throws SQLException {
+        PreparedStatement ps = null;
+        long startTime = System.currentTimeMillis();
+        Connection connection = null;
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(SQL_TRANS_LOG);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            int i = 1;
+            ps.setString(i++, log.getTransactionId());
+            ps.setInt(i++, log.getType());
+            ps.setString(i++, log.getMsisdn());
+            ps.setString(i++, log.getRequest());
+            ps.setString(i++, log.getResponse());
+            ps.setString(i++, log.getErrorCode());
+            ps.setString(i++, log.getCommand());
+            ps.setTimestamp(i++, log.getRequestTime());
+            ps.setTimestamp(i++, log.getResponseTime());
+            ps.setString(i++, log.getChannel());
+
+            return ps.executeUpdate();
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeStatement(ps);
+            closeConnection(connection);
+            logTime("Time to insert TRANSACTION_LOG", startTime);
+        }
+    }
+
+    public String getConfiguration(String key, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        String value = null;
+        long startTime = System.currentTimeMillis();
+
+        String sql = "SELECT * FROM configuration where para_key = ? and service_id = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, key);
+            ps.setInt(2, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                value = rs.getString("PARA_VALUE");
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getConfiguration");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to getConfiguration", startTime);
+        }
+        return value;
+    }
+
+    public String getConfigurationByKey(String key) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        String value = null;
+        long startTime = System.currentTimeMillis();
+
+        String sql = "SELECT * FROM config where PARAM_NAME = ? and module = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            ps.setString(1, key);
+            ps.setString(2, "REPORT");
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                value = rs.getString("PARAM_VALUE");
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR getConfigurationByKey");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to getConfigurationByKey", startTime);
+        }
+        return value;
+    }
+
+    public ProductInfo iLoadPackageByName(String subServiceName) {
+        ProductInfo product = null;
+        long timeBegin = System.currentTimeMillis();
+        while (product == null) {
+            try {
+                product = loadPackageByName(subServiceName);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - iLoadPackage");
+                logger.error(br, ex);
+            }
+        }
+        return product;
+    }
+
+    private ProductInfo loadPackageByName(String subServiceName) throws SQLException {
+        long timeStart = System.currentTimeMillis();
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        ProductInfo product = new ProductInfo();
+        String sql = "SELECT * FROM PACKG where product_name = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, subServiceName);
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                product.setProductId(rs.getInt("PRODUCT_ID"));
+                product.setFee(rs.getDouble("FEE"));
+                product.setNumberSpin(rs.getInt("NUMBER_SPIN"));
+                product.setProductName(rs.getString("PRODUCT_NAME"));
+                product.setSmsSyntax(rs.getString("SMS_SYNTAX"));
+                product.setBizId(rs.getInt("BIZ_ID"));
+                product.setExpireDays(rs.getInt("EXPIRE_DAYS"));
+                product.setRenew(rs.getInt("RENEW"));
+            }
+            logger.error("result: " + product);
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to loadPackageByName", timeStart);
+        }
+        return product;
+    }
+
+    public HashMap loadMpsConfig() {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        HashMap<String, MpsConfigObj> mMps = new HashMap();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM MPS_CONFIG";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                MpsConfigObj mpsConfig = new MpsConfigObj();
+                mpsConfig.setActionCode(rs.getString(MpsConfigObj.ACTION_CODE));
+                mpsConfig.setCategory(rs.getString(MpsConfigObj.CATEGORY));
+                mpsConfig.setCommand(rs.getString(MpsConfigObj.COMMAND));
+                mpsConfig.setCpName(rs.getString(MpsConfigObj.CP_NAME));
+                mpsConfig.setPrice(rs.getString(MpsConfigObj.PRICE));
+                mpsConfig.setService(rs.getString(MpsConfigObj.SERVICE));
+                mpsConfig.setSubService(rs.getString(MpsConfigObj.SUB_SERVICE));
+                mpsConfig.setKeyPath(rs.getString(MpsConfigObj.KEY_PATH));
+                mMps.put(mpsConfig.getActionCode(), mpsConfig);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR loadMpsConfig");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to load mps config", startTime);
+        }
+        return mMps;
+    }
+
+
+    // FOR ADMIN
+    public Boolean checkAdminLogin(String user_admin, String pass_admin, String serviceId) {
+        Boolean registered = null;
+        try {
+            registered = icheckAdminLogin(user_admin, pass_admin, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR checkAdminLogin");
+            logger.error(br, ex);
+        }
+
+        return registered;
+    }
+
+    private Boolean icheckAdminLogin(String user_admin, String pass_admin, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM ACCOUNT_ADMIN WHERE user_admin = ? AND pass_admin = ? AND service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, user_admin);
+            ps.setString(2, pass_admin);
+            ps.setInt(3, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                return true;
+            }
+            return false;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR icheckAdminLogin");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to icheckAdminLogin", startTime);
+        }
+    }
+
+    public boolean insertNewGame(Game game) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = iInsertNewGame(game);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertNewGame - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertNewGame\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean iInsertNewGame(Game game) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "INSERT INTO fq_games (ID,PARENT_ID,SERVICE_ID,CODE,NAME_GLOBAL,NAME_LOCAL,DESCRIPTION_GLOBAL,DESCRIPTION_LOCAL,\n"
+                + "INTRODUCTION_GLOBAL,INTRODUCTION_LOCAL,ICON,LOGO,CONTENT_,CONTENT_TYPE,UPDATE_DATE,LEVEL_,FROM_DATE,TO_DATE_,STATUS,IS_PLAYED,TYPE_OF,NOTE)\n"
+                + " VALUES(games_seq.nextval, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, sysdate, ?, to_date(?, 'YYYY-MM-DD HH24:MI:SS'), to_date(?, 'YYYY-MM-DD HH24:MI:SS'), ?, ?, ?, ?)";
+//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setLong(1, Long.parseLong(game.getParentId()));
+            ps.setInt(2, Integer.parseInt(game.getServiceId()));
+            ps.setString(3, game.getCode());
+            ps.setString(4, game.getNameGlobal());
+            ps.setString(5, game.getNameLocal());
+            ps.setString(6, game.getDescriptionGlobal());
+            ps.setString(7, game.getDescriptionLocal());
+            ps.setString(8, game.getIntroductionGlobal());
+            ps.setString(9, game.getIntroductionLocal());
+            ps.setString(10, game.getIcon());
+            ps.setString(11, game.getLogo());
+            ps.setString(12, game.getContent());
+            ps.setString(13, game.getContentType());
+            ps.setInt(14, game.getLevel() != null ? Integer.parseInt(game.getLevel()) : 5);
+            ps.setString(15, game.getFromDate());
+            ps.setString(16, game.getToDate());
+            ps.setInt(17, Integer.parseInt(game.getStatus()));
+            ps.setInt(18, Integer.parseInt(game.getIsPlayed()));
+            ps.setInt(19, Integer.parseInt(game.getTypeOf()));
+            ps.setString(20, game.getNote());
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to iInsertNewGame", timeStart);
+        }
+        return rs;
+    }
+
+    public boolean updateGame(Game game) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = iUpdateGame(game);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR insertNewGame - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK insertNewGame\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean iUpdateGame(Game game) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+//        2020-10-13 19:05:00
+        String sql = "UPDATE fq_games SET CODE=?,NAME_GLOBAL=?,NAME_LOCAL=?,DESCRIPTION_GLOBAL=?,DESCRIPTION_LOCAL=?,INTRODUCTION_GLOBAL=?,INTRODUCTION_LOCAL=?,\n"
+                + "ICON=?,LOGO=?,CONTENT_=?,CONTENT_TYPE=?,UPDATE_DATE=sysdate,FROM_DATE=to_date(?, 'YYYY-MM-DD HH24:MI:SS'),TO_DATE_=to_date(?, 'YYYY-MM-DD HH24:MI:SS'),STATUS=?,IS_PLAYED=?,TYPE_OF=?,NOTE=?\n"
+                + " WHERE ID = ?";
+//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, game.getCode());
+            ps.setString(2, game.getNameGlobal());
+            ps.setString(3, game.getNameLocal());
+            ps.setString(4, game.getDescriptionGlobal());
+            ps.setString(5, game.getDescriptionLocal());
+            ps.setString(6, game.getIntroductionGlobal());
+            ps.setString(7, game.getIntroductionLocal());
+            ps.setString(8, game.getIcon());
+            ps.setString(9, game.getLogo());
+            ps.setString(10, game.getContent());
+            ps.setString(11, game.getContentType());
+            ps.setString(12, game.getFromDate());
+            ps.setString(13, game.getToDate());
+            ps.setInt(14, game.getStatus() != null ? Integer.parseInt(game.getStatus()) : 0);
+            ps.setInt(15, game.getIsPlayed() != null ? Integer.parseInt(game.getIsPlayed()) : 0);
+            ps.setInt(16, game.getIsPlayed() != null ? Integer.parseInt(game.getTypeOf()) : 0);
+            ps.setString(17, game.getNote());
+            ps.setInt(18, Integer.parseInt(game.getId()));
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to iUpdateGame", timeStart);
+        }
+        return rs;
+    }
+
+    public boolean deleteGame(String id, String serviceId) {
+        boolean result = false;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (result == false) {
+            try {
+                result = ideleteGame(id, serviceId);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR deleteGame - ").append(count);
+                logger.error(br, ex);
+                count++;
+            }
+            if (result == false && System.currentTimeMillis() - timeBegin > TIME_BREAK) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).
+                        append("==> BREAK deleteGame\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean ideleteGame(String id, String serviceId) throws Exception {
+        long timeStart = System.currentTimeMillis();
+        boolean rs = false;
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "DELETE from fq_games WHERE ID = ? and service_id = ?";
+//        String sqlWeek = "INSERT INTO ranking (ID,MSISDN,START_TIME,END_TIME,SPIN_COUNT,INSERT_TIME,LAST_UPDATE,SUB_TYPE,RANK_TYPE,PERIOD) \n"
+//                + "VALUES(ranking_seq.nextval, ?, ?, trunc(sysdate,'iw') + 7 - 1/86400, ?, sysdate, sysdate,?, ?, 1)";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(id));
+            ps.setInt(2, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+            rs = true;
+        } catch (Exception ex) {
+            throw ex;
+        } finally {
+            closeResource(ps);
+//            closeResource(ps2);
+            closeResource(connection);
+            logTime("Time to deleteGame", timeStart);
+        }
+        return rs;
+    }
+
+    public Boolean updateConfiguration(String key, String value, String serviceId) {
+
+        try {
+            return iUpdateConfiguration(key, value, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR updateStatusReward");
+            logger.error(br, ex);
+        }
+
+        return null;
+    }
+
+    private Boolean iUpdateConfiguration(String key, String value, String serviceId) {
+        long timeStart = System.currentTimeMillis();
+        PreparedStatement ps = null;
+        Connection connection = null;
+        String sql = "UPDATE configuration SET para_value = ? WHERE para_key = ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(value));
+            ps.setString(2, key);
+            ps.setInt(3, Integer.parseInt(serviceId));
+            ps.executeUpdate();
+            return true;
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iUpdateStatusReward");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iUpdateStatusReward", timeStart);
+        }
+    }
+
+    public List<Configuration> getConfiguration(String serviceId) {
+        List<Configuration> configurations = new ArrayList<Configuration>();
+        try {
+            configurations = iGetConfiguration(serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getConfiguration");
+            logger.error(br, ex);
+        }
+        return configurations;
+    }
+
+    private List<Configuration> iGetConfiguration(String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<Configuration> configurations = new ArrayList<Configuration>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM configuration where service_id = ?";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(serviceId));
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                Configuration configuration = new Configuration();
+                configuration.setId(rs.getString("ID"));
+                configuration.setPara_key(rs.getString("PARA_KEY"));
+                configuration.setPara_value(rs.getString("PARA_VALUE"));
+                configuration.setService_id(rs.getString("SERVICE_ID"));
+                configurations.add(configuration);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetConfiguration");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetConfiguration", startTime);
+        }
+        return configurations;
+    }
+
+    public List<ChargeLog> getChargeLogAddMoneyHistory(Timestamp fromDate, Timestamp toDate) {
+        List<ChargeLog> chargeLogs = new ArrayList<ChargeLog>();
+        try {
+            chargeLogs = iGetChargeLogAddMoneyHistory(fromDate, toDate);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getChargeLogAddMoneyHistory");
+            logger.error(br, ex);
+        }
+        return chargeLogs;
+    }
+
+    private List<ChargeLog> iGetChargeLogAddMoneyHistory(Timestamp fromDate, Timestamp toDate) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<ChargeLog> chargeLogs = new ArrayList<ChargeLog>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM charge_log where charge_time >= ? and charge_time <= ? and fee < 0 and fee > -50";
+
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, fromDate);
+            ps.setTimestamp(2, toDate);
+            rs = ps.executeQuery();
+
+            while (rs.next()) {
+                ChargeLog chargeLog = new ChargeLog();
+                chargeLog.setFee(rs.getDouble("FEE"));
+                chargeLogs.add(chargeLog);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetPlayedTimeHistory");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetChargeLogAddMoneyHistory", startTime);
+        }
+        return chargeLogs;
+    }
+
+    // FOR REPORTING
+    public List<RegisterInfo> getNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGtNewRegisterByDay(fromDate, toDate, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getNewRegisterByDay");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<RegisterInfo> iGtNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE status = 1 AND renew = 1 and REGISTER_TIME >= ? " +
+                "and REGISTER_TIME < ? and service_id = ? ";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, fromDate);
+            ps.setTimestamp(2, toDate);
+            ps.setInt(3, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo info = new RegisterInfo();
+                info.setProductName(rs.getString("PRODUCT_NAME"));
+                info.setStatus(rs.getInt("STATUS"));
+                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
+                info.setEndTime(rs.getTimestamp("END_TIME"));
+                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGtNewRegisterByDay");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGtNewRegisterByDay", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getReNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGetReNewRegisterByDay(fromDate, toDate, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getReNewRegisterByDay");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<RegisterInfo> iGetReNewRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE status = 1 and LAST_EXTEND >= ? " +
+                "and LAST_EXTEND < ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, fromDate);
+            ps.setTimestamp(2, toDate);
+            ps.setInt(3, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo info = new RegisterInfo();
+                info.setProductName(rs.getString("PRODUCT_NAME"));
+                info.setStatus(rs.getInt("STATUS"));
+                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
+                info.setEndTime(rs.getTimestamp("END_TIME"));
+                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetReNewRegisterByDay");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetReNewRegisterByDay", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getBuyMoreByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGetBuyMoreByDay(fromDate, toDate, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getBuyMoreByDay");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<RegisterInfo> iGetBuyMoreByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE renew = 0 AND status = 1 and REGISTER_TIME >= ? " +
+                "and REGISTER_TIME < ?  and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, fromDate);
+            ps.setTimestamp(2, toDate);
+            ps.setInt(3, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo info = new RegisterInfo();
+                info.setProductName(rs.getString("PRODUCT_NAME"));
+                info.setStatus(rs.getInt("STATUS"));
+                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
+                info.setEndTime(rs.getTimestamp("END_TIME"));
+                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetBuyMoreByDay");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetBuyMoreByDay", startTime);
+        }
+        return listReg;
+    }
+
+    public List<RegisterInfo> getCancelRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        try {
+            listReg = iGetCancelRegisterByDay(fromDate, toDate, serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getCancelRegisterByDay");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<RegisterInfo> iGetCancelRegisterByDay(Timestamp fromDate, Timestamp toDate, String serviceId) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<RegisterInfo> listReg = new ArrayList<RegisterInfo>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM REG_INFO WHERE status = 0 and END_TIME >= ? " +
+                "and END_TIME < ? and service_id = ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, fromDate);
+            ps.setTimestamp(2, toDate);
+            ps.setInt(3, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                RegisterInfo info = new RegisterInfo();
+                info.setProductName(rs.getString("PRODUCT_NAME"));
+                info.setStatus(rs.getInt("STATUS"));
+                info.setLastExtend(rs.getTimestamp("LAST_EXTEND"));
+                info.setEndTime(rs.getTimestamp("END_TIME"));
+                info.setRegisterTime(rs.getTimestamp("REGISTER_TIME"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetCancelRegisterByDay");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetCancelRegisterByDay", startTime);
+        }
+        return listReg;
+    }
+
+    public List<ChargeLog> getChargeLogByDay(Timestamp fromDate, Timestamp toDate) {
+        List<ChargeLog> listReg = new ArrayList<ChargeLog>();
+        try {
+            listReg = iGetChargeLogByDay(fromDate, toDate);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getDailyRewardByDay");
+            logger.error(br, ex);
+        }
+
+        return listReg;
+    }
+
+    private List<ChargeLog> iGetChargeLogByDay(Timestamp fromDate, Timestamp toDate) {
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        List<ChargeLog> listReg = new ArrayList<ChargeLog>();
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT * FROM CHARGE_LOG WHERE CHARGE_TIME >= ? " +
+                "and CHARGE_TIME < ?";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setTimestamp(1, fromDate);
+            ps.setTimestamp(2, toDate);
+
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                ChargeLog info = new ChargeLog();
+                info.setFee(rs.getDouble("FEE"));
+                info.setChargeTime(rs.getTimestamp("CHARGE_TIME"));
+                listReg.add(info);
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetDailyRewardByDay");
+            logger.error(br, ex);
+            return null;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetDailyRewardByDay", startTime);
+        }
+        return listReg;
+    }
+    public int getTotalSub(String serviceId) {
+        int listReg = 0;
+        try {
+            listReg = iGetTotalSub(serviceId);
+        } catch (Exception ex) {
+            br.append(loggerLabel).append(new Date()).append("\nERROR getTotalSub");
+            logger.error(br, ex);
+        }
+        return listReg;
+    }
+
+    private int iGetTotalSub(String serviceId) {
+        int total = 0;
+
+        PreparedStatement ps = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        long startTime = System.currentTimeMillis();
+        String sql = "SELECT COUNT(*) FROM REG_INFO WHERE service_id = ? AND status = 1 AND renew = 1 and EXPIRE_TIME > sysdate";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setInt(1, Integer.parseInt(serviceId));
+
+            rs = ps.executeQuery();
+            if (rs.next()) {
+                total = rs.getInt("COUNT(*)");
+            }
+        } catch (Exception ex) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(new Date()).
+                    append("\nERROR iGetTotalSub");
+            logger.error(br, ex);
+            return total;
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to iGetTotalSub", startTime);
+        }
+        return total;
+    }
+    
+    public SpinResultObj countLuckySpin(String msisdn) {
+        PreparedStatement ps = null;
+        long timeStart = System.currentTimeMillis();
+        ResultSet rs = null;
+        Connection connection = null;
+        String sql = "select nvl(sum(added - used),0) remain_spin, nvl(sum(added),0) total_spin,  nvl(sum(used),0) used_spin  from lucky_spin \n"
+                + "where msisdn = ? and expire_time > sysdate";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            SpinResultObj result = new SpinResultObj();
+            while (rs.next()) {
+                result.setRemainSpin(rs.getInt("remain_spin"));
+                result.setTotalSpin(rs.getInt("total_spin"));
+                result.setUsedSpin(rs.getInt("used_spin"));
+                return result;
+            }
+        } catch (Exception ex) {
+            logger.error("Error countLuckySpin", ex);
+        } finally {
+            closeResultSet(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to countLuckySpin", timeStart);
+        }
+        return null;
+    }
+    public SpinResultObj doSpin(String msisdn) {
+        long timeStart = System.currentTimeMillis();
+        CallableStatement cs = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        String sql = "{call update_lucky_spin ( ?, ? )}";
+        try {
+            connection = getConnection(dbName);
+            cs = connection.prepareCall(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            cs.setString(1, msisdn);
+            cs.registerOutParameter(2, OracleTypes.CURSOR);
+            cs.executeUpdate();
+            rs = (ResultSet) cs.getObject(2);
+            SpinResultObj result = new SpinResultObj();
+            while (rs.next()) {
+                result.setLuckySpinId(rs.getLong("id"));
+                result.setPrizeId(rs.getInt("prize_id"));
+                result.setRemainSpin(rs.getInt("remain_spin"));
+                result.setTotalSpin(rs.getInt("total_spin"));
+                result.setUsedSpin(rs.getInt("used_spin"));
+                result.setTotalCoin(rs.getInt("total_coin"));
+                return result;
+            }
+        } catch (Exception ex) {
+            logger.error("Error call update_lucky_spin", ex);
+        } finally {
+            closeResource(rs);
+            closeResource(cs);
+            closeResource(connection);
+            logTime("Time to call update_lucky_spin", timeStart);
+        }
+        return null;
+    }
+    public SpinResultObj doSpinT(String msisdn,int prizeId, String partner_tran_id) {
+        long timeStart = System.currentTimeMillis();
+        CallableStatement cs = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        String sql = "{call update_lucky_spin_tool ( ?, ?,?,? )}";
+        try {
+            connection = getConnection(dbName);
+            cs = connection.prepareCall(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            cs.setString(1, msisdn);
+            cs.setInt(2, prizeId);
+            cs.setString(3, partner_tran_id);
+            cs.registerOutParameter(4, OracleTypes.CURSOR);
+            cs.executeUpdate();
+            rs = (ResultSet) cs.getObject(4);
+            SpinResultObj result = new SpinResultObj();
+            while (rs.next()) {
+                result.setLuckySpinId(rs.getLong("id"));
+                result.setPrizeId(rs.getInt("prize_id"));
+                result.setRemainSpin(rs.getInt("remain_spin"));
+                result.setTotalSpin(rs.getInt("total_spin"));
+                result.setUsedSpin(rs.getInt("used_spin"));
+                result.setTotalCoin(rs.getInt("total_coin"));
+                result.setPrizeWinnerId(rs.getInt("prize_winner_id"));
+                return result;
+            }
+        } catch (Exception ex) {
+            logger.error("Error call update_lucky_spin", ex);
+        } finally {
+            closeResource(rs);
+            closeResource(cs);
+            closeResource(connection);
+            logTime("Time to call update_lucky_spin", timeStart);
+        }
+        return null;
+    }
+    
+    public SpinResultObj doSpinSubmitPrize(String msisdn,int prizeId, int PrizeWinnerID, String transId) {
+        long timeStart = System.currentTimeMillis();
+        CallableStatement cs = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        String sql = "{call add_prize_submit ( ?, ?,?,?,? )}";
+        try {
+            connection = getConnection(dbName);
+            cs = connection.prepareCall(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            cs.setString(1, msisdn);
+            cs.setInt(2, prizeId);
+            cs.setInt(3, PrizeWinnerID);
+            cs.setString(4, transId);
+            cs.registerOutParameter(5, OracleTypes.CURSOR);
+            cs.executeUpdate();
+            rs = (ResultSet) cs.getObject(5);
+            SpinResultObj result = new SpinResultObj();
+            while (rs.next()) {
+                result.setLuckySpinId(rs.getLong("id"));
+                result.setPrizeId(rs.getInt("prize_id"));
+                result.setRemainSpin(rs.getInt("remain_spin"));
+                result.setTotalSpin(rs.getInt("total_spin"));
+                result.setUsedSpin(rs.getInt("used_spin"));
+                result.setTotalCoin(rs.getInt("total_coin"));
+                result.setPrizeWinnerId(rs.getInt("prize_winner_id"));
+                return result;
+            }
+        } catch (Exception ex) {
+            logger.error("Error call update_lucky_spin", ex);
+        } finally {
+            closeResource(rs);
+            closeResource(cs);
+            closeResource(connection);
+            logTime("Time to call update_lucky_spin", timeStart);
+        }
+        return null;
+    }
+    public List<PrizeWinner> getListWinner(String msisdn, int period, int page, int pageSize, int isTop, int codeType, String startDate, String endDate) throws SQLException {
+    ResultSet rs = null;
+    PreparedStatement ps = null;
+    List<PrizeWinner> result = new ArrayList<>();
+    long startTime = System.currentTimeMillis();
+    Connection connection = null;
+
+    StringBuilder sql = new StringBuilder();
+    sql.append("SELECT * FROM (SELECT ROWNUM rn, a.* FROM (")
+       .append("SELECT pw.*, lp.description, lp.prize_name,lp.IS_TOP ")
+       .append("FROM prize_winner pw ")
+       .append("LEFT JOIN list_prize lp ON pw.prize_id = lp.id ")
+       .append("WHERE 1=1 ");
+
+    List<Object> params = new ArrayList<>();
+
+    if (period > 0) {
+        sql.append("AND pw.period = ? ");
+        params.add(period);
+    }
+    if (msisdn != null && !msisdn.trim().isEmpty()) {
+        sql.append("AND pw.msisdn = ? ");
+        params.add(msisdn);
+    }
+    if (isTop > 0) {
+        sql.append("AND lp.is_top = ? ");
+        params.add(isTop);
+    }
+    if (startDate != null && endDate != null) {
+        sql.append("AND CODE_TIME >= to_date(?,'yyyy-MM-dd HH24:mi:ss') AND CODE_TIME <= to_date(?,'yyyy-MM-dd HH24:mi:ss') ");
+        params.add(startDate);
+        params.add(endDate);
+    }
+
+    sql.append("ORDER BY pw.code_time DESC) a) ")
+       .append("WHERE rn > ").append((page - 1) * pageSize)
+       .append(" AND rn <= ").append(page * pageSize);
+
+    try {
+        connection = getConnection(dbName);
+        ps = connection.prepareStatement(sql.toString());
+        if (WebserviceManager.queryDbTimeout > 0) {
+            ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+        }
+
+        // Set parameters
+        for (int i = 0; i < params.size(); i++) {
+            ps.setObject(i + 1, params.get(i));
+        }
+
+        // Logging SQL with params
+        String loggedSql = sql.toString();
+        for (Object param : params) {
+            String value = (param instanceof String || param instanceof Timestamp)
+                ? "'" + param.toString() + "'" : String.valueOf(param);
+            loggedSql = loggedSql.replaceFirst("\\?", value);
+        }
+        logger.info("Executing SQL: " + loggedSql);
+
+        rs = ps.executeQuery();
+
+        while (rs.next()) {
+            PrizeWinner pw = new PrizeWinner();
+            pw.setId(rs.getInt("ID"));
+            pw.setMsisdn(rs.getString("MSISDN"));
+            pw.setCode(rs.getString("CODE"));
+            pw.setCodeTime(fullDf.format(rs.getTimestamp("CODE_TIME")));
+            Timestamp processTime = rs.getTimestamp("PROCESS_TIME");
+            pw.setProcessTime(processTime == null ? "" : fullDf.format(processTime));
+            pw.setPrizeDescription(rs.getString("DESCRIPTION"));
+            pw.setPrizeName(rs.getString("PRIZE_NAME"));
+            pw.setPeriod(rs.getInt("PERIOD"));
+            pw.setTop(rs.getInt("IS_TOP"));
+            pw.setPage(page);
+            result.add(pw);
+        }
+
+        return result;
+    } catch (SQLException ex) {
+        logger.error("Error while fetching prize winners", ex);
+        throw ex; // rethrow để cho phép controller hoặc caller xử lý tiếp
+    } finally {
+        closeResource(rs);
+        closeResource(ps);
+        closeResource(connection);
+        logTime("Time to execute getListWinner", startTime);
+    }
+}
+
+    
+//    public List<PrizeWinner> getListWinner(String msisdn, int period, int page, int pageSize, int isTop, int codeType,Timestamp startDate,Timestamp endDate) throws SQLException {
+//        ResultSet rs = null;
+//        PreparedStatement ps = null;
+//        List<PrizeWinner> result = null;
+//        long startTime = System.currentTimeMillis();
+//        Connection connection = null;
+//        String sql = "select * from (select rownum rn,  a.* from \n"
+//                + "(select  pw.*,  lp.description, lp.prize_name "
+//                + "from prize_winner pw \n"
+//                + "left join list_prize lp on pw.prize_id = lp.id "
+//                + "where 1=1  ";
+//        if (period == 1) {
+//            sql += " and CODE_TIME >= trunc(sysdate)-15 ";
+//        } else if (period == 2) {
+//            sql += " and CODE_TIME >= trunc(sysdate)-30 ";
+//        }
+//        if (period > 0) {
+//            sql += " and pw.period = ? \n";
+//        }
+//        if (msisdn != null && !msisdn.isEmpty()) {
+//            sql += " and pw.msisdn = ? ";
+//        }
+//        if (isTop >= 0) {
+//            sql += " and lp.is_top = ? ";
+//        }
+//        if (startDate != null && endDate != null) {
+//                sql += " and CODE_TIME >= ? and CODE_TIME <= ? ";
+//        }
+////        sql += " and pw.code_type = ? ";
+//        sql += "order by code_time desc) a )\n"
+//                + "where rn > " + (page - 1) + " * " + pageSize + " and rn <= " + page + " * " + pageSize;
+//        try {
+//            connection = getConnection(dbName);
+//            ps = connection.prepareStatement(sql);
+//            if (WebserviceManager.queryDbTimeout > 0) {
+//                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+//            }
+//            int i = 0;
+//            if (period > 0) {
+//                ps.setInt(++i, period);
+//            }
+//            if (msisdn != null && !msisdn.isEmpty()) {
+//                ps.setString(++i, msisdn);
+//            }
+//            if (isTop >= 0) {
+//                ps.setInt(++i, isTop);
+//            }
+//            if (startDate != null && endDate != null) {
+//                ps.setTimestamp(++i, startDate);
+//                ps.setTimestamp(++i, endDate);
+//            }
+////            ps.setInt(++i, codeType);
+//            rs = ps.executeQuery();
+//            result = new ArrayList();
+//            while (rs.next()) {
+//                PrizeWinner lc = new PrizeWinner();
+//                lc.setId(rs.getInt("ID"));
+//                lc.setMsisdn(rs.getString("MSISDN"));
+//                lc.setCode(rs.getString("CODE"));
+//                lc.setCodeTime(fullDf.format(rs.getTimestamp("CODE_TIME")));
+//                lc.setProcessTime(rs.getTimestamp("PROCESS_TIME") == null ? "" : fullDf.format(rs.getTimestamp("PROCESS_TIME")));
+//                lc.setPrizeDescription(rs.getString("DESCRIPTION"));
+//                lc.setPrizeName(rs.getString("PRIZE_NAME"));
+////                lc.setChannel(rs.getString("CHANNEL"));
+//                lc.setPeriod(rs.getInt("PERIOD"));
+////                lc.setCodeType(rs.getInt("CODE_TYPE"));
+//                lc.setPage(page);
+//                result.add(lc);
+//            }
+//            return result;
+//        } catch (SQLException ex) {
+//            logger.error("Error get list winner", ex);
+//        } finally {
+//            closeResource(rs);
+//            closeResource(ps);
+//            closeResource(connection);
+//            logTime("Time to getListWinner", startTime);
+//        }
+//        return null;
+//    }
+
+    public int getCountWinner(String msisdn, int period, int isTop, int codeType,String startDate,String endDate) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+//        List<PrizeWinner> result = null;
+        long startTime = System.currentTimeMillis();
+        Connection connection = null;
+        String sql = "select count(*) counter from \n"
+                + "(select rownum, pw.*,   lp.description from prize_winner pw \n"
+                + "left join list_prize lp on pw.prize_id = lp.id "
+                //                + "left join group_prize g on lp.sub_group_prize = g.sub_group_id "
+                + "where 1=1 ";
+        if (period > 0) {
+            sql += " and pw.period = ? \n";
+        }
+        if (msisdn != null && !msisdn.isEmpty()) {
+            sql += " and pw.msisdn = ? ";
+        }
+        if (isTop >= 0) {
+            sql += " and lp.is_top = ? ";
+        }
+        sql += "order by code_time desc) \n";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.queryDbTimeout > 0) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            int i = 0;
+            if (period > 0) {
+                ps.setInt(++i, period);
+            }
+            if (msisdn != null && !msisdn.isEmpty()) {
+                ps.setString(++i, msisdn);
+            }
+            if (isTop >= 0) {
+                ps.setInt(++i, isTop);
+            }
+            rs = ps.executeQuery();
+            while (rs.next()) {
+                return rs.getInt("COUNTER");
+            }
+        } catch (SQLException ex) {
+            logger.error("Error count winner", ex);
+        } finally {
+            closeResource(rs);
+            closeResource(ps);
+            closeResource(connection);
+            logTime("Time to getCountWinner", startTime);
+        }
+        return 0;
+    }
+    
+    
+    public String addTurnSpin(String msisdn, int turn) {
+        long timeStart = System.currentTimeMillis();
+        CallableStatement cs = null;
+        ResultSet rs = null;
+        Connection connection = null;
+        String sql = "{call ADD_TURN_SPIN ( ?, ? )}";
+        try {
+            connection = getConnection(dbName);
+            cs = connection.prepareCall(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                cs.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+
+            cs.setString(1, msisdn);
+            cs.setInt(2, turn);
+            cs.executeUpdate();
+        } catch (Exception ex) {
+            logger.error("Error call ADD_TURN_SPIN", ex);
+        } finally {
+            closeResource(rs);
+            closeResource(cs);
+            closeResource(connection);
+            logTime("Time to call ADD_TURN_SPIN", timeStart);
+        }
+        return null;
+    }
+    
+    
+    public LuckySprin igetLuckySprin(String msisdn) {
+        LuckySprin mSprin = null;
+        long timeBegin = System.currentTimeMillis();
+        int count = 1;
+        while (mSprin == null) {
+            try {
+                mSprin = getLuckySprin(msisdn);
+            } catch (Exception ex) {
+                br.setLength(0);
+                br.append(loggerLabel).append("ERROR - ").append(count).append("\n").append(sqlGetUser);
+                logger.error(br, ex);
+                count++;
+            }
+            if (mSprin == null && System.currentTimeMillis() - timeBegin > WebserviceManager.breakQuery) {
+                br.setLength(0);
+                br.append(loggerLabel).append(new Date()).append("==>BREAK query select VTFREE_USER\n");
+                logger.error(br);
+                break;
+            }
+        }
+        return mSprin;
+    }
+
+    /**
+     * Lay thong tin luot choi
+     *
+     * @param userName
+     * @return
+     * @throws SQLException
+     */
+    private LuckySprin getLuckySprin(String msisdn) throws SQLException {
+        ResultSet rs = null;
+        PreparedStatement ps = null;
+        LuckySprin mSprin = null;
+        long timeStart = System.currentTimeMillis();
+        Connection connection = null;
+        String sql = "SELECT ID,MSISDN,ADDED,USED FROM lucky_spin where MSISDN = ? ";
+        try {
+            connection = getConnection(dbName);
+            ps = connection.prepareStatement(sql);
+            if (WebserviceManager.enableQueryDbTimeout) {
+                ps.setQueryTimeout(WebserviceManager.queryDbTimeout);
+            }
+            ps.setString(1, msisdn);
+            rs = ps.executeQuery();
+            mSprin = new LuckySprin();
+
+            if (rs.next()) {
+                logger.info("result: " + rs);
+                mSprin.setUsed(rs.getInt("USED"));
+                mSprin.setAdded(rs.getInt("ADDED"));
+                mSprin.setMsisdn(rs.getString("MSISDN"));
+                mSprin.setId(rs.getInt("ID"));
+            }
+            logger.info("mSprin: " + mSprin);
+            return mSprin;
+        } catch (SQLException ex) {
+            throw ex;
+        } finally {
+            closeResultSet(rs);
+            closeStatement(ps, sqlGetUser);
+            closeConnection(connection);
+            logTime("Time to getUserInfo", timeStart);
+        }
+    }
+
+    
+    
+}

+ 51 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/ScanProcessManager.java

@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.main;
+
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 3, 2013
+ * @version 1.0
+ */
+public class ScanProcessManager {
+
+    private static ScanProcessManager instance;
+    private Logger logger;
+
+    public ScanProcessManager() throws Exception {
+        logger = Logger.getLogger(ScanProcessManager.class);
+    }
+
+    public static ScanProcessManager getInstance() throws Exception {
+        if (instance == null) {
+            instance = new ScanProcessManager();
+        }
+        return instance;
+    }
+
+    public void start() {
+
+        logger.info("+++  SYSTEM IS STARTING  +++");
+        try {
+            WebserviceManager.getInstance().start();
+        } catch (Exception ex) {
+            logger.error(ex);
+        }
+    }
+
+    public void stop() {
+
+        logger.info("+++  SYSTEM IS STOPPING  +++");
+        try {
+            WebserviceManager.getInstance().stop();
+        } catch (Exception ex) {
+            logger.error(ex);
+        }
+    }
+}

+ 36 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/Start.java

@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.main;
+//import com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression;
+
+//import com.vas.wsfw.services.Trigger;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 3, 2013
+ * @version 1.0
+ */
+public class Start {
+
+    public static void main(String[] args) throws Exception {
+        // Khoi dong MoProcess        
+        ScanProcessManager.getInstance().start();
+//        RegularExpression regex = new RegularExpression("[Ee][Vv][Nn]\\s+([Tt][Cc]|[Nn][Tt])\\s+\\w+\\s+\\w+");
+//        String str = "EVn nt abc rwer 234";
+//        boolean match = regex.matches(str);
+//        System.out.print(match);
+
+        // trigger for returning the rewards
+//        Trigger trigger = new Trigger();
+//        trigger.beepForAnHour();
+
+//        // trigger for reporting
+//        Report report = new Report();
+////        report.reportForAnHour();
+//        Thread thread = new Thread(report);
+//        thread.start();
+    }
+}

+ 18 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/Stop.java

@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.main;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 3, 2013
+ * @version 1.0
+ */
+public class Stop {
+
+    public static void main(String[] args) throws Exception {
+        ScanProcessManager.getInstance().stop();
+    }
+}

+ 24 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/main/test.java

@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2010 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.main;
+import com.sun.org.apache.xerces.internal.impl.xpath.regex.RegularExpression;
+
+/**
+ *
+ * @author minhnh@viettel.com.vn
+ * @since Jun 3, 2013
+ * @version 1.0
+ */
+public class test {
+
+    public static void main(String[] args) throws Exception {
+        // Khoi dong MoProcess        
+//        ScanProcessManager.getInstance().start();
+        RegularExpression regex = new RegularExpression("[Ee][Vv][Nn]\\s+[Nn][Tt]\\s+\\w+");
+        String str = "EvN nt 123456";
+        boolean match = regex.matches(str);
+        System.out.print(match);
+    }
+}

+ 693 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/Exchange.java

@@ -0,0 +1,693 @@
+/*
+ * @Exchange.java    version 1.0
+ *
+ * Created on May 3, 2010
+ *
+ * Copyright 2006 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.services;
+
+import com.viettel.common.ExchMsg;
+import java.util.Date;
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+import com.vas.kittyfallwsvas.wsfw.common.Common;
+import java.text.SimpleDateFormat;
+import java.util.HashMap;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author: toanpd
+ * @since: May 3, 2010
+ */
+public class Exchange extends ExchangeClientChannel {
+
+    private Logger logger;
+    private Logger detailLogger;
+    private String loggerLabel = "Exchange: ";
+    //private ExchangeChannel channel;
+//    private String DATE_FORMAT = "yyyy-MM-dd";
+//    private String DATE_FORMAT2 = "yyyy-MM-dd HH:mm:ss";
+//    private java.text.SimpleDateFormat sdf;
+    private java.text.SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private java.text.SimpleDateFormat fullDf = new SimpleDateFormat("yyyyMMddHHmmss");
+//    private SimpleDateFormat dateFormatExchVal = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss a");
+//    private SimpleDateFormat fsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+//    private Calendar c1;
+    //
+//    private static final String NOT_REG = "S-PPS-68002";
+//    private static final String POS_REGISTER = "1";
+//    private static final String POS_UNREGISTER = "0";
+//    private static final String NOT_POST = "S-PRF-00025";
+//    public static final String EXCHGW_RESULT_ERR_CODE_IDX = "EXCHGW_RESULT_ERR_CODE_IDX";
+    //
+    private long timeStart;
+    private long timeExecute;
+    private StringBuilder br = new StringBuilder();
+    //
+//    public static long IN_VIEWACNTINFO;
+//    public static long IN_MODIACNTBAL_POSITIVE;
+//    public static long IN_MODIACNTBAL;
+//    public static long IN_MOD_VOICE_PRE;
+//    public static long CHARGING_MODIPRICEPLAN;
+//    public static long IN_ADDPRICE_FULL;
+//    public static long IN_REMOVEPRICE;
+//    public static long IN_MODIMBFREEBAL2;
+//    public static long IN_MODIMBFREEBAL;
+//    public static long IN_MODISMSBAL;
+//    public static long PCRF_ADJUSTQUOTA;
+//    public static long PCRF_GETALLQUOTA;
+//    public static long PCRF_UPDATEQUOTA;
+//    public static long CHARGING_QUERYACCTINFO;
+//    public static long CHARGING_MODI_ALL_BALANCE;
+//    public static long CHARGING_CREATE_OTCRD;
+//    public static long PCRF_SUBSCRIBESERVICE;
+//    public static long PCRF_UNSUBSCRIBESERVICE;
+//    //
+//    public static List ERR_PRE2POST = new ArrayList();
+//    public static List ERR_NOT_ALLOW_REG = new ArrayList();
+//    public static List ERR_PRE_PRICE_NOT_EXIST = new ArrayList();
+//    public static List ERR_POS_PRICE_NOT_EXIST = new ArrayList();
+//    public static List BALANCE_NOT_ENOUGH = new ArrayList();
+//    public static List BALANCE_SUSPEND = new ArrayList();
+//    public static List PRE_ALREADY_REG = new ArrayList();
+//    public static List POS_ALREADY_REG = new ArrayList();
+//    public static List ERR_PCRF = new ArrayList();
+//    //tungnv: nang cap partycode
+//    public static String PARTY_CODE_REG;
+//    public static String PARTY_CODE_EXTEND;
+//    public static String PARTY_CODE_ROLLBACK_REG;
+//    public static String PARTY_CODE_ROLLBACK_EXTEND;
+//    public static String PARTY_CODE_PROMOTION_MONEY;
+
+    /**
+     *
+     * @param logger
+     */
+    public Exchange(Logger logger) throws Exception {
+        this.logger = logger;
+        this.detailLogger = Logger.getLogger("detail");
+//        sdf = new java.text.SimpleDateFormat(DATE_FORMAT);
+//        sdf2 = new java.text.SimpleDateFormat(DATE_FORMAT2);
+//        c1 = Calendar.getInstance();
+    }
+
+    /**
+     *
+     * @param msisdn
+     * @param money
+     * @param balanceId
+     * @return
+     */
+//    public String addBalanceBasicPreAll(long money, String balanceId, Date expireDate,
+//            String productName) {
+////        if (money == 0) {
+////            return FreeTalk.ResultCode.SUCCESS;
+////        }
+//
+//        br.setLength(0);
+//        br.append(loggerLabel).
+//                append("Cong tien tai khoan: MSISDN=").append(cdrRecord.getMsisdn()).
+//                append(" - ADD_BALANCES=").append(money).
+//                append(" - BALANCE_ID=").append(balanceId).
+//                append(" - EXPIRE_DATE=").append(sdf2.format(expireDate));
+//        logger.info(br);
+//
+//        ExchMsg response = null;
+//        try {
+//            ExchMsg request = new ExchMsg();
+//            request.setSynchronous(true);
+//
+//            request.setCommand("IN_MOD_SMS_PRE");
+//            request.set("MSISDN", cdrRecord.getMsisdn());
+//            request.set("ADD_SMS", String.valueOf(money));//So tien cong
+//            if (balanceId != null) {//Neu co tai khoan truyen vao. (De null, cong vao tai khoan goc)
+//                request.set("ACCT_REST_ID", balanceId);//Ma tai khoan
+//            }
+//            request.set("EXPIRE_DATE", sdf2.format(expireDate));//Thoi gian het han
+////            request.set("PARTY_CODE", PARTY_CODE_PROMOTION_MONEY + "@" + productName);
+//            logger.info(request);
+//
+//            timeStart = System.currentTimeMillis();
+//            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+//            logTime("Time to IN_MOD_SMS_PRE");
+//
+//            String errCode = response.getError();
+//
+//            if (!errCode.equals(Common.ResultCode.SUCCESS)) {
+//                br.setLength(0);
+//                br.append(loggerLabel).
+//                        append("ERROR execute IN_MOD_SMS_PRE: MSISDN=").append(cdrRecord.getMsisdn()).
+//                        append(" - DESCRIPTION=").append(response.getDescription());
+//                logger.error(br);
+//                return "IN_MOD_SMS_PRE-" + errCode + "-" + response.getDescription();
+//            }
+//
+//            // tao cdr partycode
+////            CdrPartyCode cdr = new CdrPartyCode();
+////            cdr.setSender("VTFREE");
+////            cdr.setMsisdn(cdrRecord.getMsisdn());
+////            cdr.setActionId("3");
+////            cdr.setReqDate(fullDf.format(new Date()));
+////            cdr.setMoney(money);
+////            cdr.setDescription("Cong tien khuyen mai");
+////            cdr.setBackup1(PARTY_CODE_PROMOTION_MONEY + "@" + productName);
+////            cdr.setStatus(0);
+////            cdr.setFileTypeId(FreeTalk.CdrFileTypeId.PREPAID);
+////            listCdrPartyCode.add(cdr);
+//
+//            try {
+//                br.setLength(0);
+//                br.append(WebserviceManager.appId).append("||").
+//                        append("ProcessCdrTopup").append("||").
+//                        append(fullDf.format(new Date(timeStart))).append("||").
+//                        append(fullDf.format(new Date())).append("||").
+//                        append(ExchangeClientChannel.getChannel().getUser()).append("||").
+//                        append(Inet4Address.getLocalHost().getHostAddress()).append("||").
+//                        append("ProcessCdrTopup").append("||").
+//                        append("Cong tien KM").append("||").
+//                        append(cdrRecord.getMsisdn()).append("||").
+//                        append("MSISDN:").append(cdrRecord.getMsisdn()).append("|").
+//                        append("AMOUNT:").append(money).append("|").
+//                        append("EXPIRE:").append(sdf2.format(expireDate)).append("|").
+//                        append("BALANCE_ID:").append(balanceId);
+//                detailLogger.info(br);
+//            } catch (Exception ex) {
+//                logger.warn("Loi ghi log", ex);
+//            }
+//
+//            return Common.ResultCode.SUCCESS;
+//        } catch (Exception ex) {
+//            if (response != null) {
+//                br.setLength(0);
+//                br.append(loggerLabel).
+//                        append("ERROR execute IN_MOD_SMS_PRE: MSISDN=").append(cdrRecord.getMsisdn()).
+//                        append("\n").append(response);
+//                logger.error(br, ex);
+//            } else {
+//                br.setLength(0);
+//                br.append(loggerLabel).
+//                        append("ERROR execute IN_MOD_SMS_PRE: Response is null, MSISDN=").append(cdrRecord.getMsisdn());
+//                logger.error(br, ex);
+//            }
+//        }
+//        return Common.ResultCode.ERROR;
+//    }
+    public String addPromotion(String msisdn, String amount, String addDays, String accId)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        if (!msisdn.startsWith(WebserviceManager.countryCode)) {
+            msisdn = WebserviceManager.countryCode + msisdn;
+        }
+        request.setCommand("IN_MOD_SMS_PRE");
+        request.set("ADD_DAYS", addDays);
+        request.set("ADD_SMS", amount);
+        request.set("MSISDN", msisdn);
+        request.set("ACCT_REST_ID", accId);
+        this.logger.info("Add promotion subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+            this.logger.debug("Result add promotion subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute IN_MOD_SMS_PRE: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                return response.getDescription();
+            }
+            return Common.ResultCode.SUCCESS;
+        } catch (Exception ex) {
+            this.logger.error("Exception when add promotion for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+    public String topup(String msisdn, String amount, String addDays, String accId)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        if (!msisdn.startsWith(WebserviceManager.countryCode)) {
+            msisdn = WebserviceManager.countryCode + msisdn;
+        }
+        request.setCommand("CHARGING_MOD_MONEY_PRE");
+        request.set("ADD_DAYS", addDays);
+        request.set("ADD_BALANCES", amount);
+        request.set("MSISDN", msisdn);
+        request.set("ACCT_REST_ID", accId);
+        this.logger.info("charging subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+            this.logger.debug("Result charging for subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute CHARGING_MOD_MONEY_PRE: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                return response.getDescription();
+            }
+            return Common.ResultCode.SUCCESS;
+        } catch (Exception ex) {
+            this.logger.error("Exception when charging for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+    public String reset(String msisdn, String amount, String addDays, String accId)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        if (!msisdn.startsWith(WebserviceManager.countryCode)) {
+            msisdn = WebserviceManager.countryCode + msisdn;
+        }
+        request.setCommand("IN_MOD_BASIC2_PRE");
+        request.set("ADD_DAYS", addDays);
+        request.set("ADD_BALANCES", amount);
+        request.set("MSISDN", msisdn);
+        request.set("ACCT_REST_ID", accId);
+        request.set("RESET_MONEY", "0");
+        this.logger.info("charging subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+            this.logger.debug("Result charging for subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute CHARGING_MOD_MONEY_PRE: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                return response.getDescription();
+            }
+            return Common.ResultCode.SUCCESS;
+        } catch (Exception ex) {
+            this.logger.error("Exception when charging for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+    public String addPricePlan(String msisdn, String pricePlan, Date expireDate) {
+        if (pricePlan == null) {
+            return Common.ResultCode.SUCCESS;
+        } else {
+            br.setLength(0);
+            br.append("Add ma gia phu: MSISDN=").append(msisdn).
+                    append(" - PRICE_PLAN=").append(pricePlan).
+                    append(" - EXPIRE_DATE=").append(sdf2.format(expireDate));
+            logger.info(br);
+
+            ExchMsg response = null;
+            try {
+                ExchMsg request = new ExchMsg();
+                request.setSynchronous(true);
+                if (!msisdn.startsWith(WebserviceManager.countryCode)) {
+                    msisdn = WebserviceManager.countryCode + msisdn;
+                }
+                request.setCommand("IN_ADDPRICE_FULL");
+                request.set("MSISDN", msisdn);
+                request.set("PricePlanId", pricePlan);//So tien cong
+                request.set("EXP_PRICEPLAN", sdf2.format(expireDate));//Thoi gian het han
+                request.set("ACTION_ADD_PRICEPLAN", "1");//action add ma gia
+//                setTimeSt(System.currentTimeMillis());
+//                response = (ExchMsg) send(request, msisdn);
+                response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+                logTime("Time to IN_ADDPRICE_FULL");
+
+                String errCode = response.getError();
+                if ("S-PRF-00109".equals(errCode)) {
+                    return Common.ResultCode.EXIT_PRICEPLAN;
+                }
+
+
+                if (!errCode.equals(Common.ResultCode.SUCCESS)) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("ERROR execute IN_ADDPRICE_FULL: MSISDN=").append(msisdn).
+                            append(" - DESCRIPTION=").append(response.getDescription());
+                    logger.error(br);
+                    return "IN_ADDPRICE_FULL-" + errCode + "-" + response.getDescription();
+                }
+
+                return Common.ResultCode.SUCCESS;
+            } catch (Exception ex) {
+                if (response != null) {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("ERROR execute IN_ADDPRICE_FULL: MSISDN=").append(msisdn).
+                            append("\n").append(response);
+                    logger.error(br, ex);
+                } else {
+                    br.setLength(0);
+                    br.append(loggerLabel).
+                            append("ERROR execute IN_ADDPRICE_FULL: Response is null, MSISDN=").append(msisdn);
+                    logger.error(br, ex);
+                }
+            }
+            return Common.ResultCode.ERROR;
+        }
+    }
+
+//    public Response getBalance(String msisdn, Response resp)
+//            throws Exception {
+//        ExchMsg response = new ExchMsg();
+//        ExchMsg request = new ExchMsg();
+//        msisdn = "" + msisdn;
+//        request.setCommand("CHARGING_QUERY_ACCT_BAL");
+//        request.set("MSISDN", msisdn);
+//        this.logger.info("View getEABalance subscriber <" + msisdn + "> \n" + request);
+//        try {
+//            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+////            response = (ExchMsg) send(request, msisdn);
+//            logTime("Time to CHARGING_QUERY_ACCT_BAL");
+//            this.logger.debug("Result balace for subscriber <" + msisdn + "> \n" + response);
+//            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+//                br.setLength(0);
+//                br.append(loggerLabel).
+//                        append("ERROR execute CHARGING_QUERY_ACCT_BAL: MSISDN=").append(msisdn).
+//                        append(" - DESCRIPTION=").append(response.getDescription());
+//                logger.error(br);
+//                resp.setErrorCode("99");
+//                return resp;
+//            }
+//            String accId = response.get("ACCT_REST_ID") != null ? (String) response.get("ACCT_REST_ID") : null;
+//            String blStr = response.get("BALANCE") != null ? (String) response.get("BALANCE") : null;
+//            String exStr = response.get("EXPIRE_DATE") != null ? (String) response.get("EXPIRE_DATE") : null;
+//            String names = response.get("ACCT_REST_NAME") != null ? (String) response.get("ACCT_REST_NAME") : null;
+//            resp.setLstAccId(accId);
+//            resp.setLstAccName(names);
+//            resp.setLstBalance(blStr);
+//            resp.setLstExpire(exStr);
+//        } catch (Exception ex) {
+//            this.logger.error("Exception when view balance for sub <" + msisdn + "> detail following \n", ex);
+//        }
+//        return resp;
+//    }
+    public String chargingEMoney(String msisdn, String amount)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        msisdn = "" + msisdn;
+        request.setCommand("CHARGING_MOD_MONEY_PRE");
+        request.set("ADD_DAYS", "0");
+        request.set("ADD_BALANCES", amount);
+        request.set("MSISDN", msisdn);
+        request.set("ACCT_REST_ID", "88");
+        this.logger.info("chargingEMoney subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+//            response = (ExchMsg) send(request, msisdn);
+            logTime("Time to CHARGING_MOD_MONEY_PRE");
+            this.logger.debug("Result chargingEMoney for subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute CHARGING_MOD_MONEY_PRE: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                result = response.getDescription();
+            }
+        } catch (Exception ex) {
+            this.logger.error("Exception when chargingEMoney for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+    public String getBalance(String msisdn, String balanceId)
+            throws Exception {
+        String balance = "0";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        msisdn = "" + msisdn;
+        request.setCommand("IN_VIEWACNTINFO");
+        request.set("MSISDN", msisdn);
+        this.logger.info("View getEABalance subscriber <" + msisdn + "> \n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+//            response = (ExchMsg) send(request, msisdn);
+            logTime("Time to IN_VIEWACNTINFO");
+            this.logger.debug("Result balace for subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute IN_VIEWACNTINFO: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                return balance;
+            }
+            String accId = response.get("BALANCE_TYPE_IDS") != null ? (String) response.get("BALANCE_TYPE_IDS") : null;
+            String blStr = response.get("BALANCES") != null ? (String) response.get("BALANCES") : null;
+            if (accId != null && blStr != null) {
+                String[] accIdArr = accId.split("&");
+                String[] blStrArr = blStr.split("&");
+                if (accIdArr.length != blStrArr.length) {
+                    return balance;
+                } else {
+                    HashMap bleMap = new HashMap();
+                    for (int i = 0; i < accIdArr.length; i++) {
+                        bleMap.put(accIdArr[i], blStrArr[i]);
+                    }
+                    try {
+                        balance = bleMap.get(balanceId).toString();
+                        balance = balance.substring(0, balance.length() - 4);
+                    } catch (Exception e) {
+                        balance = "0";
+                    }
+                    return balance;
+                }
+            } else {
+                return balance;
+            }
+        } catch (Exception ex) {
+            this.logger.error("Exception when view balance for sub <" + msisdn + "> detail following \n", ex);
+        }
+        return balance;
+    }
+
+    public String addMoney(String msisdn, String amount, String balanceId)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        msisdn = "" + msisdn;
+        request.setCommand("IN_MOD_BASIC2_PRE");
+        request.set("ADD_DAYS", "0");
+        request.set("ADD_BALANCES", amount);
+        request.set("MSISDN", msisdn);
+        request.set("ACCT_REST_ID", balanceId);
+        this.logger.info("chargingEMoney subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+//            response = (ExchMsg) send(request, msisdn);
+            logTime("Time to IN_MOD_BASIC2_PRE");
+            this.logger.debug("Result chargingEMoney for subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute IN_MOD_BASIC2_PRE: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                result = response.getDescription();
+            } else {
+                result = Common.ResultCode.SUCCESS;
+            }
+        } catch (Exception ex) {
+            this.logger.error("Exception when chargingEMoney for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+    public String chargingMoney(String msisdn, String amount)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        msisdn = "" + msisdn;
+        request.setCommand("IN_MODIACNTBAL_POSITIVE");
+
+        request.set("MSISDN", msisdn);
+        request.set("CHARGE_VALUE", amount);
+        this.logger.info("chargingEMoney subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+//            response = (ExchMsg) send(request, msisdn);
+            logTime("Time to IN_MODIACNTBAL_POSITIVE");
+            this.logger.debug("Result chargingEMoney for subscriber <" + msisdn + "> \n" + response);
+            if (Common.ResultCode.NOT_ENOUGHT.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                result = Common.ResultCode.NOT_ENOUGHT;
+            }
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute IN_MODIACNTBAL_POSITIVE: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                result = response.getDescription();
+            } else {
+                result = Common.ResultCode.SUCCESS;
+            }
+        } catch (Exception ex) {
+            this.logger.error("Exception when chargingEMoney for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+//    public String getBalance(String msisdn)
+//            throws Exception {
+//        String balance = "0";
+//        ExchMsg response = new ExchMsg();
+//        ExchMsg request = new ExchMsg();
+//        msisdn = "" + msisdn;
+//        request.setCommand("CHARGING_QUERY_ACCT_BAL");
+//        request.set("MSISDN", msisdn);
+//        this.logger.info("View getEABalance subscriber <" + msisdn + "> \n" + request);
+//        try {
+//            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+////            response = (ExchMsg) send(request, msisdn);
+//            logTime("Time to CHARGING_QUERY_ACCT_BAL");
+//            this.logger.debug("Result balace for subscriber <" + msisdn + "> \n" + response);
+//            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+//                br.setLength(0);
+//                br.append(loggerLabel).
+//                        append("ERROR execute CHARGING_QUERY_ACCT_BAL: MSISDN=").append(msisdn).
+//                        append(" - DESCRIPTION=").append(response.getDescription());
+//                logger.error(br);
+//                return balance;
+//            }
+//            String accId = response.get("ACCT_REST_ID") != null ? (String) response.get("ACCT_REST_ID") : null;
+//            String blStr = response.get("BALANCE") != null ? (String) response.get("BALANCE") : null;
+//            if (accId != null && blStr != null) {
+//                String[] accIdArr = accId.split("&");
+//                String[] blStrArr = blStr.split("&");
+//                if (accIdArr.length != blStrArr.length) {
+//                    return balance;
+//                } else {
+//                    HashMap bleMap = new HashMap();
+//                    for (int i = 0; i < accIdArr.length; i++) {
+//                        bleMap.put(accIdArr[i], blStrArr[i]);
+//                    }
+//                    try {
+//                        balance = bleMap.get("1").toString();
+//                        balance = balance.substring(0, balance.length() - 4);
+//                    } catch (Exception e) {
+//                        balance = "0";
+//                    }
+//                    return balance;
+//                }
+//            } else {
+//                return balance;
+//            }
+//        } catch (Exception ex) {
+//            this.logger.error("Exception when view balance for sub <" + msisdn + "> detail following \n", ex);
+//        }
+//        return balance;
+//    }
+    public String topupByEMoney(String msisdn, String amount)
+            throws Exception {
+        String result = "";
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        msisdn = "" + msisdn;
+        request.setCommand("CHARGING_IN_PAYMENT");
+        request.set("VALUE", amount);
+        request.set("MSISDN", msisdn);
+        this.logger.info("topupByEMoney subscriber <" + msisdn + ">amount<" + amount + ">\n" + request);
+        try {
+//            response = (ExchMsg) send(request, msisdn);
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+            logTime("Time to CHARGING_IN_PAYMENT");
+            this.logger.debug("Result topupByEMoney subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute CHARGING_IN_PAYMENT: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                result = response.getDescription();
+            }
+        } catch (Exception ex) {
+            this.logger.error("Exception when topupByEMoney for sub <" + msisdn + "> detail following \n", ex);
+            result = ex.toString();
+        }
+        return result;
+    }
+
+    public void logTime(String strLog) {
+        timeExecute = System.currentTimeMillis() - timeStart;
+        if (timeExecute >= WebserviceManager.minTimeOcs && WebserviceManager.loggerOcsMap != null) {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(WebserviceManager.getTimeLevelOcs(timeExecute)).append(": ").
+                    append(strLog).
+                    append(": ").
+                    append(timeExecute).
+                    append(" ms");
+
+            logger.warn(br);
+        } else {
+            br.setLength(0);
+            br.append(loggerLabel).
+                    append(strLog).
+                    append(": ").
+                    append(timeExecute).
+                    append(" ms");
+
+            logger.info(br);
+        }
+    }
+
+    public String[] getAllBalance(String msisdn)
+            throws Exception {
+        String[] balance = new String[4];
+        ExchMsg response = new ExchMsg();
+        ExchMsg request = new ExchMsg();
+        msisdn = "" + msisdn;
+        request.setCommand("IN_VIEWACNTINFO");
+        request.set("MSISDN", msisdn);
+        this.logger.info("View getEABalance subscriber <" + msisdn + "> \n" + request);
+        try {
+            response = (ExchMsg) ExchangeClientChannel.getChannel().sendAll(request, 30000L, true);
+//            response = (ExchMsg) send(request, msisdn);
+            logTime("Time to IN_VIEWACNTINFO");
+            this.logger.debug("Result balace for subscriber <" + msisdn + "> \n" + response);
+            if (!Common.ResultCode.SUCCESS.equals(response.getError())) {
+                br.setLength(0);
+                br.append(loggerLabel).
+                        append("ERROR execute IN_VIEWACNTINFO: MSISDN=").append(msisdn).
+                        append(" - DESCRIPTION=").append(response.getDescription());
+                logger.error(br);
+                return null;
+            }
+            //String accId = response.get("BALANCE_TYPE_IDS") != null ? (String) response.get("BALANCE_TYPE_IDS") : null;
+            String accName = response.get("BALANCE_NAMES") != null ? (String) response.get("BALANCE_NAMES") : null;
+            String blStr = response.get("BALANCES") != null ? (String) response.get("BALANCES") : null;
+            String exStr = response.get("EXPIRE_DATES") != null ? (String) response.get("EXPIRE_DATES") : null;
+            String blType = response.get("BALANCE_TYPE_IDS") != null ? (String) response.get("BALANCE_TYPE_IDS") : null;
+            balance[0] = accName;
+            balance[1] = blStr;
+            balance[2] = exStr;
+            balance[3] = blType;
+
+        } catch (Exception ex) {
+            this.logger.error("Exception when view balance for sub <" + msisdn + "> detail following \n", ex);
+            return null;
+        }
+        return balance;
+    }
+}

+ 285 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/ExchangeChannel.java

@@ -0,0 +1,285 @@
+/*
+ * Copyright 2011 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.services;
+
+import com.viettel.common.ExchMsg;
+import com.viettel.common.ObjectClientChannel;
+import com.viettel.common.ViettelMsg;
+import com.viettel.common.ViettelService;
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+import java.io.IOException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import org.apache.log4j.Logger;
+
+/**
+ * Thong tin ObjectClientChannel va moduleId
+ *
+ * @author TungTT
+ * @version 1.0
+ * @since 01-03-2011
+ */
+public class ExchangeChannel {
+
+    private String host;
+    private int port;
+    private String user;
+    private String pass;
+    private ObjectClientChannel channel;
+    private int id;
+    private String pathEx;
+    private int status;
+    private String type;
+    //
+    private Logger logger = Logger.getLogger(ExchangeChannel.class);
+    private String loggerLabel;
+    //checker
+    private ExchangeChannel.ChannelChecker checker;
+    private ExecutorService executor = Executors.newCachedThreadPool();
+    private boolean startChecker = false;
+
+    public ExchangeChannel(ObjectClientChannel channel, long receiverTimeOut, int id, String pathEx, String type) {
+        this.channel = channel;
+        this.channel.setReceiverTimeout(receiverTimeOut);
+        this.id = id;
+        this.host = channel.getIp();
+        this.port = channel.getPort();
+        this.user = channel.getUsername();
+        this.pass = channel.getPassword();
+        this.pathEx = pathEx;
+        this.loggerLabel = "ExchangeChannel" + this.getInfor();
+        this.type = type;
+        this.checker = new ExchangeChannel.ChannelChecker();
+    }
+
+    public String getInfor() {
+        return host + ":" + port;
+    }
+
+    public String getFullInfo() {
+        return host + ":" + port + "/" + user + "@" + pass;
+    }
+
+    public ObjectClientChannel getChannel() {
+        return channel;
+    }
+
+    public void setChannel(ObjectClientChannel channel) {
+        this.channel = channel;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public String getPass() {
+        return pass;
+    }
+
+    public void setPass(String pass) {
+        this.pass = pass;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public String getUser() {
+        return user;
+    }
+
+    public void setUser(String user) {
+        this.user = user;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setId(int id) {
+        this.id = id;
+    }
+
+    public int getStatus() {
+        return status;
+    }
+
+    public void setStatus(int status) {
+        this.status = status;
+    }
+
+    public synchronized void startChecker() {
+        if (!startChecker) {
+            startChecker = true;
+            this.executor.execute(checker);
+        }
+    }
+
+    public ViettelMsg send(ViettelMsg request) throws IOException {
+        long timeSt = System.currentTimeMillis();
+        try {
+            if (this.status == 0) {
+                ViettelMsg response = channel.send(request);
+                return response;
+            } else {
+                throw new IOException("ExchangeChannel is blocked because It has many timeout transactions...");
+            }
+        } catch (IOException ex) {
+            this.status = 1;
+            //khoi tao tien trinh kiem tra ket noi o day
+            this.startChecker();
+            throw ex;
+        } finally {
+            logTime("Time to send request", timeSt);
+        }
+    }
+
+    /**
+     *
+     * @param request
+     * @param commandTimeOut
+     * @param changeClientWhenErr
+     * @param logger
+     * @return
+     * @throws IOException
+     */
+    public ViettelMsg sendAll(ViettelMsg request, Long commandTimeOut, boolean changeClientWhenErr) throws Exception {
+        ViettelMsg response = null;
+        try {
+            if (commandTimeOut != null) {
+                request.set("ClientTimeout", String.valueOf(commandTimeOut));
+            }
+            response = this.send(request);
+        } catch (Exception ex) {
+            logger.error(loggerLabel + "ERROR send request " + this.getInfor(), ex);
+            this.status = 1;
+            //khoi tao tien trinh kiem tra ket noi o day
+            this.startChecker();
+            if (changeClientWhenErr) {
+                int mainId = this.getId();
+                ExchangeChannel newChannel = ExchangeClientChannel.getChannel();
+                if (mainId != newChannel.getId()) {
+                    logger.info(loggerLabel + "Change to Exchange " + newChannel.getInfor());
+                    return processRequestOther(mainId, newChannel, request);
+                } else {
+                    logger.error(loggerLabel
+                            + "All Client Exchange error, not process request: ERROR " + request.getCommand());
+                    return response;
+                }
+            }
+        }
+        return response;
+    }
+
+    private ViettelMsg processRequestOther(int mainChannelId, ExchangeChannel channelOther, ViettelMsg request) {
+        ViettelMsg response = null;
+        try {
+            response = channelOther.send(request);
+        } catch (Exception ex) {
+            logger.error(loggerLabel + "ERROR send request in Client: " + channelOther.getInfor(), ex);
+            channelOther.setStatus(1);
+            //khoi tao tien trinh kiem tra ket noi o day
+            channelOther.startChecker();
+            ExchangeChannel newChannel = ExchangeClientChannel.getChannel();
+
+            if (mainChannelId != newChannel.getId()) {
+                logger.info(loggerLabel + "Change to Exchange " + newChannel.getInfor());
+                return processRequestOther(mainChannelId, newChannel, request);
+            } else {
+                logger.error(loggerLabel
+                        + "All Client Exchange error, not process request: ERROR " + request.getCommand());
+                return response;
+            }
+        } finally {
+        }
+        return response;
+    }
+
+    public void logTime(String strLog, long timeSt) {
+        long timeEx = System.currentTimeMillis() - timeSt;
+        if (timeEx >= WebserviceManager.minTimeOcs && WebserviceManager.loggerOcsMap != null) {
+            logger.warn(loggerLabel
+                    + WebserviceManager.getTimeLevelOcs(timeEx)
+                    + ": " + strLog + ": " + timeEx + " ms\n");
+        } else {
+            logger.info(loggerLabel + strLog + ": " + timeEx + " ms");
+        }
+    }
+
+    private class ChannelChecker implements Runnable {
+
+        private ChannelChecker() {
+        }
+
+        @Override
+        public void run() {
+            String label = ExchangeChannel.this.getInfor() + ":";
+            ExchangeChannel.this.logger.info(label + "Start thread check channel " + ExchangeChannel.this.getInfor());
+            while (true) {
+                try {
+                    Thread.sleep(ExchangeClientChannel.periodCheck);
+                } catch (Exception e) {
+                }
+
+                if (ExchangeChannel.this.status != 0) {
+                    if (ExchangeChannel.this.type.equalsIgnoreCase("exchange")) {
+                        ExchMsg request = new ExchMsg();
+                        ExchMsg response = null;
+                        request.setCommand(ExchangeClientChannel.commandTest);
+                        request.set("MSISDN", ExchangeClientChannel.msisdnTest);
+                        request.set("ClientTimeout", "25000");
+                        try {
+                            ExchangeChannel.this.logger.info(label + "Test send command  ");
+                            response = (ExchMsg) ExchangeChannel.this.send(request);
+                            if (response != null) {
+                                ExchangeChannel.this.logger.info(label + "Test send command success");
+                                ExchangeChannel.this.status = 0;
+                                ExchangeChannel.this.startChecker = false;
+                                return;
+                            } else {
+                                ExchangeChannel.this.logger.error(label + "Test send command error");
+                            }
+                        } catch (Exception e) {
+                            ExchangeChannel.this.logger.error(label + "Test send command error");
+                        }
+                    } else if (ExchangeChannel.this.type.equalsIgnoreCase("service")) {
+                        ViettelService request = new ViettelService();
+                        ViettelService response = null;
+                        request.setMessageType(ExchangeClientChannel.messageTypeTest);
+                        request.setProcessCode(ExchangeClientChannel.processCodeTest);
+                        request.set("MSISDN", ExchangeClientChannel.msisdnTest);
+                        request.set("ClientTimeout", "25000");
+                        try {
+                            ExchangeChannel.this.logger.info(label + "Test send command  ");
+                            response = (ViettelService) ExchangeChannel.this.send(request);
+                            if (response != null) {
+                                ExchangeChannel.this.logger.info(label + "Test send command   success");
+                                ExchangeChannel.this.status = 0;
+                                ExchangeChannel.this.startChecker = false;
+                                return;
+                            } else {
+                                ExchangeChannel.this.logger.error(label + "Test send command  error");
+                            }
+                        } catch (Exception e) {
+                            ExchangeChannel.this.logger.error(label + "Test send command  error");
+                        }
+                    }
+                } else {
+                    ExchangeChannel.this.logger.info(label + " no need check, status=" + ExchangeChannel.this.status);
+                    ExchangeChannel.this.startChecker = false;
+                    return;
+                }
+            }
+        }
+    }
+}

+ 277 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/ExchangeClientChannel.java

@@ -0,0 +1,277 @@
+/*
+ * Copyright 2011 Viettel Telecom. All rights reserved.
+ * VIETTEL PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ */
+package com.vas.kittyfallwsvas.wsfw.services;
+
+import com.viettel.common.ObjectClientChannel;
+import com.viettel.utility.PropertiesUtils;
+import java.util.HashMap;
+import org.apache.log4j.Logger;
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+
+/**
+ * Quan ly thong tin Exchange client
+ *
+ * @author TungTT
+ * @version 1.0
+ * @since 01-03-2011
+ */
+public class ExchangeClientChannel {
+
+    private static Logger logger = Logger.getLogger(ExchangeClientChannel.class);
+    private static String loggerLabel = "ExchangeClientChannel: ";
+    private static HashMap listExch;
+    private int exchId;
+//    private static HashMap<String, ExchangeClientChannel> hmInstance = new HashMap<String, ExchangeClientChannel>();
+    private static ExchangeClientChannel instance;
+    private int RECEIVER_TIME_OUT = -1;
+    private static int exchCount = 0;
+    //test ket noi
+    public static String commandTest;
+    public static String messageTypeTest;
+    public static String processCodeTest;
+    public static String msisdnTest;
+    public static long periodCheck;
+
+    public ExchangeClientChannel() throws Exception {
+        logger.info(loggerLabel + "Init Exchange");
+        String path = WebserviceManager.pathExch;
+
+        String host;
+        int port;
+        String user;
+        String pass;
+        String type;
+        listExch = new HashMap();
+
+        try {
+            PropertiesUtils pro = new PropertiesUtils();
+            pro.loadPropertiesEpt(path);
+            String[] properties = pro.getProperties();
+
+            RECEIVER_TIME_OUT = Integer.parseInt(pro.getProperty("RECEIVER_TIME_OUT", "100000"));
+            commandTest = pro.getProperty("EXCH_COMMAND_TEST", "IN_VIEWUSERINFO");
+            messageTypeTest = pro.getProperty("MESSAGE_TYPE_TEST", "1900");
+            processCodeTest = pro.getProperty("PROCESS_CODE_TEST", "030005");
+            msisdnTest = pro.getProperty("MSISDN_TEST", "84985098588");
+            periodCheck = Long.parseLong(pro.getProperty("PERIOD_CHECK", "30000"));
+
+            int index = 0;
+            String line = properties[index];
+            exchId = 0;
+
+            while (index <= properties.length) {
+                host = "";
+                port = -1;
+                user = "";
+                pass = "";
+                type = "";
+
+                // Get config
+                while (index < properties.length && !line.trim().toUpperCase().equals("[CHANNEL]")) {
+                    line = properties[index++];
+                }
+                if (index >= properties.length) {
+                    return;
+                }
+                line = properties[index++];
+
+
+                while (index <= properties.length && line.trim().toUpperCase().indexOf("[CHANNEL]") < 0) {
+                    if (line.trim().length() > 0) {
+                        String info[] = line.split("=");
+                        if (info[0].trim().toUpperCase().equals("ADDRESS")) {
+                            host = info[1].trim();
+                        }
+                        if (info[0].trim().toUpperCase().equals("PORT")) {
+                            port = Integer.parseInt(info[1].trim());
+                        }
+                        if (info[0].trim().toUpperCase().equals("USER")) {
+                            user = info[1].trim();
+                        }
+                        if (info[0].trim().toUpperCase().equals("PASS")) {
+                            pass = info[1].trim();
+                        }
+                        if (info[0].trim().toUpperCase().equals("TYPE")) {
+                            type = info[1].trim();
+                        }
+                    }
+                    if (index >= properties.length) {
+                        break;
+                    }
+                    line = properties[index++];
+                }
+                // init client
+                ObjectClientChannel channel = new ObjectClientChannel(host, port, user, pass, true);
+                ExchangeChannel exChannel = new ExchangeChannel(channel, RECEIVER_TIME_OUT, exchId, path, type);
+                listExch.put(exchId, exChannel);
+                exchId++;
+
+                logger.info(loggerLabel + "Init Exchange: " + exChannel.getInfor() + " success");
+            }
+
+            if (RECEIVER_TIME_OUT != -1) {
+                logger.info(loggerLabel + "RECEIVER_TIME_OUT: " + RECEIVER_TIME_OUT);
+            }
+
+            logger.info(loggerLabel + "Init All Exchange success");
+        } catch (Exception ex) {
+            logger.error("ERROR Init Exchange, please check exchange_client.cfg", ex);
+            listExch.clear();
+        }
+    }
+
+    public ExchangeClientChannel(String pathEx) throws Exception {
+        logger.info(loggerLabel + "Init Exchange");
+        String path = pathEx;
+
+        String host;
+        int port;
+        String user;
+        String pass;
+        String type;
+        listExch = new HashMap();
+
+        try {
+            PropertiesUtils pro = new PropertiesUtils();
+            pro.loadPropertiesEpt(path);
+            String[] properties = pro.getProperties();
+
+            RECEIVER_TIME_OUT = Integer.parseInt(pro.getProperty("RECEIVER_TIME_OUT", "100000"));
+            commandTest = pro.getProperty("EXCH_COMMAND_TEST", "IN_VIEWUSERINFO");
+            messageTypeTest = pro.getProperty("MESSAGE_TYPE_TEST", "1900");
+            processCodeTest = pro.getProperty("PROCESS_CODE_TEST", "030005");
+            msisdnTest = pro.getProperty("MSISDN_TEST", "");
+            periodCheck = Long.parseLong(pro.getProperty("PERIOD_CHECK", "30000"));
+
+            int index = 0;
+            String line = properties[index];
+            exchId = 0;
+
+            while (index <= properties.length) {
+                host = "";
+                port = -1;
+                user = "";
+                pass = "";
+                type = "";
+
+                // Get config
+                while (index < properties.length && !line.trim().toUpperCase().equals("[CHANNEL]")) {
+                    line = properties[index++];
+                }
+                if (index >= properties.length) {
+                    return;
+                }
+                line = properties[index++];
+
+
+                while (index <= properties.length && line.trim().toUpperCase().indexOf("[CHANNEL]") < 0) {
+                    if (line.trim().length() > 0) {
+                        String info[] = line.split("=");
+                        if (info[0].trim().toUpperCase().equals("ADDRESS")) {
+                            host = info[1].trim();
+                        }
+                        if (info[0].trim().toUpperCase().equals("PORT")) {
+                            port = Integer.parseInt(info[1].trim());
+                        }
+                        if (info[0].trim().toUpperCase().equals("USER")) {
+                            user = info[1].trim();
+                        }
+                        if (info[0].trim().toUpperCase().equals("PASS")) {
+                            pass = info[1].trim();
+                        }
+                        if (info[0].trim().toUpperCase().equals("TYPE")) {
+                            type = info[1].trim();
+                        }
+                    }
+                    if (index >= properties.length) {
+                        break;
+                    }
+                    line = properties[index++];
+                }
+                // init client
+                ObjectClientChannel channel = new ObjectClientChannel(host, port, user, pass, true);
+                ExchangeChannel exChannel = new ExchangeChannel(channel, RECEIVER_TIME_OUT, exchId, pathEx, type);
+                listExch.put(exchId, exChannel);
+                exchId++;
+
+                logger.info(loggerLabel + "Init Exchange: " + exChannel.getInfor() + " success");
+            }
+
+            if (RECEIVER_TIME_OUT != -1) {
+                logger.info(loggerLabel + "RECEIVER_TIME_OUT: " + RECEIVER_TIME_OUT);
+            }
+
+            logger.info(loggerLabel + "Init All Exchange success");
+        } catch (Exception ex) {
+            logger.error("ERROR Init Exchange, please check exchange_client.cfg", ex);
+            listExch.clear();
+        }
+    }
+
+    public static ExchangeClientChannel getInstance() throws Exception {
+        if (instance == null) {
+            instance = new ExchangeClientChannel();
+        }
+        return instance;
+    }
+
+    public synchronized static ExchangeChannel getChannel() {
+        int getAcount = 0;
+        try {
+            while (true) {
+                if (getAcount > listExch.size() - 1) {
+                    logger.info("All ExchangeChannel is blocked => set active status for all");
+                    //Tat ca cac Channel trong list deu bi block. Thuc hien giai phong 
+                    for (int i = 0; i < listExch.size(); i++) {
+                        ((ExchangeChannel) listExch.get(i)).setStatus(0);
+                    }
+                    getAcount = 0;
+                }
+
+                if (exchCount > listExch.size() - 1) {
+                    //Kiem tra exchCount co lon hon so luong chanle trong list khong.
+                    exchCount = 0;
+                }
+
+                if (((ExchangeChannel) listExch.get(exchCount)).getStatus() == 0) {
+                    //Lay channel ra, tang exchCount roi return
+                    ExchangeChannel channel = (ExchangeChannel) listExch.get(exchCount);
+                    exchCount++;
+                    return channel;
+                } else {
+                    getAcount++;
+                    exchCount++;
+                }
+            }
+        } catch (Exception ex) {
+            logger.error("Get channel in exchange channel list fails, return Null:.........", ex);
+            return null;
+        }
+    }
+
+    public int getExchId() {
+        return exchId;
+    }
+
+    public void setExchId(int exchId) {
+        this.exchId = exchId;
+    }
+
+    public HashMap getListExch() {
+        return listExch;
+    }
+
+    public void setListExch(HashMap listExch) {
+        ExchangeClientChannel.listExch = listExch;
+    }
+
+    public int getRECEIVER_TIME_OUT() {
+        return RECEIVER_TIME_OUT;
+    }
+
+    public void setRECEIVER_TIME_OUT(int RECEIVER_TIME_OUT) {
+        this.RECEIVER_TIME_OUT = RECEIVER_TIME_OUT;
+    }
+}

+ 578 - 0
KittyFallWs/KittyFallWs/src/com/vas/kittyfallwsvas/wsfw/services/WSProcessor.java

@@ -0,0 +1,578 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.kittyfallwsvas.wsfw.services;
+
+import com.vas.kittyfallwsvas.wsfw.common.Common;
+import com.vas.kittyfallwsvas.wsfw.common.EncryptUtil;
+import com.vas.kittyfallwsvas.wsfw.obj.MpsConfigObj;
+import com.viettel.ussdfw.log.ProcessTransLog;
+import com.viettel.ussdfw.object.TransactionLog;
+import com.viettel.ussdfw.object.WebserviceMsg;
+import com.viettel.ussdfw.object.WebserviceObject;
+import com.viettel.ussdfw.webservice.WebserviceFW;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+/**
+ *
+ * @author Sungroup
+ */
+public class WSProcessor extends WebserviceFW {
+
+    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+    public static String propertyTag = "original";
+    public static String errorTag = "return";
+    public static List<String> NOT_ENOUGH_MONEY_RES;
+    public static List<String> ACCOUNT_BLOCKED_RES;
+    public static List<String> LIST_SUCCESS_RES;
+    public static List<String> LIST_CANCEL_SUCCESS_RES;
+
+    public WSProcessor(Logger logger, String pathWSConfig) throws Exception {
+        super(logger, pathWSConfig);
+    }
+
+    public WSProcessor(Logger logger, String pathWSConfig, String pathDatabaseConfig) throws Exception {
+        super(logger, pathWSConfig, pathDatabaseConfig);
+    }
+
+    public String cancelService(String msisdn, String packName) {
+
+        // TODO add your handling code here:  
+        // insert to webservice table
+        WebserviceObject wsObj = this.getWebservice("register");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        // get mps config
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("CANCEL_" + packName);
+        String mpsUrl = makeMpsUrl(msisdn, mpsConfig, wsObj.getWsdl(), false, null);
+
+        logger.info("mpsUrl: " + mpsUrl);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when cancel service via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String registerMps(String msisdn, double fee, String packName) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("register");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("REGISTER_" + packName);
+        String mpsUrl = makeMpsUrl(msisdn, mpsConfig, wsObj.getWsdl(), false, null);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when charge money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String requestMpsOtp(String msisdn, int fee, String REQ, String packName) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("register_otp");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("REGISTER_" + packName);
+
+        logger.info("wsObj: " + wsObj.getWsdl());
+
+        String mpsUrl = makeMpsUrl(msisdn, mpsConfig, wsObj.getWsdl(), true, REQ);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when charge money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String registerMpsConfirm(String msisdn, int fee, String otp, String REQ, String packName) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("register_otp");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("REGISTER_" + packName);
+        String mpsUrl = makeMpsUrlOtpConfirm(msisdn, mpsConfig, wsObj.getWsdl(), otp, REQ);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when charge money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String chargeFeeOtp(String msisdn, int fee, String REQ) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("charge_fee");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("CHARGE_" + fee);
+        String mpsUrl = makeMpsUrl(msisdn, mpsConfig, wsObj.getWsdl(), true, REQ);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when charge money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String chargeFeeConfirm(String msisdn, int fee, String otp, String REQ) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("charge_fee");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("CHARGE_" + fee);
+        String mpsUrl = makeMpsUrlOtpConfirm(msisdn, mpsConfig, wsObj.getWsdl(), otp, REQ);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when charge money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String addMoney(String msisdn, int fee) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("add_money");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("ADD_" + fee);
+
+//        MpsConfigObj mpsConfig = Common.mapMpsConfig.get(actionCode);
+        String mpsUrl = makeMpsUrl(msisdn, mpsConfig, wsObj.getWsdl(), false, null);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when add money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+
+    public String addData(String msisdn, int data) {
+        // TODO add your handling code here: 
+//        Map<String, String> params = new HashMap();
+        WebserviceObject wsObj = this.getWebservice("add_data");
+//        String isdn = msisdn.substring(Common.COUNTRY_CODE.length());
+//        String keyPath = "../etc/key/" + packName + "/";
+
+        MpsConfigObj mpsConfig = Common.mapMpsConfig.get("ADD_DATA_" + data);
+
+//        MpsConfigObj mpsConfig = Common.mapMpsConfig.get(actionCode);
+        String mpsUrl = makeMpsUrl(msisdn, mpsConfig, wsObj.getWsdl(), false, null);
+
+        String value = null;
+        //
+        TransactionLog log = new TransactionLog();
+        log.setMsisdn(msisdn);
+        log.setType(3);
+        log.setRequest(mpsUrl);
+        log.setCommand(wsObj.getWsCode());
+        log.setErrorCode("000");
+        log.setChannel(wsObj.getWsdl());
+        log.setRequestTime(new Timestamp(System.currentTimeMillis()));
+        setTimeSt(System.currentTimeMillis());
+        try {
+            String response = sendMps(mpsUrl);
+            //
+            log.setResponse(response.length() >= 4000 ? response.substring(0, 3999) : response);
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+
+            logger.info("Response from MPS:" + response);
+            String data_complete_spamsms = EncryptUtil.decodeMpsResponse(response, mpsConfig.getKeyPath());
+            value = EncryptUtil.analyseCodeReturn(data_complete_spamsms);
+            logger.info("mps response value:" + value);
+            String error = value.split("\\|")[0];
+
+            log.setErrorCode(error);
+            return error;
+        } catch (Exception ex) {
+            logger.error("Error when add money via MPS", ex);
+            log.setResponse("Exception");
+            log.setResponseTime(new Timestamp(System.currentTimeMillis()));
+        } finally {
+            logTime("Time to " + wsObj.getWsCode());
+            ProcessTransLog.enqueue(log);
+        }
+        return value;
+    }
+    
+    public String extendService(String msisdn,String prizeCode , String prizeType) {
+        WebserviceObject obj = this.getWebservice("ADD_EMOLA");
+        WebserviceMsg request = new WebserviceMsg();
+        request.setMsisdn(msisdn);
+        String msgTemplate = obj.getMsgTemplate();
+        
+        msgTemplate = msgTemplate.replace("#MSISDN#", msisdn);
+        msgTemplate = msgTemplate.replace("#PRIZECODE#", prizeCode);
+        msgTemplate = msgTemplate.replace("#PRIZETYPE#", prizeType);
+        request.setRequest(msgTemplate);
+
+        WebserviceMsg response = this.send(request, obj);
+        //String original = response.getProperty("return");
+        String error = StringUtils.substringBetween(response.getResponse(), "<errorCode>", "</errorCode>");
+        if (!error.equals("0")) {
+            String content = StringUtils.substringBetween(response.getResponse(), "<content>", "</content>");
+            return error + "|" + content;
+        }
+        return error;
+    }
+//    public String extendServiceDoSpin(String msisdn) {
+//        WebserviceObject obj = this.getWebservice("Prize_winner");
+//        WebserviceMsg request = new WebserviceMsg();
+//        request.setMsisdn(msisdn);
+//        String msgTemplate = obj.getMsgTemplate();
+//        
+//        msgTemplate = msgTemplate.replace("#MSISDN#", msisdn);
+//        request.setRequest(msgTemplate);
+//
+//        WebserviceMsg response = this.send(request, obj);
+//        //String original = response.getProperty("return");
+//        String error = StringUtils.substringBetween(response.getResponse(), "<errorCode>", "</errorCode>");
+//        if (!error.equals("0")) {
+//            String content = StringUtils.substringBetween(response.getResponse(), "<content>", "</content>");
+//            return error + "|" + content;
+//        }
+//        return error;
+//    }
+    
+
+    private String sendMps(String url) throws Exception {
+        logger.info("Request to mps: " + url);
+        String strTemp = "";
+        try {
+            URL urlre_spamsms = new URL(url);
+            InputStream ips = urlre_spamsms.openStream();
+            BufferedReader br_spamsms = new BufferedReader(new InputStreamReader(ips));
+            while (null != (strTemp = br_spamsms.readLine())) {
+                if (strTemp.length() > 200) {
+                    return strTemp;
+                } else {
+                    logger.warn("abort, mps response:" + strTemp);
+                }
+            }
+        } catch (Exception ex) {
+            logger.error("Error when send charge request to MPS", ex);
+            throw ex;
+        }
+        return strTemp;
+
+    }
+
+    private String makeMpsUrl(String msisdn, MpsConfigObj mpsConfig, String wsUrl, boolean isOtpRequest, String requestId) {
+
+        Map<String, String> params = new HashMap();
+        String service = mpsConfig.getService();
+        String subService = mpsConfig.getSubService();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+        String REQ = requestId != null ? requestId : dateFormat.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+        String SESS = dateFormat.format(new Date()) + "2" + msisdn.substring(Common.COUNTRY_CODE.length());
+        String command = mpsConfig.getCommand();
+        String proCode = mpsConfig.getCpName();
+        params.put("SUB", mpsConfig.getSubService());//fix
+        params.put("REQ", REQ);//fix
+        params.put("CATE", mpsConfig.getCategory());
+        params.put("ITEM", "NULL");
+        params.put("IMEI", "NULL");
+        params.put("SUB_CP", "");
+        params.put("CONT", "BLANK");
+        params.put("PRICE", mpsConfig.getPrice());
+        params.put("MOBILE", msisdn);
+        params.put("TYPE", "MOBILE");
+        params.put("SOURCE", "CLIENT");
+
+//        logger.info("command " + mpsConfig.getCommand());
+//        logger.info("getCpName " + mpsConfig.getCpName());
+//        logger.info("getSubService " + mpsConfig.getSubService());
+//        logger.info("getCategory " + mpsConfig.getCategory());
+        if (isOtpRequest) {
+            params.put("OTP_TYPE", "0");
+        } else {
+            params.put("SESS", SESS);//fix 
+        }
+
+        String mpsUrl = EncryptUtil.makeMpsRequestUrl(proCode, service, subService, command, wsUrl, params, mpsConfig.getKeyPath());
+        return mpsUrl;
+    }
+
+    private String makeMpsUrlOtpConfirm(String msisdn, MpsConfigObj mpsConfig, String wsUrl, String otp, String REQ) {
+
+        Map<String, String> params = new HashMap();
+        String service = mpsConfig.getService();
+        String subService = mpsConfig.getSubService();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+//        String REQ = dateFormat.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+        String SESS = dateFormat.format(new Date()) + "2" + msisdn.substring(Common.COUNTRY_CODE.length());
+        String command = mpsConfig.getCommand();
+        String proCode = mpsConfig.getCpName();
+        params.put("SUB", mpsConfig.getSubService());//fix
+        params.put("REQ", REQ);//fix
+//        params.put("SESS", SESS);//fix 
+        params.put("CATE", mpsConfig.getCategory());
+        params.put("ITEM", "NULL");
+        params.put("IMEI", "NULL");
+        params.put("SUB_CP", "");
+        params.put("CONT", "BLANK");
+        params.put("PRICE", mpsConfig.getPrice());
+        params.put("MOBILE", msisdn);
+        params.put("TYPE", "MOBILE");
+        params.put("SOURCE", "CLIENT");
+        params.put("OTP", otp);
+        params.put("OTP_TYPE", "1");
+
+        String mpsUrl = EncryptUtil.makeMpsRequestUrl(proCode, service, subService, command, wsUrl, params, mpsConfig.getKeyPath());
+        return mpsUrl;
+    }
+    
+    public static String getMessageFromResult(Logger logger, String resultFromMps) {
+        logger.info("Response from MPS to convert to message:" + resultFromMps);
+        if (resultFromMps.contains("416")) {
+            return "Your OTP is wrong";
+        } else if (resultFromMps.contains("415")) {
+            return "Your OTP is not valid";
+        } else if (resultFromMps.contains("401")) {
+            return "You have not enough money to make this transaction";
+        } else if (resultFromMps.contains("408")) {
+            return "Msisdn is using service";
+        } else {
+            String[] resSeprate = resultFromMps.split("\\|");
+            return (resultFromMps.length() > 1 ? resSeprate[1] : "ERROR when charging");
+        }
+    }
+
+    public static String getErrorCodeFromResult(Logger logger, String resultFromMps) {
+        logger.info("Response from MPS to convert to error code:" + resultFromMps);
+        return resultFromMps;
+//        String[] resSeprate = resultFromMps.split("|");
+//        return (resultFromMps.length() > 0 ? resSeprate[0] : Common.ErrorCode.CHARGE_ERROR);
+    }
+}

+ 3190 - 0
KittyFallWs/KittyFallWs/src/com/vas/webservices/KittyFallWs.java

@@ -0,0 +1,3190 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.vas.webservices;
+
+import com.vas.kittyfallwsvas.wsfw.obj.PointTotalObj;
+import com.vas.kittyfallwsvas.wsfw.obj.UserInfo;
+import com.vas.kittyfallwsvas.wsfw.obj.ChargeLog;
+import com.vas.kittyfallwsvas.wsfw.obj.RankingObj;
+import com.vas.kittyfallwsvas.wsfw.obj.Request;
+import com.vas.kittyfallwsvas.wsfw.obj.ProductInfo;
+import com.vas.kittyfallwsvas.wsfw.obj.TransactionLog;
+import com.vas.kittyfallwsvas.wsfw.obj.SmsMtObj;
+import com.vas.kittyfallwsvas.wsfw.obj.AccountInfo;
+import com.vas.kittyfallwsvas.wsfw.obj.Response;
+import com.vas.kittyfallwsvas.wsfw.obj.SpinGift;
+import com.vas.kittyfallwsvas.wsfw.obj.RegisterInfo;
+import com.vas.kittyfallwsvas.wsfw.common.Common;
+import com.vas.kittyfallwsvas.wsfw.common.Encrypt;
+import com.vas.kittyfallwsvas.wsfw.common.MessageResponse;
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceAbstract;
+import com.vas.kittyfallwsvas.wsfw.common.WebserviceManager;
+import com.vas.kittyfallwsvas.wsfw.database.WsProcessUtils;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.LuckySprin;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.PrizeObj;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.PrizeWinner;
+import com.vas.kittyfallwsvas.wsfw.obj.draw.SpinResultObj;
+
+import com.vas.kittyfallwsvas.wsfw.services.WSProcessor;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.sql.Timestamp;
+import java.text.SimpleDateFormat;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.*;
+import javax.annotation.Resource;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.xml.ws.RequestWrapper;
+import javax.xml.ws.WebServiceContext;
+
+import org.apache.log4j.Logger;
+import sun.misc.BASE64Encoder;
+
+/**
+ * @author Sungroup
+ */
+@WebService
+public class KittyFallWs extends WebserviceAbstract {
+
+    public WsProcessUtils db;
+    private StringBuilder br = new StringBuilder();
+    //private Exchange exchange;
+    private SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
+    private SimpleDateFormat fullDf = new SimpleDateFormat("yyyyMMddHHmmss");
+    private SimpleDateFormat reqDf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+    public WSProcessor ws;
+    
+    @Resource
+    protected WebServiceContext ctx;
+    
+    public KittyFallWs() throws Exception {
+        super("KittyFallWs");
+        db = new WsProcessUtils("dbProcess", logger);
+        ws = new WSProcessor(logger, "../etc/webservice.cfg", "../etc/database.xml");
+        if (Common.iLoadConfig) {
+            Common.listConfig = db.getConfig("PROCESS");
+            MessageResponse.setMessage(Common.listConfig);
+            logger.info("LIST CONFIG:\n" + Common.listConfig);
+            Common.listProduct = db.iLoadPackage();
+            //Common.mapPrize = db.loadPrize();
+            Common.mapMpsConfig = db.loadMpsConfig();
+            Common.loadConfig();
+        }
+    }
+
+    //
+    // FOR MPS
+    //
+    public Response renewMps(String msisdn, ProductInfo product) {
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+        try {
+            msisdn = formatMsisdn(msisdn);
+            // after this, only one package returned
+            List<RegisterInfo> listReg = db.getRegisterNotCheckStatusInfo(msisdn, product.getProductName());
+            if (listReg == null || listReg.isEmpty()) {
+                logger.error("Renew but not registered: " + msisdn + " package: " + product.getProductName());
+//                response.setErrorCode(Common.ErrorCode.NOT_REGISTERED);
+                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                response.setContent(MessageResponse.getDefaultMessage(Common.Message.NOT_REGISTERED, logger));
+                return response;
+            }
+            // remove all package buy_code, just only packages daily
+            RegisterInfo regInfo = listReg.get(0);
+
+            ProductInfo productInfo = getProductByName(regInfo.getProductName());
+            if (productInfo == null || productInfo.getProductName() == null) {
+                logger.error("Error product info is not existed: " + regInfo.getProductName());
+                response.setErrorCode(Common.ErrorCode.SYSTEM_ERROR);
+                response.setContent(MessageResponse.getDefaultMessage(Common.Message.SYSTEM_FAIL, logger));
+                return response;
+            }
+            double fee = productInfo.getFee();
+            logger.info("Renew pending success " + msisdn + ", fee " + fee + ", account " + msisdn + ", package: " + product.getProductName());
+
+            // insert register
+            Timestamp expire = getExpireTime(productInfo);
+            regInfo.setExpireTime(expire);
+            regInfo = updateRegRenew(regInfo, productInfo);
+            db.updateRenewReg(regInfo);
+
+            //insert chargelog
+            if (fee > 0) {
+                ChargeLog chargeLog = new ChargeLog();
+                chargeLog.setFee(fee);
+                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                chargeLog.setMsisdn(msisdn);
+                chargeLog.setDescription("Renew " + regInfo.getProductName());
+                chargeLog.setStatus(Common.Constant.RENEW_STATUS);
+                db.iInsertChargeLog(chargeLog);
+            }
+//            db.addTurnSpin(msisdn,productInfo.getNumberSpin());
+            // send message
+            String message;
+            message = MessageResponse.get(Common.Message.RENEW_SUCCESS,
+                    Common.Message.RENEW_SUCCESS + "_" + regInfo.getProductName(), logger);
+            message = message.replace("%fee%", String.valueOf(fee));
+            message = message.replaceAll("%expire%", sdf.format(expire));
+//                        SmsMtObj mt = new SmsMtObj();
+//                        mt.setMsisdn(msisdn);
+//                        mt.setChannel(Common.CHANNEL);
+//                        mt.setMessage(message);
+//                        db.insertMt(mt);
+            response.setErrorCode(Common.ErrorCode.SUCCESS);
+            response.setContent(message);
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+        response.setErrorCode(Common.ErrorCode.SUCCESS);
+        return response;
+    }
+
+    public Response registerByMps(String msisdn, ProductInfo productInfo, int fee, String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+//        Timestamp reqTime = new Timestamp(System.currentTimeMillis());
+
+        try {
+            // check existed
+            AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, productInfo.getProductName());
+//            UserProfile userProfile = db.iGetUserProfileByMsisdn(msisdn);
+
+            if (accountInfo == null) {
+                logger.error("Error check exist account: " + msisdn);
+                response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
+//                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+                response.setContent(message);
+                return response;
+            }
+            List<RegisterInfo> listReg = db.getRegisterInfo(msisdn, productInfo.getProductName());
+            if (listReg != null && !listReg.isEmpty()) {
+                logger.info("Already registered: " + msisdn + " -> cancel service");
+                db.disableAutoExtend(listReg.get(0).getRegisterId());
+            }
+            List<RegisterInfo> listRegInday = null;
+            boolean registered = false;
+            listRegInday = db.getRegisterInday(msisdn, productInfo.getProductName());
+            if (listRegInday != null && listRegInday.size() > 0) {
+                registered = true;
+            }
+
+            logger.info("Register success " + msisdn + ", fee " + fee + ", account " + accountInfo.getMsisdn() + ", pack = " + productInfo.getProductName());
+
+            boolean isCreated = true;
+            // create account
+            String password = generateValidateCode(4);
+            if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                isCreated = false;
+                String encyptedPassword = Encrypt.getHashCode(msisdn, password, logger);
+                db.insertAccountUser(msisdn, password, "USSD", productInfo.getProductName());
+            }
+
+            RegisterInfo reg;
+            if (!registered) {
+                // insert register
+                logger.info("create new reg_info " + msisdn);
+                reg = new RegisterInfo();
+                reg.setMsisdn(msisdn);
+                reg.setProductName(productInfo.getProductName());
+                reg.setExpireTime(getExpireTime(productInfo));
+                reg.setServiceId(productInfo.getProductId());
+                reg.setChannel("MPS");
+                reg = updateRegRenew(reg, productInfo);
+                db.iInsertRegisterInfo(reg);
+
+            } else {
+                logger.info("register again reg_info " + msisdn);
+                reg = listRegInday.get(0);
+                reg.setExpireTime(getExpireTime(productInfo));
+                db.iInsertRegisterInfo(reg);
+            }
+
+            //insert chargelog
+            if (fee > 0) {
+                ChargeLog chargeLog = new ChargeLog();
+                chargeLog.setFee(productInfo.getFee());
+                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                chargeLog.setMsisdn(msisdn);
+                chargeLog.setDescription("Register " + productInfo.getProductName());
+                chargeLog.setStatus(Common.Constant.REGISTER_STATUS);
+                db.iInsertChargeLog(chargeLog);
+            }
+
+            // send message
+            String message = "";
+            if (!isCreated) {
+                message = MessageResponse.get(Common.Message.CREATE_ACCOUNT_SUCCESS,
+                        Common.Message.CREATE_ACCOUNT_SUCCESS, logger);
+                message = message.replaceAll("%password%", password);
+            }
+            message = MessageResponse.get(Common.Message.REGISTER_SUCCESS,
+                    Common.Message.REGISTER_SUCCESS, logger);
+//            message = message.replaceAll("%package%", productInfo.getProductName());
+            message = message.replaceAll("%fee%", String.valueOf(productInfo.getFee()));
+            message = message.replaceAll("%spin%", String.valueOf(productInfo.getNumberSpin()));
+
+            if (productInfo.getProductName().equals(Common.Constant.REGISTER_DAILY_HEALTH)) {
+                message = message.replaceAll("%command%", Common.Constant.OFF_DAILY_HEALTH);
+                message = message.replaceAll("%package%", Common.Constant.REGISTER_DAILY_HEALTH + "");
+                message = message.replaceAll("%describer%", Common.Constant.DESCRIBER_NEWS + "");
+
+            } else if (productInfo.getProductName().equals(Common.Constant.REGISTER_DAILY_LOT)) {
+                message = message.replaceAll("%command%", Common.Constant.OFF_DAILY_LOT);
+                message = message.replaceAll("%package%", Common.Constant.REGISTER_DAILY_LOT + "");
+                message = message.replaceAll("%describer%", Common.Constant.DESCRIBER_LOT + "");
+
+            } else if (productInfo.getProductName().equals(Common.Constant.REGISTER_DAILY_NEWS)) {
+                message = message.replaceAll("%command%", Common.Constant.OFF_DAILY_NEWS);
+                message = message.replaceAll("%package%", Common.Constant.REGISTER_DAILY_NEWS + "");
+                message = message.replaceAll("%describer%", Common.Constant.DESCRIBER_HEALTH + "");
+            }
+
+            response.setErrorCode(Common.ErrorCode.SUCCESS);
+            response.setContent(message);
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+        response.setErrorCode(Common.ErrorCode.SUCCESS);
+        return response;
+    }
+
+    public Response cancelServiceMps(String msisdn, ProductInfo productInfo, String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            // check existed
+            msisdn = formatMsisdn(msisdn);
+            List<RegisterInfo> listReg = db.getRegisterInfo(msisdn, productInfo.getProductName());
+            if (listReg == null) {
+                logger.error("Error check exist account: " + msisdn);
+                response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
+                response.setContent("Error database!");
+                return response;
+            } else if (listReg.isEmpty()) {
+                logger.info("Not registered: " + msisdn + " -> success");
+//                response.setErrorCode(Common.ErrorCode.ACCOUNT_NOT_REGISTERED);
+//                response.setContent("Not registered");
+                String message = MessageResponse.get(Common.Message.DESTROY_ACCOUNT_SUCCESS, logger);
+                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                response.setContent(message);
+                return response;
+            }
+            boolean res = db.disableAutoExtend(listReg.get(0).getRegisterId());
+
+            if (res) {
+                ChargeLog chargeLog = new ChargeLog();
+                chargeLog.setFee(0);
+                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                chargeLog.setMsisdn(msisdn);
+                chargeLog.setDescription("Cancel " + productInfo.getProductName());
+                chargeLog.setStatus(Common.Constant.CANCEL_STATUS);
+                db.iInsertChargeLog(chargeLog);
+                // send message
+                String message = MessageResponse.get(Common.Message.DESTROY_ACCOUNT_SUCCESS, logger);
+                response.setContent(message);
+
+                // return
+                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                logger.info("Cancel success" + msisdn + ", account " + msisdn + ", pack = " + productInfo.getProductName());
+            } else {
+                // return
+                response.setErrorCode(Common.ErrorCode.FAILURE);
+                logger.info("Cancel failure " + msisdn + ", account " + msisdn + ", pack = " + productInfo.getProductName());
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+        response.setErrorCode(Common.ErrorCode.SUCCESS);
+        return response;
+    }
+
+    
+    @WebMethod(operationName = "heartbeat")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public String heartBeat() {
+        Response response = new Response();
+        response.setErrorCode(Common.ErrorCode.SUCCESS);
+        return response.getErrorCode();
+    }
+    /*
+    @WebMethod(operationName = "subRequest")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public String subRequest(
+            @WebParam(name = "username") String wsUser,
+            @WebParam(name = "password") String wsPass,
+            @WebParam(name = "serviceid") String serviceid,
+            @WebParam(name = "msisdn") String msisdn,
+            @WebParam(name = "chargetime") String chargetime,
+            @WebParam(name = "params") String params,
+            @WebParam(name = "mode") String mode,
+            //            @WebParam(name = "subServiceName") String subServiceName,
+            @WebParam(name = "amount") String fee,
+            @WebParam(name = "transid") String transid) {
+
+        Response response = new Response();
+
+        response.setErrorCode(SUCCESS);
+        // translog
+        Timestamp reqTime = new Timestamp(System.currentTimeMillis());
+        TransactionLog transLog = new TransactionLog();
+        transLog.setTransactionId(transid);
+        transLog.setCommand(params);
+        transLog.setMsisdn(msisdn);
+        transLog.setRequestTime(reqTime);
+        transLog.setRequest(serviceid + "|" + msisdn + "|" + chargetime + "|" + params + "|" + fee);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("subRequest Params:").
+                    append("\nserviceid:").append(serviceid).
+                    append("\nmsisdn:").append(msisdn).
+                    append("\nchargetime:").append(chargetime).
+                    append("\namount:").append(fee).
+                    append("\nparams:").append(params).
+                    append("\nmode:").append(mode).
+                    append("\ntransactionId:").append(transid);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(msisdn);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (params == null || params.length() == 0) {
+                logger.info("params is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("params is null");
+            } 
+            else if (transid == null || transid.length() == 0) {
+                logger.info("params is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("transactionId is null");
+            }
+            if (!Objects.equals(mode, "REAL")) {
+                    response.setErrorCode(Common.ErrorCode.SUCCESS);
+                    return response.getErrorCode();
+            }
+            if (SUCCESS.equals(response.getErrorCode())) {
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                    return response.getErrorCode() + "|" + response.getContent();
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    ProductInfo productInfo = getProductByName(serviceid);
+                    if (productInfo == null || productInfo.getProductName() == null) {
+                        logger.info("serviceid is wrong: " + serviceid);
+                        response.setErrorCode(PARAM_NOT_VALID);
+                        response.setContent("subServiceName is wrong");
+                    } else {
+                        if (params.equals("0")) {
+                            int amount = Integer.parseInt(fee);
+                            // register
+//                        ProductInfo product = db.iLoadPackageByName(subServiceName);
+                            response = registerByMps(msisdn, productInfo, amount, "1");
+                        } else if (params.equals("1")) {
+                            // unsub
+                            response = cancelServiceMps(msisdn, productInfo, "1");
+                        } else {
+                            logger.info("Unknown params: " + params);
+                            response.setErrorCode(PARAM_NOT_VALID);
+                            response.setContent("Unknown params: " + params);
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        } finally {
+            try {
+                transLog.setErrorCode(response.getErrorCode());
+                transLog.setResponse(response.toString());
+                transLog.setResponseTime(new Timestamp(System.currentTimeMillis()));
+                db.insertTransLog1(transLog);
+            } catch (Exception ex) {
+                logger.error("Error insert log", ex);
+            } finally {
+            }
+        }
+
+        return response.getErrorCode();
+    }
+
+    @WebMethod(operationName = "receiveresult")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public String receiveresult(
+            @WebParam(name = "username") String wsUser,
+            @WebParam(name = "password") String wsPass,
+            @WebParam(name = "serviceid") String serviceid,
+            @WebParam(name = "msisdn") String msisdn,
+            @WebParam(name = "chargetime") String chargetime,
+            @WebParam(name = "params") String params,
+            @WebParam(name = "mode") String mode,
+            @WebParam(name = "amount") String fee,
+            @WebParam(name = "transid") String transid) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+        // translog
+        Timestamp reqTime = new Timestamp(System.currentTimeMillis());
+        TransactionLog transLog = new TransactionLog();
+        transLog.setTransactionId(transid);
+        transLog.setCommand(params);
+        transLog.setMsisdn(msisdn);
+        transLog.setRequestTime(reqTime);
+        transLog.setRequest(serviceid + "|" + msisdn + "|" + chargetime + "|" + params + "|" + fee);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("receiveresult Params:").
+                    append("\nmsisdn:").append(msisdn).
+                    append("\nparams:").append(params).
+                    append("\nchargetime:").append(chargetime).
+                    append("\nserviceid:").append(serviceid).
+                    append("\ntransid:").append(transid).
+                    append("\nmode:").append(mode).
+                            append("\namount:").append(fee);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(msisdn);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (params == null || params.length() == 0) {
+                logger.info("params is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("params is null");
+            } 
+            else if (fee == null || fee.length() == 0) {
+                logger.info("amount is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("amount is null");
+            } else if (transid == null || transid.length() == 0) {
+                logger.info("transactionId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("transactionId is null");
+            }
+            if (!Objects.equals(mode, "REAL")) {
+                            response.setErrorCode(Common.ErrorCode.SUCCESS);
+                            return response.getErrorCode();
+            }
+            if (SUCCESS.equals(response.getErrorCode())) {
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                    return response.getErrorCode() + "|" + response.getContent();
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    if (params.equals("0")) {
+                        ProductInfo productInfo = getProductByName(serviceid);
+                        response = renewMps(msisdn, productInfo);
+                    } else if (params.equals("1")) {
+                        logger.info("Renew fail not enough money: " + msisdn);
+                        logger.info("Unknown params: " + params);
+                        response.setErrorCode(SUCCESS);
+                        response.setContent("Unknown params: " + params);
+                    } else {
+                        logger.info("Renew fail: " + msisdn);
+                        logger.info("Unknown params: " + params);
+                        response.setErrorCode(PARAM_NOT_VALID);
+                        response.setContent("Unknown params: " + params);
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        } finally {
+            try {
+                transLog.setErrorCode(response.getErrorCode());
+                transLog.setResponse(response.toString());
+                transLog.setResponseTime(new Timestamp(System.currentTimeMillis()));
+                db.insertTransLog1(transLog);
+            } catch (Exception ex) {
+                logger.error("Error insert log", ex);
+            } finally {
+            }
+        }
+
+        return response.getErrorCode();
+    }
+    
+    */
+
+    //cho MYTEL
+    @WebMethod(operationName = "subRequest", action = "subRequest")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    @RequestWrapper(localName = "subRequest", targetNamespace = "http://contentws/xsd")
+    public String subRequest(
+            @WebParam(name = "username", targetNamespace = "http://contentws/xsd") String wsUser,
+            @WebParam(name = "password", targetNamespace = "http://contentws/xsd") String wsPass,
+            @WebParam(name = "serviceid", targetNamespace = "http://contentws/xsd") String serviceid,
+            @WebParam(name = "msisdn", targetNamespace = "http://contentws/xsd") String msisdn,
+            @WebParam(name = "chargetime", targetNamespace = "http://contentws/xsd") String chargetime,
+            @WebParam(name = "params", targetNamespace = "http://contentws/xsd") String params,
+            @WebParam(name = "mode", targetNamespace = "http://contentws/xsd") String mode,
+            @WebParam(name = "amount", targetNamespace = "http://contentws/xsd") String fee,
+            @WebParam(name = "command", targetNamespace = "http://contentws/xsd") String command) {
+
+        String content = null;
+        String transactionid = null;
+        String language = null;
+        String channel = null;
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+        // translog
+        Timestamp reqTime = new Timestamp(System.currentTimeMillis());
+        TransactionLog transLog = new TransactionLog();
+        transLog.setCommand(params);
+        transLog.setMsisdn(msisdn);
+        transLog.setRequestTime(reqTime);
+        transLog.setRequest(serviceid + "|" + msisdn + "|" + chargetime + "|" + params + "|" + fee);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("subRequest Params:").
+                    append("\nserviceid:").append(serviceid).
+                    append("\nmsisdn:").append(msisdn).
+                    append("\nchargetime:").append(chargetime).
+                    append("\namount:").append(fee).
+                    append("\nparams:").append(params).
+                    append("\ncommand:").append(command).
+                    append("\ncontent:").append(content).
+                    append("\ntransactionid:").append(transactionid).
+                    append("\nlanguage:").append(language).
+                    append("\nchannel:").append(channel);
+            logger.info(br);
+
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (params == null || params.length() == 0) {
+                logger.info("params is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("params is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                    return response.getErrorCode();
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    ProductInfo productInfo = getProductByName(serviceid);
+                    if (productInfo == null || productInfo.getProductName() == null) {
+                        logger.info("serviceid is wrong: " + serviceid);
+                        response.setErrorCode(PARAM_NOT_VALID);
+                        response.setContent("subServiceName is wrong");
+                        return response.getErrorCode();
+                    }
+                    if (params.equals("0")) {
+                        int amount = Integer.parseInt(fee);
+                        // register
+                        logger.info("Register " + serviceid + ": " + msisdn);
+                        response = registerByMps(msisdn, productInfo, amount, channel);
+                    } else if (params.equals("1")) {
+                        // unsub
+                        logger.info("Cancel " + serviceid + ": " + msisdn);
+                        response = cancelServiceMps(msisdn, productInfo,serviceid);
+                    } else {
+                        logger.info("Unknown params: " + params);
+                        response.setErrorCode(PARAM_NOT_VALID);
+                        response.setContent("Unknown params: " + params);
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        } finally {
+            try {
+                transLog.setErrorCode(response.getErrorCode());
+                transLog.setResponse(response.toString());
+                transLog.setResponseTime(new Timestamp(System.currentTimeMillis()));
+            } catch (Exception ex) {
+                logger.error("Error insert log", ex);
+            } finally {
+            }
+        }
+
+        return response.getErrorCode();
+    }
+    
+    //cho thị trường mytel
+    @WebMethod(operationName = "resultRequest", action = "resultRequest")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL, parameterStyle = SOAPBinding.ParameterStyle.WRAPPED)
+    @RequestWrapper(localName = "resultRequest", targetNamespace = "http://contentws/xsd")
+    public String resultRequest(
+            @WebParam(name = "username", targetNamespace = "http://contentws/xsd") String wsUser,
+            @WebParam(name = "password", targetNamespace = "http://contentws/xsd") String wsPass,
+            @WebParam(name = "serviceid", targetNamespace = "http://contentws/xsd") String serviceid,
+            @WebParam(name = "msisdn", targetNamespace = "http://contentws/xsd") String msisdn,
+            @WebParam(name = "chargetime", targetNamespace = "http://contentws/xsd") String chargetime,
+            @WebParam(name = "params", targetNamespace = "http://contentws/xsd") String params,
+            @WebParam(name = "mode", targetNamespace = "http://contentws/xsd") String mode,
+            @WebParam(name = "amount", targetNamespace = "http://contentws/xsd") String fee,
+            @WebParam(name = "command", targetNamespace = "http://contentws/xsd") String command,
+            @WebParam(name = "transactionid", targetNamespace = "http://contentws/xsd") String transactionId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+        // translog
+        Timestamp reqTime = new Timestamp(System.currentTimeMillis());
+        TransactionLog transLog = new TransactionLog();
+//        transLog.setTransactionId(transactionId);
+        transLog.setCommand(params);
+        transLog.setMsisdn(msisdn);
+        transLog.setRequestTime(reqTime);
+        transLog.setRequest(serviceid + "|" + msisdn + "|" + chargetime + "|" + params + "|" + fee);
+
+        try {
+            String ip = getIpClient();
+//            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("receiveresult Params:").
+                    append("\nmsisdn:").append(msisdn).
+                    append("\nparams:").append(params).
+                    append("\nchargetime:").append(chargetime).
+                    append("\nserviceid:").append(serviceid).
+                    append("\namount:").append(fee).
+                    append("\ntransactionId:").append(transactionId).
+                    append("\ncommand:").append(command).
+                    append("\nmode:").append(mode);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setMsisdn(msisdn);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (params == null || params.length() == 0) {
+                logger.info("params is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("params is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+
+                msisdn = formatMsisdn(msisdn);
+                ProductInfo productInfo = getProductByName(serviceid);
+                if (productInfo == null || productInfo.getProductName() == null) {
+                    logger.info("serviceid is wrong: " + serviceid);
+                    response.setErrorCode(PARAM_NOT_VALID);
+                    response.setContent("subServiceName is wrong");
+                    return response.getErrorCode();
+                }
+                if (params.equals("0")) {
+                    renewMps(msisdn, productInfo);
+                    // return
+                    logger.info("Renew account success: " + msisdn);
+                    response.setErrorCode(Common.ErrorCode.SUCCESS);
+                    response.setContent(Common.ResultCode.SUCCESS);
+                    return response.getErrorCode();
+
+                } else {
+                    logger.info("Renew fail: " + msisdn);
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        } finally {
+            try {
+                transLog.setErrorCode(response.getErrorCode());
+                transLog.setResponse(response.toString());
+                transLog.setResponseTime(new Timestamp(System.currentTimeMillis()));
+                if (transactionId != null) {
+
+                }
+            } catch (Exception ex) {
+                logger.error("Error insert log", ex);
+            } finally {
+            }
+        }
+
+        return response.getErrorCode();
+    }
+    
+    
+    
+    
+    
+    public void processAfterCharge(String msisdn, int fee) {
+        List<RegisterInfo> listReg = db.getRegisterInfoAll(msisdn);
+        if (listReg == null || listReg.isEmpty()) {
+            // unsub
+            int spinNum = (int) (fee / Common.SPIN_FEE);
+            // update spin_gift
+            List<SpinGift> listSg = db.getSpinGift(msisdn);
+            if (listSg != null && listSg.size() > 0) {
+                // update spin gift
+                SpinGift sg = listSg.get(0);
+                sg.setGiftMsisdn(msisdn);
+                sg.setNumberSpin(sg.getNumberSpin() + (int) spinNum);
+                db.iUpdateSpinGift(sg);
+            } else {
+                // insert new spin gift
+                SpinGift sg = new SpinGift();
+                sg.setMsisdn(msisdn);
+                sg.setGiftMsisdn(msisdn);
+                sg.setNumberSpin(spinNum);
+                db.iInsertSpinGift(sg);
+            }
+
+            String message = MessageResponse.get(Common.Message.BUY_SPIN_UNSUB_SUCCESS, logger);
+            message = message.replace("%fee%", fee + "");
+            message = message.replace("%spin%", spinNum + "");
+//            SmsMtObj mt = new SmsMtObj();
+//            mt.setMsisdn(msisdn);
+//            mt.setChannel(Common.CHANNEL);
+//            mt.setMessage(message);
+//            db.insertMt(mt);
+
+            // update ranking
+            updateRanking(msisdn, Common.SubType.UNSUB, spinNum, Common.RankType.BOUGHT, Common.PeriodPrize.WEEKLY);
+            updateRanking(msisdn, Common.SubType.UNSUB, spinNum, Common.RankType.BOUGHT, Common.PeriodPrize.MONTHLY);
+        } else {
+            // for sub
+            int spinInt = fee * Common.ADD_SPIN_TIMES / Common.ADD_SPIN_FEE;
+            // update spin
+            db.updateAddMoreTimes(listReg.get(0).getRegisterId(), spinInt);
+
+            // send message
+            String message = MessageResponse.get(Common.Message.BUY_SPIN_SUB_SUCCESS, logger);
+            message = message.replaceAll("%fee%", fee + "");
+            message = message.replaceAll("%spin%", spinInt + "");
+//            SmsMtObj mt = new SmsMtObj();
+//            mt.setMsisdn(msisdn);
+//            mt.setChannel(Common.CHANNEL);
+//            mt.setMessage(message);
+//            db.insertMt(mt);
+
+            // update ranking
+            updateRanking(msisdn, Common.SubType.SUB, spinInt, Common.RankType.BOUGHT, Common.PeriodPrize.WEEKLY);
+            updateRanking(msisdn, Common.SubType.SUB, spinInt, Common.RankType.BOUGHT, Common.PeriodPrize.MONTHLY);
+        }
+    }
+
+    //    --------- FOR REGISTER FROM WEB ---------------
+    @WebMethod(operationName = "wsRegisterSub")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsRegisterSub(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsRegisterSub Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\nMsisdn:").append(msisdn).
+                    append("\nserviceId:").append(serviceId).
+                    append("\nPackageName:").append(packageName);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    List<RegisterInfo> listRegInday = db.getRegisterInday(msisdn, packageName);
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ALREADY_REGISTER);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ALREADY_REGISTERED, logger));
+                    } else {
+                        // da dang ki (status = 1) nhung he thong chua kip gia han
+                        ProductInfo productInfo = getProductByName(packageName);
+                        String resultPaid = "0";
+                        int fee = (int) productInfo.getFee();
+                        boolean registered = false;
+                        if (!db.checkRegistered(msisdn, productInfo.getProductName())) {
+                            // new user
+                            fee = 0;
+                        } else {
+                            if (listRegInday != null && !listRegInday.isEmpty()) {
+                                fee = 0;
+                                registered = true;
+                            }
+                        }
+                        // neu khong co buoc otp thi tao them requestId ban di
+                        String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+                        logger.info("after get product info " + fee);
+                        // right -----------------------------------------------
+                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
+                        
+                        String errorCode = resultPaid.split("\\|")[0];
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            logger.info("Register success success " + msisdn + ", fee " + fee);
+                            Timestamp expireTime = getExpireTime(productInfo);
+                            // check registered
+                            RegisterInfo reg;
+                            if (!registered) {
+                                // insert register
+                                reg = new RegisterInfo();
+                                reg.setMsisdn(msisdn);
+                                reg.setProductName(productInfo.getProductName());
+                                reg.setExpireTime(expireTime);
+                                reg.setServiceId(productInfo.getProductId());
+                                reg.setChannel("WEB");
+                                reg = updateRegRenew(reg, productInfo);
+                                db.iInsertRegisterInfo(reg);
+                            } else {
+                                reg = listRegInday.get(0);
+                                db.iInsertRegisterInfo(reg);
+                            }
+
+                            //insert chargelog
+                            if (fee > 0) {
+                                ChargeLog chargeLog = new ChargeLog();
+                                chargeLog.setFee(productInfo.getFee());
+                                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                                chargeLog.setMsisdn(msisdn);
+                                chargeLog.setDescription("Register " + packageName);
+                                chargeLog.setStatus(Common.Constant.REGISTER_STATUS);
+                                db.iInsertChargeLog(chargeLog);
+                            }
+
+                            // create a new account_user for this user
+                            boolean isCreated = true;
+                            // check existed
+                            AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                            // create account
+                            String password = generateValidateCode(4);
+                            if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                                isCreated = false;
+                                String encyptedPassword = Encrypt.getHashCode(msisdn, password, logger);
+                                logger.info("Create account success " + msisdn);
+                                db.insertAccountUser(msisdn, password, "WEB", serviceId);
+                            }
+                            // send message
+                            String message = "";
+                            if (!isCreated) {
+                                message = MessageResponse.get(Common.Message.CREATE_ACCOUNT_SUCCESS, logger);
+                                message = message.replaceAll("%password%", password);
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(msisdn);
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+                            }
+
+                            // send message
+                            message = MessageResponse.get(Common.Message.REGISTER_SUCCESS,
+                                    Common.Message.REGISTER_SUCCESS, logger);
+                            message = message.replace("%fee%", productInfo.getFee() + "");
+                            message = message.replace("%spin%", productInfo.getNumberSpin() + "");
+
+                            // check user have registered in the past
+                            if (!db.checkRegisteredForTheFirstTime(msisdn, serviceId)) {
+                                response.setErrorCode(Common.ErrorCode.SUCCESS_FOR_THE_FIRST_TIME_REGISTER);
+                            } else {
+                                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                            }
+
+                            response.setContent(message);
+                        } 
+                        else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                }
+                
+            }
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+    
+    
+    @WebMethod(operationName = "wsRegisterSubOtp")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsRegisterSubOtp(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsRegisterSubOtp Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\nMsisdn:").append(msisdn).
+                    append("\nserviceId:").append(serviceId).
+                    append("\nPackageName:").append(packageName);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+//------danh cho thị trường không có otp ------------------
+                // kiem tra thong tin dang nhap
+                /*
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    List<RegisterInfo> listRegInday = db.getRegisterInday(msisdn, packageName);
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ALREADY_REGISTER);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ALREADY_REGISTERED, logger));
+                    } else {
+                        // da dang ki (status = 1) nhung he thong chua kip gia han
+                        ProductInfo productInfo = getProductByName(packageName);
+                        String resultPaid = "0";
+                        int fee = (int) productInfo.getFee();
+                        boolean registered = false;
+                        if (!db.checkRegistered(msisdn, productInfo.getProductName())) {
+                            // new user
+                            fee = 0;
+                        } else {
+                            if (listRegInday != null && !listRegInday.isEmpty()) {
+                                fee = 0;
+                                registered = true;
+                            }
+                        }
+                        // neu khong co buoc otp thi tao them requestId ban di
+                        String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+                        logger.info("after get product info " + fee);
+                        // right -----------------------------------------------
+                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
+                        
+                        String errorCode = resultPaid.split("\\|")[0];
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            logger.info("Register success success " + msisdn + ", fee " + fee);
+                            Timestamp expireTime = getExpireTime(productInfo);
+                            // check registered
+                            RegisterInfo reg;
+                            if (!registered) {
+                                // insert register
+                                reg = new RegisterInfo();
+                                reg.setMsisdn(msisdn);
+                                reg.setProductName(productInfo.getProductName());
+                                reg.setExpireTime(expireTime);
+//                                reg.setServiceId(Integer.parseInt("1"));
+                                reg.setServiceId(productInfo.getProductId());
+                                reg.setChannel("WEB");
+                                reg = updateRegRenew(reg, productInfo);
+                                db.iInsertRegisterInfo(reg);
+                            } else {
+                                reg = listRegInday.get(0);
+                                db.iInsertRegisterInfo(reg);
+                            }
+
+                            //insert chargelog
+                            if (fee > 0) {
+                                ChargeLog chargeLog = new ChargeLog();
+                                chargeLog.setFee(productInfo.getFee());
+                                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                                chargeLog.setMsisdn(msisdn);
+                                chargeLog.setDescription("Register " + packageName);
+                                chargeLog.setStatus(Common.Constant.REGISTER_STATUS);
+                                db.iInsertChargeLog(chargeLog);
+                            }
+
+                            // create a new account_user for this user
+                            boolean isCreated = true;
+                            // check existed
+                            AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                            // create account
+                            String password = generateValidateCode(4);
+                            if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                                isCreated = false;
+                                String encyptedPassword = Encrypt.getHashCode(msisdn, password, logger);
+                                logger.info("Create account success " + msisdn);
+                                db.insertAccountUser(msisdn, password, "WEB", serviceId);
+                            }
+                            // send message
+                            String message = "";
+                            if (!isCreated) {
+                                message = MessageResponse.get(Common.Message.CREATE_ACCOUNT_SUCCESS, logger);
+                                message = message.replaceAll("%password%", password);
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(msisdn);
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+                            }
+
+                            // send message
+                            message = MessageResponse.get(Common.Message.REGISTER_SUCCESS,
+                                    Common.Message.REGISTER_SUCCESS, logger);
+                            message = message.replace("%fee%", productInfo.getFee() + "");
+                            message = message.replace("%spin%", productInfo.getNumberSpin() + "");
+
+                            // check user have registered in the past
+                            if (!db.checkRegisteredForTheFirstTime(msisdn, serviceId)) {
+                                response.setErrorCode(Common.ErrorCode.SUCCESS_FOR_THE_FIRST_TIME_REGISTER);
+                            } else {
+                                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                            }
+
+                            response.setContent(message);
+                        } 
+                        else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                }
+                */
+//---------------------ket thuc danh cho natcom -------------------------------------------------
+                
+//-------------- bat dau danh cho thi truong co dung otp    ---------------------------------------           
+                 
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+//                   AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, "");
+
+                    List<RegisterInfo> listReg = db.getRegisterInday(msisdn, packageName);
+                    if (listReg != null && !listReg.isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ALREADY_REGISTER);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ALREADY_REGISTERED, logger));
+                    } else {
+                        ProductInfo productInfo = getProductByName(packageName);
+                        String resultPaid = "100";
+                        int fee = (int) productInfo.getFee();
+                        // not waiting confirm
+                        String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+                        logger.info("REQ: " + REQ);
+                        logger.info("after get product info " + fee);
+
+                        // right -----------------------------------------------
+//                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            logger.info("Create otp success " + msisdn + ", fee " + fee);
+
+                            // send message
+                            String message = MessageResponse.get(Common.Message.REGISTER_WAIT_CONFIRM + "_" + productInfo.getProductName(),
+                                    Common.Message.REGISTER_WAIT_CONFIRM, logger);
+
+                            response.setErrorCode(Common.ErrorCode.WAITING_OTP);
+                            response.setContent(message);
+                            response.setResultCode(REQ);
+                        } else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                }
+                
+// -------------Ket thuc danh cho thi truong có otp------------------
+            }
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+
+    @WebMethod(operationName = "wsRegisterSubConfirm")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsRegisterSubConfirm(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "RequestId") String requestId,
+            @WebParam(name = "Otp") String otp,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsRegisterSubConfirm Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\nMsisdn:").append(msisdn).
+                    append("\nPackageName:").append(packageName).
+                    append("\nserviceId:").append(serviceId).
+                    append("\nOtp:").append(otp);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (otp == null || otp.length() == 0) {
+                logger.info("otp is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("otp is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("otp is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    List<RegisterInfo> listRegInday = db.getRegisterInday(msisdn, packageName);
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ALREADY_REGISTER);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ALREADY_REGISTERED, logger));
+                    } else {
+                        // da dang ki (status = 1) nhung he thong chua kip gia han
+                        ProductInfo productInfo = getProductByName(packageName);
+                        String resultPaid = "0";
+                        int fee = (int) productInfo.getFee();
+                        serviceId = String.valueOf(productInfo.getProductId());
+                        boolean registered = false;
+                        if (!db.checkRegistered(msisdn, productInfo.getProductName())) {
+                            // new user
+                            fee = 0;
+                        } else {
+                            if (listRegInday != null && !listRegInday.isEmpty()) {
+                                fee = 0;
+                                registered = true;
+                            }
+                        }
+                        
+                        resultPaid = ws.registerMpsConfirm(msisdn, fee, otp, requestId, productInfo.getProductName());
+                        String errorCode = resultPaid.split("\\|")[0];
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            logger.info("Register success success " + msisdn + ", fee " + fee);
+                            Timestamp expireTime = getExpireTime(productInfo);
+                            // check registered
+                            RegisterInfo reg;
+                            if (!registered) {
+                                // insert register
+                                reg = new RegisterInfo();
+                                reg.setMsisdn(msisdn);
+                                reg.setProductName(productInfo.getProductName());
+                                reg.setExpireTime(getExpireTime(productInfo));
+                                reg.setServiceId(productInfo.getProductId());
+                                reg.setChannel("WEB");
+                                reg = updateRegRenew(reg, productInfo);
+                                db.iInsertRegisterInfo(reg);
+                            } else {
+                                reg = listRegInday.get(0);
+                                db.iInsertRegisterInfo(reg);
+                            }
+
+                            //insert chargelog
+                            if (fee > 0) {
+                                ChargeLog chargeLog = new ChargeLog();
+                                chargeLog.setFee(productInfo.getFee());
+                                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                                chargeLog.setMsisdn(msisdn);
+                                chargeLog.setDescription("Register " + packageName);
+                                chargeLog.setStatus(Common.Constant.REGISTER_STATUS);
+                                db.iInsertChargeLog(chargeLog);
+                            }
+//                            db.addTurnSpin(msisdn,productInfo.getNumberSpin());
+                            // create a new account_user for this user
+                            boolean isCreated = true;
+                            // check existed
+                            AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, productInfo.getProductName());
+                            // create account
+                            String password = generateValidateCode(4);
+                            if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                                isCreated = false;
+                                String encyptedPassword = Encrypt.getHashCode(msisdn, password, logger);
+                                logger.info("Create account success " + msisdn);
+                                db.insertAccountUser(msisdn, password, "WEB", productInfo.getProductName());
+                            }
+                            // send message
+                            String message = "";
+                            if (!isCreated) {
+                                message = MessageResponse.get(Common.Message.CREATE_ACCOUNT_SUCCESS, logger);
+//                                message = message.replace("%fee%", fee + "");
+                                message = message.replaceAll("%password%", password);
+//                                message = message.replaceAll("%expire%", sdf.format(reg.getExpireTime()));
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(msisdn);
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+                            }
+
+                            // send message
+                            message = MessageResponse.get(Common.Message.REGISTER_SUCCESS,
+                                    Common.Message.REGISTER_SUCCESS, logger);
+                            message = message.replace("%fee%", productInfo.getFee() + "");
+                            message = message.replace("%spin%", productInfo.getNumberSpin() + "");
+                            // check user have registered in the past
+                            if (!db.checkRegisteredForTheFirstTime(msisdn, serviceId)) {
+                                response.setErrorCode(Common.ErrorCode.SUCCESS_FOR_THE_FIRST_TIME_REGISTER);
+                            } else {
+                                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                            }
+
+                            response.setContent(message);
+                        }
+                        else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+
+    @WebMethod(operationName = "wsRegisterSubQuick")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsRegisterSubQuick(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "ServiceId") String serviceId) {
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsRegisterSubQuick Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\nMsisdn:").append(msisdn).
+                    append("\nserviceId:").append(serviceId).
+                    append("\nPackageName:").append(packageName);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    List<RegisterInfo> listRegInday = db.getRegisterInday(msisdn, packageName);
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ALREADY_REGISTER);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ALREADY_REGISTERED, logger));
+                    } else {
+                        // da dang ki (status = 1) nhung he thong chua kip gia han
+                        ProductInfo productInfo = getProductByName(packageName);
+                        String resultPaid = "0";
+                        int fee = (int) productInfo.getFee();
+                        boolean registered = false;
+                        if (!db.checkRegistered(msisdn, productInfo.getProductName())) {
+                            // new user
+//                            fee = 0;
+                        } else {
+                            if (listRegInday != null && !listRegInday.isEmpty()) {
+                                fee = 0;
+                                registered = true;
+                            }
+                        }
+                        // neu khong co buoc otp thi tao them requestId ban di
+                        String REQ = reqDf.format(new Date()) + productInfo.getProductId() + msisdn.substring(Common.COUNTRY_CODE.length());
+                        logger.info("after get product info " + fee);
+                        // right -----------------------------------------------
+                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
+                        
+                        String errorCode = resultPaid.split("\\|")[0];
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            logger.info("Register success success " + msisdn + ", fee " + fee);
+                            Timestamp expireTime = getExpireTime(productInfo);
+                            // check registered
+                            RegisterInfo reg;
+                            if (!registered) {
+                                // insert register
+                                reg = new RegisterInfo();
+                                reg.setMsisdn(msisdn);
+                                reg.setProductName(productInfo.getProductName());
+                                reg.setExpireTime(expireTime);
+                                reg.setServiceId(productInfo.getProductId());
+                                reg.setChannel("WEB");
+                                reg = updateRegRenew(reg, productInfo);
+                                db.iInsertRegisterInfo(reg);
+                            } else {
+                                reg = listRegInday.get(0);
+                                db.iInsertRegisterInfo(reg);
+                            }
+
+                            //insert chargelog
+                            if (fee > 0) {
+                                ChargeLog chargeLog = new ChargeLog();
+                                chargeLog.setFee(productInfo.getFee());
+                                chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                                chargeLog.setMsisdn(msisdn);
+                                chargeLog.setDescription("Register " + packageName);
+                                chargeLog.setStatus(Common.Constant.REGISTER_STATUS);
+                                db.iInsertChargeLog(chargeLog);
+                            }
+
+                            // create a new account_user for this user
+                            boolean isCreated = true;
+                            // check existed
+                            AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                            // create account
+                            String password = generateValidateCode(4);
+                            if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                                isCreated = false;
+                                String encyptedPassword = Encrypt.getHashCode(msisdn, password, logger);
+                                logger.info("Create account success " + msisdn);
+                                db.insertAccountUser(msisdn, password, "WEB", serviceId);
+                            }
+                            // send message
+                            String message = "";
+                            if (!isCreated) {
+                                message = MessageResponse.get(Common.Message.CREATE_ACCOUNT_SUCCESS, logger);
+                                message = message.replaceAll("%password%", password);
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(msisdn);
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+                            }
+                            // send message
+                            message = MessageResponse.get(Common.Message.REGISTER_SUCCESS,
+                                    Common.Message.REGISTER_SUCCESS, logger);
+                            message = message.replace("%fee%", productInfo.getFee() + "");
+                            message = message.replace("%spin%", productInfo.getNumberSpin() + "");
+
+                            // check user have registered in the past
+                            response.setErrorCode(Common.ErrorCode.SUCCESS);
+                            response.setContent(message);
+                        } 
+                        else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                    
+                    /*
+                    msisdn = formatMsisdn(msisdn);
+                    List<RegisterInfo> listRegInday = db.getRegisterInday(msisdn, packageName);
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ALREADY_REGISTER);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ALREADY_REGISTERED, logger));
+                    } else {
+                        // da dang ki (status = 1) nhung he thong chua kip gia han
+                        ProductInfo productInfo = getProductByName(packageName);
+                        String resultPaid = "0";
+                        int fee = (int) productInfo.getFee();
+                        boolean registered = false;
+                        if (!db.checkRegistered(msisdn, productInfo.getProductName())) {
+                            // new user
+                            fee = 0;
+                        } else {
+                            if (listRegInday != null && !listRegInday.isEmpty()) {
+                                fee = 0;
+                                registered = true;
+                            }
+                        }
+                        // neu khong co buoc otp thi tao them requestId ban di
+                        String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+                        logger.info("after get product info " + fee);
+                        // right -----------------------------------------------
+//                        resultPaid = ws.requestMpsOtp(msisdn, fee, REQ, productInfo.getProductName());
+                        
+                        String errorCode = resultPaid.split("\\|")[0];
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            logger.info("Register success " + msisdn + ", fee " + fee);
+
+                            // send message
+                            String message = MessageResponse.get(Common.Message.REGISTER_SUCCESS,
+                                    Common.Message.REGISTER_SUCCESS, logger);
+                            message = message.replace("%fee%", productInfo.getFee() + "");
+                            message = message.replace("%spin%", productInfo.getNumberSpin() + "");
+//
+//                            // check user have registered in the past
+//                            if (!db.checkRegisteredForTheFirstTime(msisdn, serviceId)) {
+//                                response.setErrorCode(Common.ErrorCode.SUCCESS_FOR_THE_FIRST_TIME_REGISTER);
+//                            } else {
+//                                response.setErrorCode(Common.ErrorCode.SUCCESS);
+//                            }
+                            response.setErrorCode(Common.ErrorCode.SUCCESS);
+                        } 
+                        else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                    */
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+    
+    
+    
+    @WebMethod(operationName = "wsDisableRegister")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsDisableRegister(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "msisdn") String msisdn,
+            @WebParam(name = "packName") String packName) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsDisableRegister Params:\n").
+                    append("User:").append(msisdn).
+                    append("\npackName:").append(packName);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(msisdn);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (packName == null) {
+                logger.info("packName is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("packName is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    // check existed
+                    ProductInfo productInfo = getProductByName(packName);
+                    AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn,productInfo.getProductName());
+                    if (accountInfo == null) {
+                        logger.error("Error check exist account: " + msisdn);
+                        response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
+                        response.setContent("Error database!");
+                    } else if (accountInfo.getMsisdn() == null) {
+                        logger.info("Account not existed: " + msisdn);
+
+                        String message = MessageResponse.get(Common.Message.ACCOUNT_NOT_EXISTED + "_" + packName, Common.Message.ACCOUNT_NOT_EXISTED, logger);
+                        SmsMtObj mt = new SmsMtObj();
+                        mt.setMsisdn(msisdn);
+                        mt.setChannel(Common.CHANNEL);
+                        mt.setMessage(message);
+                        db.insertMt(mt);
+
+                        response.setErrorCode(Common.ErrorCode.ACCOUNT_NOT_EXISTED);
+                        response.setContent(message);
+                    } else {
+                        String rsCancelMps = "0";
+                        // get register
+                        if (packName.equals("ALL")) {
+                            List<RegisterInfo> regInfo = db.getRegisterInfoAll(msisdn);
+                            if (regInfo == null || regInfo.isEmpty()) {
+                                String message = MessageResponse.get(Common.Message.DISABLE_NOT_REGISTER + "_" + packName, Common.Message.DISABLE_NOT_REGISTER, logger);
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(accountInfo.getMsisdn());
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+                                response.setErrorCode(Common.ErrorCode.NOT_REGISTERED);
+                                response.setContent(message);
+                            } else {
+                                for (RegisterInfo reg : regInfo) {
+                                    rsCancelMps = ws.cancelService(msisdn, reg.getProductName());
+                                    if (WSProcessor.LIST_CANCEL_SUCCESS_RES.contains(rsCancelMps)) {
+                                        db.disableAutoExtend(regInfo.get(0).getRegisterId());
+                                    }
+                                }
+                                // send message
+                                String message = MessageResponse.get(Common.Message.DISABLE_EXTEND_SUCCESS + "_" + packName, Common.Message.DISABLE_EXTEND_SUCCESS, logger);
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(accountInfo.getMsisdn());
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+
+                                // return
+                                response.setErrorCode(Common.ErrorCode.SUCCESS);
+                                response.setContent(message);
+                            }
+                        } else {
+                            List<RegisterInfo> regInfo = db.getRegisterInfo(msisdn, packName);
+                            if (regInfo == null || regInfo.isEmpty()) {
+                                String message = MessageResponse.get(Common.Message.DISABLE_NOT_REGISTER + "_" + packName, Common.Message.DISABLE_NOT_REGISTER, logger);
+                                SmsMtObj mt = new SmsMtObj();
+                                mt.setMsisdn(accountInfo.getMsisdn());
+                                mt.setChannel(Common.CHANNEL);
+                                mt.setMessage(message);
+                                db.insertMt(mt);
+
+                                response.setErrorCode(Common.ErrorCode.NOT_REGISTERED);
+                                response.setContent(message);
+                            } else {
+                                rsCancelMps = ws.cancelService(msisdn, regInfo.get(0).getProductName());
+                                if (WSProcessor.LIST_CANCEL_SUCCESS_RES.contains(rsCancelMps)) {
+                                    db.disableAutoExtend(regInfo.get(0).getRegisterId());
+
+                                    // send message
+                                    String message = MessageResponse.get(Common.Message.DISABLE_EXTEND_SUCCESS + "_" + packName, Common.Message.DISABLE_EXTEND_SUCCESS, logger);
+                                    SmsMtObj mt = new SmsMtObj();
+                                    mt.setMsisdn(accountInfo.getMsisdn());
+                                    mt.setChannel(Common.CHANNEL);
+                                    mt.setMessage(message);
+                                    db.insertMt(mt);
+
+                                    // return
+                                    response.setErrorCode(Common.ErrorCode.SUCCESS);
+                                    response.setContent(message);
+                                } else {
+                                    response.setErrorCode(Common.ErrorCode.CHARGE_ERROR);
+                                    response.setContent("Transaction failed!");
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+
+        return response;
+    }
+    
+    
+    @WebMethod(operationName = "wsGetUserServices")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsGetUserServices(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsGetUserServices Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\nmsisdn:").append(msisdn).
+                    append("\nserviceId:").append(serviceId);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // check user and password
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    List<RegisterInfo> listRegs = db.getUserServicesRenew(msisdn, serviceId);
+                    List<String> listServices = new ArrayList<>();
+                    for (int c = 0; c < listRegs.size(); c++) {
+                        logger.info(listRegs.get(c).getProductName());
+                        if (listRegs.get(c).getStatus() == 1) {
+                            listServices.add(listRegs.get(c).getProductName());
+                        }
+                    }
+                    response.setListServices(listServices);
+                    response.setErrorCode(SUCCESS);
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+        return response;
+    }
+    
+    //có cả buy turn
+    @WebMethod(operationName = "wsChargeFeeOtp")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsChargeFeeOtp(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "Fee") String fee,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsChargeFeeOtp Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\n Msisdn:").append(msisdn).
+                    append("\n serviceId:").append(serviceId).
+                    append("\n packageName:").append(packageName).
+                    append("\n Fee:").append(fee);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            } else if (packageName == null || packageName.length() == 0) {
+                logger.info("packageName is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("packageName is null");
+            } else if (fee == null || fee.length() == 0) {
+                logger.info("fee is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("fee is null");
+            }
+//------- ----------Dành cho thị trường có OTP -------------------------
+    /*
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    // check account
+                    assert msisdn != null;
+                    msisdn = formatMsisdn(msisdn);
+                    // check account
+                    AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                    // create account
+                    if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ACCOUNT_NOT_EXISTED);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ACCOUNT_NOT_EXISTED, logger));
+                    } else {
+                        int moneyCharge = Common.ADD_SPIN_FEE;
+                        if (fee != null && fee.length() > 0) {
+                            moneyCharge = Integer.parseInt(fee);
+                        }
+
+                        if (moneyCharge < 0) {
+                            response.setErrorCode(Common.ErrorCode.NOT_ENOUGH_MONEY);
+                            response.setContent("Charge fail");
+                            return response;
+                        }
+
+                        ProductInfo productInfo = getProductByName(packageName);
+                        if (productInfo == null) {
+                            response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
+                            response.setContent("Your package name is not valid");
+                            return response;
+                        }
+
+                        // waiting confirm
+                        String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+                        
+                        String resultPaid = ws.chargeFeeOtp(msisdn, moneyCharge, REQ);
+                        if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                            if (Objects.equals(resultPaid, Common.ErrorCode.WAITING_OTP)) {
+                                // confirm 2 steps
+                                logger.info("Create otp for buy turn success " + msisdn + ", fee " + moneyCharge);
+
+                                // send message
+                                String message = MessageResponse.get(Common.Message.CHARGE_WAIT_CONFIRM, logger);
+                                assert fee != null;
+                                message = message.replaceAll("%money%", fee);
+
+                                response.setErrorCode(Common.ErrorCode.WAITING_OTP);
+                                response.setContent(message);
+                                response.setResultCode(REQ);
+                            } else if (Objects.equals(resultPaid, Common.ErrorCode.SUCCESS)) {
+                                // buy turn buy one step
+
+                                boolean registered = false;
+                                List<RegisterInfo> listRegInday = null;
+                                listRegInday = db.getRegisterInday(msisdn, productInfo.getProductName());
+                                if (listRegInday != null && !listRegInday.isEmpty()) {
+                                    registered = true;
+                                }
+
+                                Timestamp expireTime = getExpireTime(productInfo);
+                                // check registered and write the next action to database
+                                RegisterInfo reg;
+                                if (!registered) {
+                                    // insert register
+                                    reg = new RegisterInfo();
+                                    reg.setMsisdn(msisdn);
+                                    reg.setProductName(productInfo.getProductName());
+                                    reg.setExpireTime(expireTime);
+                                    reg.setServiceId(Integer.parseInt(serviceId));
+                                    reg.setChannel("WEB");
+                                    reg = updateRegRenew(reg, productInfo);
+                                    db.iInsertRegisterInfo(reg);
+                                } else {
+                                    reg = listRegInday.get(0);
+                                    db.iInsertRegisterInfo(reg);
+                                }
+
+                                //insert chargelog
+                                if (moneyCharge > 0) {
+                                    ChargeLog chargeLog = new ChargeLog();
+                                    chargeLog.setFee(moneyCharge);
+                                    chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                                    chargeLog.setMsisdn(msisdn);
+                                    chargeLog.setDescription("Charge");
+                                    chargeLog.setStatus(Common.Constant.CHARGE_STATUS);
+                                    db.iInsertChargeLog(chargeLog);
+                                }
+                            }
+                        } else {
+                            response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                            response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                        }
+                    }
+                }
+
+            }
+        */
+//--------------- Kết thúc mua lượt có otp ---------------------------------------
+//--------------- Bắt đầu mua lượt không có otp ----------------------------------
+                
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    int moneyCharge = Common.ADD_SPIN_FEE;
+                    if (fee != null && fee.length() > 0) {
+                        moneyCharge = Integer.parseInt(fee);
+                    }
+                    if (moneyCharge < 0) {
+                        response.setErrorCode(Common.ErrorCode.NOT_ENOUGH_MONEY);
+                        response.setContent("Charge fail");
+                        return response;
+                    }
+                    ProductInfo productInfo = getProductByName(packageName);
+                    if (productInfo == null) {
+                        response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
+                        response.setContent("Your package name is not valid");
+                        return response;
+                    }
+                    String REQ = reqDf.format(new Date()) + "1" + msisdn.substring(Common.COUNTRY_CODE.length());
+
+                    // charge
+                  String resultPaid = ws.chargeFeeOtp(msisdn, moneyCharge, REQ);
+//                    String resultPaid = "0";
+                    boolean registered = false;
+                    List<RegisterInfo> listRegInday = null;
+                    listRegInday = db.getRegisterInday(msisdn, productInfo.getProductName());
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        registered = true;
+                    }
+
+                    if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                        Timestamp expireTime = getExpireTime(productInfo);
+                        // check registered and write the next action to database
+                        RegisterInfo reg;
+                        if (!registered) {
+                            // insert register
+                            reg = new RegisterInfo();
+                            reg.setMsisdn(msisdn);
+                            reg.setProductName(productInfo.getProductName());
+                            reg.setExpireTime(expireTime);
+                            reg.setServiceId(productInfo.getProductId());
+                            reg.setChannel("WEB");
+                            reg = updateRegRenew(reg, productInfo);
+                            db.iInsertRegisterInfo(reg);
+                        } else {
+                            reg = listRegInday.get(0);
+                            db.iInsertRegisterInfo(reg);
+                        }
+                        Boolean msisdnTool = db.getMsisdnTool(msisdn);
+
+                        //insert chargelog
+                        if (moneyCharge > 0) {
+                            ChargeLog chargeLog = new ChargeLog();
+                            chargeLog.setFee(moneyCharge);
+                            chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                            chargeLog.setMsisdn(msisdn);
+                            String mTOOL_RUN = MessageResponse.get(Common.Message.TOOL_RUN,logger);
+                            if(mTOOL_RUN.equals("START") && msisdnTool == true){
+                                chargeLog.setDescription("Charge tool " + productInfo.getProductName());
+                                chargeLog.setAccountId("1");
+                            }else{
+                                chargeLog.setDescription("Charge");
+                            }
+                            
+                            chargeLog.setStatus(Common.Constant.CHARGE_STATUS);
+                            db.iInsertChargeLog(chargeLog);
+                        }
+                        
+                        // Update Spin
+//                        db.addTurnSpin(msisdn,productInfo.getNumberSpin());
+                        logger.info("Buy turn success success " + msisdn + ", fee " + fee);
+                        
+//                        LuckySprin mLuckySprin = db.igetLuckySprin(msisdn);
+//                        if(mLuckySprin != null){
+//                          response.setRemainSpin(mLuckySprin.getAdded()- mLuckySprin.getUsed());  
+//                          response.setTotalSpin(mLuckySprin.getAdded());
+//                        }
+                        response.setMoneyDeducted(moneyCharge);
+                        response.setTotalSpinAdd(productInfo.getNumberSpin());
+                        
+                        String message = MessageResponse.get(Common.Message.CHARGE_FEE_SUCCESS, logger);
+                        message = message.replace("%fee%", String.valueOf(moneyCharge));
+                        response.setErrorCode(Common.ErrorCode.SUCCESS);
+                        response.setContent(message);
+                    } 
+                    else {
+                        response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                        response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                    }
+                }
+            }
+        
+//--------------- Kết Thúc mua lượt không có otp ----------------------------------
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+        return response;
+    }
+
+    @WebMethod(operationName = "wsChargeFeeConfirm")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsChargeFeeConfirm(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "Fee") String fee,
+            @WebParam(name = "RequestId") String requestId,
+            @WebParam(name = "Otp") String otp,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsChargeFeeConfirm Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\nMsisdn:").append(msisdn).
+                    append("\nFee:").append(fee).
+                    append("\nServiceId:").append(serviceId).
+                    append("\npackageName:").append(packageName).
+                    append("\nOtp:").append(otp);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            } else if (packageName == null || packageName.length() == 0) {
+                logger.info("packageName is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("packageName is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    int moneyCharge = Common.ADD_SPIN_FEE;
+                    if (fee != null && fee.length() > 0) {
+                        moneyCharge = Integer.parseInt(fee);
+                    }
+                    if (moneyCharge < 0) {
+                        response.setErrorCode(Common.ErrorCode.NOT_ENOUGH_MONEY);
+                        response.setContent("Charge fail");
+                        return response;
+                    }
+                    ProductInfo productInfo = getProductByName(packageName);
+                    if (productInfo == null) {
+                        response.setErrorCode(Common.ErrorCode.QUERY_ERROR);
+                        response.setContent("Your package name is not valid");
+                        return response;
+                    }
+                    // charge
+                    String resultPaid = ws.chargeFeeConfirm(msisdn, moneyCharge, otp, requestId);
+                    
+                    boolean registered = false;
+                    List<RegisterInfo> listRegInday = null;
+                    listRegInday = db.getRegisterInday(msisdn, productInfo.getProductName());
+                    if (listRegInday != null && !listRegInday.isEmpty()) {
+                        registered = true;
+                    }
+
+                    if (WSProcessor.LIST_SUCCESS_RES.contains(resultPaid)) {
+                        Timestamp expireTime = getExpireTime(productInfo);
+                        // check registered and write the next action to database
+                        RegisterInfo reg;
+                        if (!registered) {
+                            // insert register
+                            reg = new RegisterInfo();
+                            reg.setMsisdn(msisdn);
+                            reg.setProductName(productInfo.getProductName());
+                            reg.setExpireTime(expireTime);
+                            reg.setServiceId(productInfo.getProductId());
+                            reg.setChannel("WEB");
+                            reg = updateRegRenew(reg, productInfo);
+                            db.iInsertRegisterInfo(reg);
+                        } else {
+                            reg = listRegInday.get(0);
+                            db.iInsertRegisterInfo(reg);
+                        }
+
+                        //insert chargelog
+                        if (moneyCharge > 0) {
+                            ChargeLog chargeLog = new ChargeLog();
+                            chargeLog.setFee(moneyCharge);
+                            chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                            chargeLog.setMsisdn(msisdn);
+                            chargeLog.setDescription("Charge");
+                            chargeLog.setStatus(Common.Constant.CHARGE_STATUS);
+                            db.iInsertChargeLog(chargeLog);
+                        }
+                        // Update Spin
+                        db.addTurnSpin(msisdn,productInfo.getNumberSpin());
+                        logger.info("Buy turn success success " + msisdn + ", fee " + fee);
+
+                        String message = MessageResponse.get(Common.Message.CHARGE_FEE_SUCCESS, logger);
+                        message = message.replace("%fee%", String.valueOf(moneyCharge));
+                        response.setErrorCode(Common.ErrorCode.SUCCESS);
+                        response.setContent(message);
+                    } 
+                    else {
+                        response.setErrorCode(WSProcessor.getErrorCodeFromResult(logger, resultPaid));
+                        response.setContent(WSProcessor.getMessageFromResult(logger, resultPaid));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+
+        return response;
+    }
+
+    // thưởng money
+    @WebMethod(operationName = "wsAddMoney")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsAddMoney(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "Fee") String fee,
+            @WebParam(name = "ServiceId") String serviceId,
+            @WebParam(name = "top") String top,
+            @WebParam(name = "type") String type) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsAddMoney Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\n Msisdn:").append(msisdn).
+                    append("\n PackageName:").append(packageName).
+                    append("\n Msisdn:").append(msisdn).
+                    append("\n ServiceId:").append(serviceId).
+                    append("\n Fee:").append(fee).
+                    append("\n Top:").append(top).
+                    append("\n Type:").append(type);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (packageName == null || packageName.length() == 0) {
+                logger.info("packageName is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("packageName is null");
+            } else if (fee == null || fee.length() == 0) {
+                logger.info("fee is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("fee is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    // check account
+                    AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                    // create account
+                    if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ACCOUNT_NOT_EXISTED);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ACCOUNT_NOT_EXISTED, logger));
+                    } else {
+
+                        int money = Integer.parseInt(fee);
+                        ws.addMoney(msisdn, money);
+
+                        ChargeLog chargeLog = new ChargeLog();
+                        chargeLog.setFee(-money);
+                        chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                        chargeLog.setMsisdn(msisdn);
+                        chargeLog.setDescription("Exchange points to money");
+                        chargeLog.setStatus(Common.Constant.UNCHARGE_STATUS);
+                        db.iInsertChargeLog(chargeLog);
+
+                        response.setErrorCode(Common.ErrorCode.SUCCESS);
+                        String message = "";
+                        if("DAILY".equals(type)){
+                            message = MessageResponse.get(Common.Message.EXCHANGE_SUCCESS_DAILY, logger);
+                            logger.info("message DAILY:"+message);
+
+                        }else if("WEEKLY".equals(type) ){
+                            message = MessageResponse.get(Common.Message.EXCHANGE_SUCCESS_WEEKLY, logger);
+                            logger.info("message WEEKLY:"+message);
+
+                        }else if("MONTHLY".equals(type)){
+                           message = MessageResponse.get(Common.Message.EXCHANGE_SUCCESS_MONTHLY, logger);
+                           logger.info("message MONTHLY:"+message);
+                        }else{
+                           message = MessageResponse.get(Common.Message.EXCHANGE_SUCCESS, logger);
+                           logger.info("message EXCHANGE_SUCCESS:"+message);
+                        }
+                        message = message.replaceAll("%money%", money + "");
+                        message = message.replaceAll("%top%", top + "");
+                        message = message.replaceAll("%type%", type + "");
+
+                        response.setContent(message);
+
+                        SmsMtObj mt = new SmsMtObj();
+                        mt.setMsisdn(msisdn);
+                        mt.setChannel(Common.CHANNEL);
+                        mt.setMessage(message);
+                        db.insertMt(mt);
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+    
+    // thưởng qua ví
+    @WebMethod(operationName = "wsAddEmola")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsAddEmola(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PrizeCode") String PrizeCode,
+            @WebParam(name = "PrizeType") String PrizeType,
+            @WebParam(name = "ServiceId") String serviceId,
+            @WebParam(name = "top") String top) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsAddEmola Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\n Msisdn:").append(msisdn).
+                    append("\n PrizeCode:").append(PrizeCode).
+                    append("\n PrizeType:").append(PrizeType).
+                    append("\n Top:").append(top);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (PrizeCode == null || PrizeCode.length() == 0) {
+                logger.info("PrizeCode is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("PrizeCode is null");
+            } else if (PrizeType == null || PrizeType.length() == 0) {
+                logger.info("PrizeType is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("PrizeType is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    // check account
+                    AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                    if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                        accountInfo = db.iGetAccountByMsisdn(msisdn, "MINHA_VIBE_MR_DAY");
+                    }
+                    // create account
+                    if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ACCOUNT_NOT_EXISTED);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ACCOUNT_NOT_EXISTED, logger));
+                    } else {
+                        PrizeObj mListPrize = db.igetListPrizeByActionType(top);
+                        String errorCode =  ws.extendService(msisdn,PrizeCode,PrizeType);
+                        if(SUCCESS.equals(errorCode)){
+                            ChargeLog chargeLog = new ChargeLog();
+                            chargeLog.setFee(-mListPrize.getValuePrize());
+                            chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                            chargeLog.setMsisdn(msisdn);
+                            chargeLog.setDescription("Exchange Emola");
+                            chargeLog.setStatus(Common.Constant.UNCHARGE_STATUS);
+                            db.iInsertChargeLog(chargeLog);
+                            
+                            response.setErrorCode(Common.ErrorCode.SUCCESS);
+                            String message = MessageResponse.get(Common.Message.EXCHANGE_SUCCESS_EMOLA, logger);
+                            logger.info("message EXCHANGE_SUCCESS_wsAddEmola:"+message);
+                            message = message.replaceAll("%money%", mListPrize.getValuePrize() + "");
+                            message = message.replaceAll("%top%", top + "");
+
+                            response.setContent(message);
+
+                            SmsMtObj mt = new SmsMtObj();
+                            mt.setMsisdn(msisdn);
+                            mt.setChannel(Common.CHANNEL);
+                            mt.setMessage(message);
+                            db.insertMt(mt);
+                        }else{
+                            response.setErrorCode(errorCode);
+                            String[] resSeprate = errorCode.split("\\|");
+                            response.setContent(errorCode.length() > 1 ? resSeprate[1] : "ERROR when charging");
+                        }
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing wsAddEmola", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+
+    // thưởng data
+    @WebMethod(operationName = "wsAddData")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsAddData(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PackageName") String packageName,
+            @WebParam(name = "data") String data,
+            @WebParam(name = "ServiceId") String serviceId) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsAddData Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\n Msisdn:").append(msisdn).
+                    append("\n PackageName:").append(packageName).
+                    append("\n Msisdn:").append(msisdn).
+                    append("\n ServiceId:").append(serviceId).
+                    append("\n data:").append(data);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            } else if (packageName == null || packageName.length() == 0) {
+                logger.info("packageName is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("packageName is null");
+            } else if (data == null || data.length() == 0) {
+                logger.info("data is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("fee is null");
+            } else if (serviceId == null || serviceId.length() == 0) {
+                logger.info("serviceId is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("serviceId is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    // check account
+                    AccountInfo accountInfo = db.iGetAccountByMsisdn(msisdn, serviceId);
+                    // create account
+                    if (accountInfo.getMsisdn() == null || accountInfo.getMsisdn().isEmpty()) {
+                        response.setErrorCode(Common.ErrorCode.ACCOUNT_NOT_EXISTED);
+                        response.setContent(MessageResponse.getDefaultMessage(Common.Message.ACCOUNT_NOT_EXISTED, logger));
+                    } else {
+
+                        int dataConvert = Integer.parseInt(data);
+                        ws.addData(msisdn, dataConvert);
+
+                        ChargeLog chargeLog = new ChargeLog();
+                        chargeLog.setFee(-dataConvert);
+                        chargeLog.setChargeTime(new Timestamp(System.currentTimeMillis()));
+                        chargeLog.setMsisdn(msisdn);
+                        chargeLog.setDescription("Exchange points to data");
+                        chargeLog.setStatus(Common.Constant.UNCHARGE_STATUS);
+                        db.iInsertChargeLog(chargeLog);
+
+                        response.setErrorCode(Common.ErrorCode.SUCCESS);
+                        String message = MessageResponse.get(Common.Message.EXCHANGE_SUCCESS, logger);
+//                        message = message.replaceAll("%point%", point + "");
+                        message = message.replaceAll("%money%", dataConvert + "");
+                        response.setContent(message);
+
+                        SmsMtObj mt = new SmsMtObj();
+                        mt.setMsisdn(msisdn);
+                        mt.setChannel(Common.CHANNEL);
+                        mt.setMessage(message);
+                        db.insertMt(mt);
+                    }
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+    
+    
+    
+
+    //     ------------------------- END ----------------------
+    
+        // GET PRIZE
+    @WebMethod(operationName = "wsDoSpin")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsDoSpin(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "Channel") String channel) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsDoSpin Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\n Msisdn:").append(msisdn);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    // update spin
+                    SpinResultObj resultSpin = db.doSpin(msisdn); 
+                    
+                    if (resultSpin == null) {
+                        response.setErrorCode(Common.ErrorCode.DB_ERROR);
+                        String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+                        response.setContent(message);
+                        return response;
+                    }
+                    // check prize
+                    response.setSpinResult(resultSpin);
+                    response.setErrorCode(Common.ErrorCode.SUCCESS);
+                    return response;
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+    
+    @WebMethod(operationName = "wsDoSpinT")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsDoSpinT(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "Msisdn") String msisdn,
+            @WebParam(name = "PrizeID") String prizeID,
+            @WebParam(name = "PrizeWinnerID") String prizeWinnerID,
+            @WebParam(name = "PartnerTransId") String partnerTransId,
+            @WebParam(name = "TransId") String transId,
+            @WebParam(name = "Channel") String channel) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsDoSpin Params:\n").
+                    append("WsUser:").append(wsUser).
+                    append("\n Msisdn:").append(msisdn);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            } else if (msisdn == null || msisdn.length() == 0) {
+                logger.info("msisdn is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("msisdn is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+                    msisdn = formatMsisdn(msisdn);
+                    // update spin
+                    SpinResultObj resultSpin = null;
+                    String mTOOL_RUN = MessageResponse.get(Common.Message.TOOL_RUN,logger);
+                    if(mTOOL_RUN.equals("START")){
+                        if (prizeID != null && !prizeID.isEmpty()
+                                && prizeWinnerID != null && !prizeWinnerID.isEmpty() ) {
+                            
+                            resultSpin = db.doSpinSubmitPrize(
+                                msisdn,
+                                Integer.parseInt(prizeID)  ,
+                                Integer.parseInt(prizeWinnerID) ,
+                                !transId.isEmpty() ? transId : "0"
+                            );
+                        } else {
+                            resultSpin = db.doSpinT(
+                                msisdn,
+                                (!prizeID.isEmpty() ? Integer.parseInt(prizeID) : 0),
+                                partnerTransId
+                            );
+                        }
+
+                    }else{
+                        if (prizeID != null && !prizeID.isEmpty()
+                                && prizeWinnerID != null && !prizeWinnerID.isEmpty()
+                                && transId != null && !transId.isEmpty()) {
+                            
+                            resultSpin = db.doSpinSubmitPrize(
+                                msisdn,
+                                !prizeID.isEmpty() ? Integer.parseInt(prizeID) : 0,
+                                !prizeWinnerID.isEmpty() ? Integer.parseInt(prizeWinnerID) : 0,
+                                !transId.isEmpty() ? transId : "0"
+                            );
+                        } else {
+                            resultSpin = db.doSpinT(
+                                msisdn,
+                                (!prizeID.isEmpty() ? Integer.parseInt(prizeID) : 0),
+                                partnerTransId
+                            );
+                        }
+                    }
+                    if (resultSpin == null) {
+                        response.setErrorCode(Common.ErrorCode.DB_ERROR);
+                        String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+                        response.setContent(message);
+                        return response;
+                    }
+                    // check prize
+                    response.setSpinResult(resultSpin);
+                    response.setErrorCode(Common.ErrorCode.SUCCESS);
+                    return response;
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            String message = MessageResponse.get(Common.Message.SYSTEM_FAIL, logger);
+            response.setContent(message);
+        }
+
+        return response;
+    }
+    
+    
+
+    @WebMethod(operationName = "wsLoadPrize")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsLoadPrize(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsLoadPrize:");
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            }
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                } else {
+//                    String lang = (String) ctx.getMessageContext().get("lang");
+                    response.setErrorCode(Common.ResultCode.SUCCESS);
+                    response.setListPrize(new ArrayList(Common.mapPrize.values()));
+                }
+            }
+
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+
+        return response;
+    }
+
+    @WebMethod(operationName = "wsGetListWinner")
+    @SOAPBinding(style = SOAPBinding.Style.DOCUMENT, use = SOAPBinding.Use.LITERAL)
+    public Response wsGetListWinner(
+            @WebParam(name = "WsUser") String wsUser,
+            @WebParam(name = "WsPass") String wsPass,
+            @WebParam(name = "msisdn") String msisdn,
+            @WebParam(name = "period") String period,
+            @WebParam(name = "page") String page,
+            @WebParam(name = "pageSize") String pageSize,
+            @WebParam(name = "isTop") String isTop,
+            @WebParam(name = "codeType") String codeType,
+            @WebParam(name = "startDate") String startDate,
+            @WebParam(name = "endDate") String endDate) {
+
+        Response response = new Response();
+        response.setErrorCode(SUCCESS);
+//        Timestamp reqTime = new Timestamp(System.currentTimeMillis());
+
+        try {
+            String ip = getIpClient();
+            UserInfo userInfo = null;
+            br.setLength(0);
+            br.append("wsGetListWinner Params:\n").
+                    append(", period:").append(period).
+                    append(", page:").append(page).
+                    append(", codeType:").append(codeType).
+                    append(", isTop:").append(isTop);
+            logger.info(br);
+
+            Request request = new Request();
+            request.setUser(wsUser);
+//            request.setPass(password);
+            if (wsUser == null || wsUser.length() == 0) {
+                logger.info("wsUser is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsUser is null");
+            } else if (wsPass == null || wsPass.length() == 0) {
+                logger.info("wsPass is null");
+                response.setErrorCode(PARAM_NOT_ENOUGH);
+                response.setContent("wsPass is null");
+            }
+
+            if (SUCCESS.equals(response.getErrorCode())) {
+                // kiem tra thong tin dang nhap
+                userInfo = authenticate(wsUser, wsPass, ip);
+                if (userInfo == null || userInfo.getWsUserId() <= 0) {
+                    response.setErrorCode(WRONG_PASSWORD);
+                    response.setContent("Authenticate fail!");
+                    return response;
+                } else {
+                    String lang = getLang();
+                    // get list code
+                    if (page == null) {
+                        page = "1";
+                    }
+                    int top = -1;
+                    int codeTypeInt = 0;
+                    if (isTop != null && !isTop.isEmpty()) {
+                        top = Integer.parseInt(isTop);
+                    }
+                    if (codeType != null && !codeType.isEmpty()) {
+                        codeTypeInt = Integer.parseInt(codeType);
+                    }
+                    
+                    DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
+                    // Định dạng đầu ra KHÔNG CÓ .0
+                    DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+                    // Chuyển startDate -> "2025-07-24 00:00:00"
+                    LocalDate start = LocalDate.parse(startDate, inputFormatter);
+                    String startDate1 = outputFormatter.format(start.atStartOfDay());
+                    // Chuyển endDate -> "2025-07-25 23:59:59"
+                    LocalDate end = LocalDate.parse(endDate, inputFormatter);
+                    LocalDateTime endDateTime = end.atTime(23, 59, 59);
+                    String endDate1 = outputFormatter.format(endDateTime);
+                    
+                    List<PrizeWinner> listWinner = db.getListWinner(msisdn, Integer.parseInt(period), Integer.parseInt(page), Integer.parseInt(pageSize), top, codeTypeInt,startDate1,endDate1);
+                    response.setListWinner(listWinner);
+                    int totalWinner = db.getCountWinner(msisdn, Integer.parseInt(period), top, codeTypeInt,startDate1,endDate1);
+
+                    int totalPages = (int) Math.ceil((double) totalWinner / Double.parseDouble(pageSize));
+                    response.setTotalPage(String.valueOf(totalPages));
+                    response.setErrorCode(Common.ErrorCode.SUCCESS);
+                    return response;
+
+                }
+            }
+        } catch (Exception e) {
+            logger.error("Error processing", e);
+            response.setErrorCode(EXCEPTION);
+            response.setContent("Transaction fail");
+        }
+
+        return response;
+    }
+
+    protected String getLang() {
+        try {
+            Map<String, List> headers = (Map<String, List>) ctx.getMessageContext().get("javax.xml.ws.http.request.headers");
+            String lang = (String) headers.get("Lang").get(0);
+            if (lang == null) {
+                lang = Common.Lang.local;
+            }
+            return lang;
+        } catch (Exception ex) {
+            return Common.Lang.local;
+        }
+    }
+    
+    public RegisterInfo updateRegRenew(RegisterInfo reg, ProductInfo productInfo) {
+        reg.setNumberSpin(productInfo.getNumberSpin());
+        reg.setExtendStatus(0);
+        reg.setPlayedTimes(0);
+        reg.setRenew(productInfo.getRenew());
+        reg.setStatus(1);
+        return reg;
+    }
+
+    private String generateValidateCode(int length) {
+        String output = "";
+        String input = "1234567890";
+        Random rnd = new Random();
+        for (int i = 0; i < length; i++) {
+            output = output + input.charAt(rnd.nextInt(input.length()));
+        }
+        return output;
+    }
+
+    private String formatMsisdn(String msisdn) {
+        if (msisdn.startsWith(WebserviceManager.countryCode)) {
+            return msisdn;
+        } else if (msisdn.startsWith("0")) {
+            return WebserviceManager.countryCode + msisdn.substring(1);
+        }
+        return WebserviceManager.countryCode + msisdn;
+    }
+
+    private void updateRanking(String msisdn, int subType, int count, int rankType, int period) {
+        List<RankingObj> listRank = db.getRankObj(msisdn, rankType, period);
+        if (listRank != null && listRank.size() > 0) {
+            // update
+            db.iUpdateRanking(listRank.get(0).getId(), subType, count);
+        } else {
+            // insert
+            Calendar currentTime = Calendar.getInstance();
+            Calendar endTime = Calendar.getInstance();
+            endTime.set(Calendar.HOUR_OF_DAY, 20);
+            endTime.set(Calendar.MINUTE, 0);
+            endTime.set(Calendar.SECOND, 0);
+            endTime.set(Calendar.MILLISECOND, 0);
+
+            if (currentTime.after(endTime)) {
+                endTime.add(Calendar.DAY_OF_MONTH, 1);
+            }
+
+            Calendar startTime = Calendar.getInstance();
+            startTime.setTimeInMillis(endTime.getTimeInMillis() - 86400000L + 1000);
+
+            RankingObj ranking = new RankingObj();
+            ranking.setMsisdn(msisdn);
+            ranking.setSpintCount(count);
+            ranking.setStartTime(new Timestamp(startTime.getTimeInMillis()));
+            ranking.setEndTime(new Timestamp(endTime.getTimeInMillis()));
+            ranking.setSubType(subType);
+            ranking.setRankType(rankType);
+
+            if (period == Common.PeriodPrize.DAILY) {
+                db.iInsertRanking(ranking);
+            } else if (period == Common.PeriodPrize.WEEKLY) {
+                db.iInsertRankingWeekly(ranking);
+            }
+            if (period == Common.PeriodPrize.MONTHLY) {
+                db.iInsertRankingMonth(ranking);
+            }
+        }
+    }
+
+    private PointTotalObj updatePoint(String msisdn, int point, int type) {
+        List<PointTotalObj> listPoint = db.getPointTotal(msisdn);
+        if (listPoint != null && listPoint.size() > 0) {
+            PointTotalObj newPoint = listPoint.get(0);
+            // update
+            logger.info("Update point: id " + newPoint.getId() + ", msisdn " + msisdn + ", point " + point);
+            if (type == 1) {
+                // add
+                newPoint.setAddedPoint(point);
+                db.iUpdatePointTotal(newPoint.getId(), point);
+                newPoint.setPoint(newPoint.getPoint() + point);
+            } else if (type == 2) {
+                // multiple
+                newPoint.setAddedPoint(newPoint.getPoint() * (point - 1));
+                db.iUpdatePointTotal(newPoint.getId(), newPoint.getPoint() * (point - 1));
+                newPoint.setPoint(newPoint.getPoint() * point);
+            }
+            return newPoint;
+        } else {
+            // insert
+            PointTotalObj pointObj = new PointTotalObj();
+            pointObj.setMsisdn(msisdn);
+            if (type == 1) {
+                // added
+                pointObj.setAddedPoint(point);
+                pointObj.setPoint(point);
+            } else {
+                // multiple
+                pointObj.setAddedPoint(0);
+                pointObj.setPoint(0);
+            }
+            pointObj.setSubType(0);
+            db.iInsertPointTotal(pointObj);
+            return pointObj;
+        }
+    }
+
+    private ProductInfo getProductByName(String packName) {
+        //logger.info(Common.listProduct);
+        for (ProductInfo product : Common.listProduct) {
+            //logger.info(product.getProductName());
+            //logger.info("fee " + product.getFee());
+//            logger.info("packName: " + packName);
+            if (product.getProductName().equalsIgnoreCase(packName)) {
+                return product;
+            }
+        }
+        return null;
+    }
+
+    private Timestamp getExpireTime(ProductInfo productInfo) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, 23);
+        cal.set(Calendar.MINUTE, 59);
+        cal.set(Calendar.SECOND, 59);
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.add(Calendar.DAY_OF_MONTH, productInfo.getExpireDays() - 1);
+        return new Timestamp(cal.getTimeInMillis());
+    }
+
+    protected Timestamp getExpireTimeInDay(int numDay) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, 23);
+        cal.set(Calendar.MINUTE, 59);
+        cal.set(Calendar.SECOND, 59);
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.add(Calendar.DAY_OF_MONTH, numDay - 1);
+        return new Timestamp(cal.getTimeInMillis());
+    }
+
+    protected Timestamp getExactTimeInDay(int second, int minute, int hour) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, hour);
+        cal.set(Calendar.MINUTE, minute);
+        cal.set(Calendar.SECOND, second);
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.add(Calendar.DAY_OF_MONTH, 0);
+        return new Timestamp(cal.getTimeInMillis());
+    }
+
+    protected Timestamp getExactTimeInDay(int second, int minute, int hour, int numday) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, hour);
+        cal.set(Calendar.MINUTE, minute);
+        cal.set(Calendar.SECOND, second);
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.add(Calendar.DAY_OF_MONTH, numday);
+        return new Timestamp(cal.getTimeInMillis());
+    }
+
+    private Timestamp getTruncSysdate() {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.HOUR_OF_DAY, 0);
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+        return new Timestamp(cal.getTimeInMillis());
+    }
+
+    private String getHashCode(String securityCode, String salt, Logger logger) {
+        MessageDigest md = null;
+        try {
+            String seq = salt + securityCode;
+            md = MessageDigest.getInstance("SHA-256"); //step 2
+            md.update(seq.getBytes("UTF-8")); //step 3
+        } catch (Exception ex) {
+            logger.error(ex.toString(), ex);
+        }
+        byte raw[] = md.digest(); //step 4
+        String hash = (new BASE64Encoder()).encode(raw); //step 5
+        return hash;
+    }
+
+    public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException {
+//        MessageDigest md = null;
+//        String seq = "123456a@" + "32323232";
+//        md = MessageDigest.getInstance("SHA-256"); //step 2
+//        md.update(seq.getBytes("UTF-8")); //step 3
+
+//        byte raw[] = md.digest(); //step 4
+//        String hash = (new BASE64Encoder()).encode(raw); //step 5
+//        System.out.println("hash" + hash);
+//        String pass = "1QAaz@123@";
+//        Pattern pattern = Pattern.compile("abcdefghijklmnopqrstuvwxyz");
+        //boolean match = list.matches(".");
+//        System.out.println("hash " + pass.matches(".*[A-Z].*"));
+//        String output = "";
+//        String input = "1234567890";
+//        Random rnd = new Random();
+//        for (int i = 0; i < 8; i++) {
+//            output = output + input.charAt(rnd.nextInt(input.length()));
+//        }
+//        System.out.println("output = " + output);
+//        double x = 1.1;
+//        System.out.println("output = " + (((x * 3 / 2) * 100) / 100));
+//        System.out.println("output = " + (x * 3 / 2));
+//        int point = Integer.parseInt("116000.0");
+//        int money = point / 10;
+//        System.out.println("Poinnt " + point + ", money: " + money);
+    }
+
+    @Override
+    public UserInfo authenticate(String userName, String password, String ipAddress) {
+        // validate thong tin user
+        // validate thong tin user
+        UserInfo userInfo = db.iGetUser(userName);
+        if (userInfo == null || userInfo.getWsUserId() <= 0) {
+            logger.info("User not existed: " + userName);
+            userInfo = new UserInfo();
+            userInfo.setWsUserId(-1);
+            return userInfo;
+        }
+
+        if (userInfo.getIp() != null && userInfo.getIp().length() > 0) {
+            // Check IP
+            String ip[] = userInfo.getIp().split(",");
+            boolean pass = false;
+            for (String ipConfig : ip) {
+                if (pair(ipAddress, ipConfig.trim())) {
+                    pass = true;
+                    break;
+                }
+            }
+            if (!pass) {
+                logger.info("IP address not allowed: " + ipAddress);
+                userInfo.setWsUserId(-2);
+                return userInfo;
+            }
+        }
+        // Check password
+        if (userInfo.getPass() != null && userInfo.getPass().trim().length() > 0) {
+            if (password.equals(userInfo.getPass())) {
+                return userInfo;
+            }
+
+            String passEncript = "";
+            passEncript = Encrypt.getHashCode(userName, password, logger);
+            if (passEncript.equals(userInfo.getPass())) {
+                return userInfo;
+            }
+            logger.info("Password incorrect: user=" + userName);
+            userInfo.setWsUserId(-3);
+            return userInfo;
+        }
+        return null;//tam fix
+    }
+}

+ 19 - 0
KittyFallWs/etc/app.conf

@@ -0,0 +1,19 @@
+##################################################
+# Application name, ma ung dung trong CONFIG
+APP_ID=WsUnews
+
+# Enable Exchange 
+EXCHANGE_ENABLE=false
+ 
+#
+COUNTRY_CODE=95
+
+LOG_TO_DATABASE=true
+
+#database path
+LOG_DATABASE_CONF=../etc/database.xml
+
+#if true, config database id to insert log
+#LOG_TO_DATABASE_ID=dbProcess
+LOG_TO_DATABASE_ID=dbProcess
+NUM_THREAD_LOG_TRANS = 1

+ 34 - 0
KittyFallWs/etc/database.xml

@@ -0,0 +1,34 @@
+<c3p0-config>
+  <timeout-config>
+  	<!-- time out query DB (s) -->
+  	<property name="queryDbTimeout">60</property>
+  	<!-- thoi gian toi da khi thuc hien ham DB (ms) -->
+  	<property name="timeBreak">90000</property>
+  	<!-- thoi gian toi da khi thuc hien xoa record time out (ms) -->
+  	<property name="timeBreakDeleteRecordTimeOut">120000</property>
+  </timeout-config>
+  <named-config name="dbProcess">
+	<property name="driver">oracle.jdbc.driver.OracleDriver</property>
+	
+<property name="connection">jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=yes)(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1539))(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1539))
+(CONNECT_DATA=(FAILOVER_MODE=(TYPE=select)(METHOD=basic)(RETRIES=180)(DELAY=5))(SERVICE_NAME=ORA12C)))</property> 
+<property name="username">Kitty_Fall</property>
+	<property name="password">123456</property>
+	<!-- <property name="connection">jdbc:oracle:thin:@(DESCRIPTION=(LOAD_BALANCE=yes)(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521))
+(CONNECT_DATA=(FAILOVER_MODE=(TYPE=select)(METHOD=basic)(RETRIES=180)(DELAY=5))(SERVICE_NAME=vascp)))</property>
+	<property name="username">hobby_hub</property>
+	<property name="password">M90$hsd4575</property> -->
+
+    <property name="initialPoolSize">5</property>   
+	<property name="maxPoolSize">30</property>
+	<property name="minPoolSize">10</property>
+	<!-- cau hinh timeout & check ket noi-->
+	<property name="readTimeout">120000</property><!-- milisecond-->
+	<property name="maxIdleTime">300</property><!-- second-->
+	<property name="checkoutTimeout">60000</property> <!-- milisecond-->
+	<property name="idleConnectionTestPeriod">30</property><!-- second-->
+	<property name="preferredTestQuery">select 1 from dual</property>
+	<property name="testConnectionOnCheckin">true</property>
+	<property name="testConnectionOnCheckout">true</property>
+  </named-config> 
+</c3p0-config>

+ 1 - 0
KittyFallWs/etc/database.xml.ept

@@ -0,0 +1 @@
+IsEnCrypted=false

+ 51 - 0
KittyFallWs/etc/key/MYJOB_DAILY/PrivateKeyCP.pem

@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAksq8Pw1FPQq4p6ypuBZDrKywDqLK3uAKB8smD/tTpGtL6zpV
+S/WZQf/uyNoL8vIwhLTMqcat8HkOC+L4ZHWc7wnBwQeYzk3BskPMVluEy9+VCdpU
+F1nYGOQgiMjwRmV5G93nKHiVJM/du/y3/p3AMTOx5Nuy3HSA5mHGCX3MwLUxzpic
+WB42FVi+JZlCBMLueaPMqSChnrGxaXDrmxtOcoIOU4GLAwM37cxvO8AVuQkfMRFU
+Kk/DqPTlRdbeO2B2JHLhGpJdXTwAo+Gn/SHMb/JIPjQfoJlnpxJ4r6nPQFvTXDnM
+lyYl3uZPygJWm7v/mD/C0bVfPIKxbzIujC4dQsIXS31O7zlnXCc5G/6TkjdOgw+y
+qYX2kT3qV+12Si4PudIyPuXFjbaIPLcJ1TAcLaK0a1YS9ZDkwPzKl2RwlHIYi1ar
+1lWE66nnjlBwze3AyW0L1JxVkWer3QmxD85uLIYIhBoj16mRFcsVrUJ1plcoXKAO
+ATjlH9UIDP3xcoT4peG+9bFFlgGTo3/8Q4mThslmWz3unst4GyUvJl7Ooojyidgy
+iaamJvygB4WT6jYYv1nG8jW7OHTjaFZLc95rbhGwDlVJzEJ6Bw++UcqgGN6mQi+8
+CBqOD0i/COwtgzHA/U8mjrfCeIS6H0adT6Hv91ZMdb+4TIlAeZLTl0me1AcCAwEA
+AQKCAgAZSRTeI5IOrr8aGvLtQ+CKaQC2tLIPbDYuG39F93vz8YuVTGoO+JJavRRL
+wsuWIMPcyCwM/q1No/yYbZNt8piC0IJwlrdqqhg4dddH9OHOIIhStyoPD6nat8km
+5r4E0kvnUfUUkpjWS3wdeq3TDSdjEk2NZ47KzMK7bJIpZmMTuuKGfOFJiIK2cJ/o
+aBroKQ/dIisJ4xYT+PXffNUI1c5QiTigh8sDTNWgf7uVZkQXqIuX7y05UJ4ah3zK
+5/VF8xrGsoc2BYpRmhleIWvHfb/ydKCfHmloR6SEMflaAP0zT937n/UvACI74B5U
+ZMy4bMzdU/ZiG0T5bmXUCqfb+8GMUFhwL4HdlRESdb+QCm7ZAGb8P9ebkrOfSibf
+axUADldEt0A+7luC+VDCgrJA0djwIsdky9kBcGBwL3djk/okeRp+xeGTNz9iKs0y
+hQktJnuYXMAoIJYW2urvv+2/OoTw3kB3NRpvcLTyha90lxK79oFmTH/N9GOmRdsc
+nnYABccXMAYENgjmHJnb1MHpTZgXfAVei2WU4q+1pdbuyAx0lsaQsBJ/k/ojBG8q
+gRdXzX0qZKDTYA/Ar/Ue100La7X475OJmsWquXhIdyym7QnkKX57HxT7WjOYmPDg
+5xacMtg9dkmdyJc6R0IgkONjUwqdhwqkIdesUy4QygZmCaMMqQKCAQEA0Xfd+Jvk
+Oxf7okgv28zknYO1d6myNPj5LkNBS3n0XxrNTmUYe7Y0xR6Z0U5EKAGZBJZGBeja
+OVQUWtHSo3hG+PgpZKKG6YPrXi+lksjTA8i5jagrKH9rBM2pvXj456PXLKwUFoSS
+x1A3kfEhH0j8TcLzkFw7yMvS+mQ9Bw4kEZUPe1C+pPaIJrukMhvSjN5NFgN0/l6l
+zIfU1OkYLTDfbl7pK5NLDkZ5g5ibBJCQd+muT+yyl+M7gET6MjoWe4gRfqkTuzI5
+CgLYUKLTVwGT7uMI73Sd22STrhmg/wfOePSgW7Rv0h5Am7rIgEqcHOxdq5l5ubfI
+wduJxwKVFwFRWwKCAQEAs2aQjjMqZwo+6oiFxbCUt+4edrnQaxwppvjk1dDQpEV4
+memJlu1158fuVU8AFA9g5eDWQX86w3zL7dX1XWbdfSQauzfi8H3fqNJX2kI5dvUS
+eP27WbUwugr44o5TiJvzRFT9Neev2QPcpOdzEUCYrvPH2myHOwsz668pqVGYnAA3
+yhGBoaJMQB6gS+jgNMGgvgCgnNo7tJFALafNOYw9tnomop4HI6l38TZvPfX5O9CY
+2vlt4U4BLhYrR5rt70WslrxMtUaM6cyQEMl96hZz/Pf6msfBtSDwLI+6+FaLqpHl
+HTE3uT1hpbp5G3QN4KFZ0PlY2hTIvifp67f4yTX7xQKCAQEAon5yW6HTc2QveLy3
+I7PWxbqe06146U8bPqA9zudUg1KvYdlbHN1EIoaSnKQyizZyFfTdbUgtwbtP7wRG
+ezmbFRiuQ7sxHYWQ2QftUekoiQ71osaKdGgkBR3mR23I6SlYivcSvkUp+CRqd3Sv
+VS2xTEGn4J0sY6B6knOgRBDcOieAUxFYU3BMPn/h6F1dAJqTAji8UXfq9reIi4In
+lycKrPxDteIVn4VcTpHb77aV2/AToTzlbp6AUgkwbjZRqpLrv246OEXFqdZ7KFKn
+0B8RO4g0Lk4xBzkGt1B6bF0J9xsOKxXWiRGe3TAQyjUW1fkm0S/GFiRUQM6mGxQN
+xELpcQKCAQA0AJYEcjZnWeP07hAAxvfE/SQdfC067xXvzZPfmsDv7SdRTg3RDxIv
+VpfyaIz4Q6Dt4aeZoryw79rZHT0bjvbDEJUjEccZuRL9B8Ppg2rO3ak2Iy6MiWYP
+d6C/Y0w5fCMe+pfPaVJi0KjDsEd9h8D6bbXPzcfBSLULK2IjL4DSL4n8a+isprP9
+niMO/fkHsdzbVqk37laCN9xnn41wkgNNgsjyOGaPYs9ev02to0BUo1m7l7PPLGJR
+LqHrBrDTu9mUdA60OTgdiWt1QkLaeRm0CVm+RgsTavHTqPIkjEm97r6AIMUrT+yf
+MpdqatCe/YZgefbUeFPcMwuuhUx7XseVAoIBAQCOHl4n+6PITWaWJBhofaBNTBZe
+JAjsq0vkABcTekMvqLI+vwqQFiTDLLTGJ4n6PpYcBTHRHTTox/h9feqsb+iqBbmk
+77587Of201aqFdgvbQ9S5y3zSwwJX0nOayKXTNhs1URkwZpsqQNMHBMWwOybMqcs
+rHVU7U9rC7aiSvrmAOiA0lzm5bNqFAtviHOuUPEhsDJB215QaE0Pm0ta0YzQJCub
+NJNLyI4WD4xjKgtzu2IZwj8NxaPPH1Io5k2DIpbpTXjSIvFY70qibjMiePsoqUnr
+4ParopAIGFNKMkljC93olXV1LyZVnq7GhAC+CMt/oK8mwMlipOkvmQBz0qAB
+-----END RSA PRIVATE KEY-----

+ 14 - 0
KittyFallWs/etc/key/MYJOB_DAILY/PublicKeyCP.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAksq8Pw1FPQq4p6ypuBZD
+rKywDqLK3uAKB8smD/tTpGtL6zpVS/WZQf/uyNoL8vIwhLTMqcat8HkOC+L4ZHWc
+7wnBwQeYzk3BskPMVluEy9+VCdpUF1nYGOQgiMjwRmV5G93nKHiVJM/du/y3/p3A
+MTOx5Nuy3HSA5mHGCX3MwLUxzpicWB42FVi+JZlCBMLueaPMqSChnrGxaXDrmxtO
+coIOU4GLAwM37cxvO8AVuQkfMRFUKk/DqPTlRdbeO2B2JHLhGpJdXTwAo+Gn/SHM
+b/JIPjQfoJlnpxJ4r6nPQFvTXDnMlyYl3uZPygJWm7v/mD/C0bVfPIKxbzIujC4d
+QsIXS31O7zlnXCc5G/6TkjdOgw+yqYX2kT3qV+12Si4PudIyPuXFjbaIPLcJ1TAc
+LaK0a1YS9ZDkwPzKl2RwlHIYi1ar1lWE66nnjlBwze3AyW0L1JxVkWer3QmxD85u
+LIYIhBoj16mRFcsVrUJ1plcoXKAOATjlH9UIDP3xcoT4peG+9bFFlgGTo3/8Q4mT
+hslmWz3unst4GyUvJl7OoojyidgyiaamJvygB4WT6jYYv1nG8jW7OHTjaFZLc95r
+bhGwDlVJzEJ6Bw++UcqgGN6mQi+8CBqOD0i/COwtgzHA/U8mjrfCeIS6H0adT6Hv
+91ZMdb+4TIlAeZLTl0me1AcCAwEAAQ==
+-----END PUBLIC KEY-----

+ 14 - 0
KittyFallWs/etc/key/MYJOB_DAILY/PublicKeyVT.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmYTjwe5Uno4Zf3x53QVL
+KykJWRqvPLH3O+MUK7lepZkIoTdMRE+DEXd3lTON9uPig8iw2Wm5CTNbdgMeUrkw
+jpP4CZFBJ05jwcR8RMDqTUlK8NvhkUcF6uIzJTGWnMKoCkcwlt3CmG2FRPIM2+3J
+qwWhM75mIkE8pPP6pN/mTT5vDggyFUNbgDZntCu/+W/mkFbkA0eg7DbJZtR2ssWO
+/2qh7auC4Yrc36LYTcUmf9m/4l6Xa55NznsPfxm78951aH7ag2jO1INdKktWSYvW
+hStJ0F1dDKfxa/MHrIQG62FtQ4ymoIzPHdXaRuuUVk79tumGrw8ZLUnR/7ExntRC
+ieP0gzC7f//VsMy6MpI6+RC5MCZsMbkMNcB0X9NB5ljKA/vyYyxkjdYfay1d9UN+
+4toK3DsmQxtIKd1SoM1b5VhuIqxNaMG7pFzl+X3HpXBvObLVqUFt+c/KgCMfhQsG
+E4RtiGmt1DDD75niCM+AFNlCmh979ahkMVZRPfhFlelSqjx6YozSyI8C9BgTReZg
+E52twmwR/vHlNvNXPbNV8lDODhYGBvZm5ggYaMB82kDwgpAWyR5j+6eF7lKW/aYO
+dhFoTGetOL6ySMhWKBhEUN1XmM3rldfJsyNlVNJJSRyBYaP6dzKLLlmyzcOYBagt
+/Mg+rlOKeH0+r9VNV5nIdS0CAwEAAQ==
+-----END PUBLIC KEY-----

+ 51 - 0
KittyFallWs/etc/key/MYJOB_MONTHLY/PrivateKeyCP.pem

@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAksq8Pw1FPQq4p6ypuBZDrKywDqLK3uAKB8smD/tTpGtL6zpV
+S/WZQf/uyNoL8vIwhLTMqcat8HkOC+L4ZHWc7wnBwQeYzk3BskPMVluEy9+VCdpU
+F1nYGOQgiMjwRmV5G93nKHiVJM/du/y3/p3AMTOx5Nuy3HSA5mHGCX3MwLUxzpic
+WB42FVi+JZlCBMLueaPMqSChnrGxaXDrmxtOcoIOU4GLAwM37cxvO8AVuQkfMRFU
+Kk/DqPTlRdbeO2B2JHLhGpJdXTwAo+Gn/SHMb/JIPjQfoJlnpxJ4r6nPQFvTXDnM
+lyYl3uZPygJWm7v/mD/C0bVfPIKxbzIujC4dQsIXS31O7zlnXCc5G/6TkjdOgw+y
+qYX2kT3qV+12Si4PudIyPuXFjbaIPLcJ1TAcLaK0a1YS9ZDkwPzKl2RwlHIYi1ar
+1lWE66nnjlBwze3AyW0L1JxVkWer3QmxD85uLIYIhBoj16mRFcsVrUJ1plcoXKAO
+ATjlH9UIDP3xcoT4peG+9bFFlgGTo3/8Q4mThslmWz3unst4GyUvJl7Ooojyidgy
+iaamJvygB4WT6jYYv1nG8jW7OHTjaFZLc95rbhGwDlVJzEJ6Bw++UcqgGN6mQi+8
+CBqOD0i/COwtgzHA/U8mjrfCeIS6H0adT6Hv91ZMdb+4TIlAeZLTl0me1AcCAwEA
+AQKCAgAZSRTeI5IOrr8aGvLtQ+CKaQC2tLIPbDYuG39F93vz8YuVTGoO+JJavRRL
+wsuWIMPcyCwM/q1No/yYbZNt8piC0IJwlrdqqhg4dddH9OHOIIhStyoPD6nat8km
+5r4E0kvnUfUUkpjWS3wdeq3TDSdjEk2NZ47KzMK7bJIpZmMTuuKGfOFJiIK2cJ/o
+aBroKQ/dIisJ4xYT+PXffNUI1c5QiTigh8sDTNWgf7uVZkQXqIuX7y05UJ4ah3zK
+5/VF8xrGsoc2BYpRmhleIWvHfb/ydKCfHmloR6SEMflaAP0zT937n/UvACI74B5U
+ZMy4bMzdU/ZiG0T5bmXUCqfb+8GMUFhwL4HdlRESdb+QCm7ZAGb8P9ebkrOfSibf
+axUADldEt0A+7luC+VDCgrJA0djwIsdky9kBcGBwL3djk/okeRp+xeGTNz9iKs0y
+hQktJnuYXMAoIJYW2urvv+2/OoTw3kB3NRpvcLTyha90lxK79oFmTH/N9GOmRdsc
+nnYABccXMAYENgjmHJnb1MHpTZgXfAVei2WU4q+1pdbuyAx0lsaQsBJ/k/ojBG8q
+gRdXzX0qZKDTYA/Ar/Ue100La7X475OJmsWquXhIdyym7QnkKX57HxT7WjOYmPDg
+5xacMtg9dkmdyJc6R0IgkONjUwqdhwqkIdesUy4QygZmCaMMqQKCAQEA0Xfd+Jvk
+Oxf7okgv28zknYO1d6myNPj5LkNBS3n0XxrNTmUYe7Y0xR6Z0U5EKAGZBJZGBeja
+OVQUWtHSo3hG+PgpZKKG6YPrXi+lksjTA8i5jagrKH9rBM2pvXj456PXLKwUFoSS
+x1A3kfEhH0j8TcLzkFw7yMvS+mQ9Bw4kEZUPe1C+pPaIJrukMhvSjN5NFgN0/l6l
+zIfU1OkYLTDfbl7pK5NLDkZ5g5ibBJCQd+muT+yyl+M7gET6MjoWe4gRfqkTuzI5
+CgLYUKLTVwGT7uMI73Sd22STrhmg/wfOePSgW7Rv0h5Am7rIgEqcHOxdq5l5ubfI
+wduJxwKVFwFRWwKCAQEAs2aQjjMqZwo+6oiFxbCUt+4edrnQaxwppvjk1dDQpEV4
+memJlu1158fuVU8AFA9g5eDWQX86w3zL7dX1XWbdfSQauzfi8H3fqNJX2kI5dvUS
+eP27WbUwugr44o5TiJvzRFT9Neev2QPcpOdzEUCYrvPH2myHOwsz668pqVGYnAA3
+yhGBoaJMQB6gS+jgNMGgvgCgnNo7tJFALafNOYw9tnomop4HI6l38TZvPfX5O9CY
+2vlt4U4BLhYrR5rt70WslrxMtUaM6cyQEMl96hZz/Pf6msfBtSDwLI+6+FaLqpHl
+HTE3uT1hpbp5G3QN4KFZ0PlY2hTIvifp67f4yTX7xQKCAQEAon5yW6HTc2QveLy3
+I7PWxbqe06146U8bPqA9zudUg1KvYdlbHN1EIoaSnKQyizZyFfTdbUgtwbtP7wRG
+ezmbFRiuQ7sxHYWQ2QftUekoiQ71osaKdGgkBR3mR23I6SlYivcSvkUp+CRqd3Sv
+VS2xTEGn4J0sY6B6knOgRBDcOieAUxFYU3BMPn/h6F1dAJqTAji8UXfq9reIi4In
+lycKrPxDteIVn4VcTpHb77aV2/AToTzlbp6AUgkwbjZRqpLrv246OEXFqdZ7KFKn
+0B8RO4g0Lk4xBzkGt1B6bF0J9xsOKxXWiRGe3TAQyjUW1fkm0S/GFiRUQM6mGxQN
+xELpcQKCAQA0AJYEcjZnWeP07hAAxvfE/SQdfC067xXvzZPfmsDv7SdRTg3RDxIv
+VpfyaIz4Q6Dt4aeZoryw79rZHT0bjvbDEJUjEccZuRL9B8Ppg2rO3ak2Iy6MiWYP
+d6C/Y0w5fCMe+pfPaVJi0KjDsEd9h8D6bbXPzcfBSLULK2IjL4DSL4n8a+isprP9
+niMO/fkHsdzbVqk37laCN9xnn41wkgNNgsjyOGaPYs9ev02to0BUo1m7l7PPLGJR
+LqHrBrDTu9mUdA60OTgdiWt1QkLaeRm0CVm+RgsTavHTqPIkjEm97r6AIMUrT+yf
+MpdqatCe/YZgefbUeFPcMwuuhUx7XseVAoIBAQCOHl4n+6PITWaWJBhofaBNTBZe
+JAjsq0vkABcTekMvqLI+vwqQFiTDLLTGJ4n6PpYcBTHRHTTox/h9feqsb+iqBbmk
+77587Of201aqFdgvbQ9S5y3zSwwJX0nOayKXTNhs1URkwZpsqQNMHBMWwOybMqcs
+rHVU7U9rC7aiSvrmAOiA0lzm5bNqFAtviHOuUPEhsDJB215QaE0Pm0ta0YzQJCub
+NJNLyI4WD4xjKgtzu2IZwj8NxaPPH1Io5k2DIpbpTXjSIvFY70qibjMiePsoqUnr
+4ParopAIGFNKMkljC93olXV1LyZVnq7GhAC+CMt/oK8mwMlipOkvmQBz0qAB
+-----END RSA PRIVATE KEY-----

+ 14 - 0
KittyFallWs/etc/key/MYJOB_MONTHLY/PublicKeyCP.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAksq8Pw1FPQq4p6ypuBZD
+rKywDqLK3uAKB8smD/tTpGtL6zpVS/WZQf/uyNoL8vIwhLTMqcat8HkOC+L4ZHWc
+7wnBwQeYzk3BskPMVluEy9+VCdpUF1nYGOQgiMjwRmV5G93nKHiVJM/du/y3/p3A
+MTOx5Nuy3HSA5mHGCX3MwLUxzpicWB42FVi+JZlCBMLueaPMqSChnrGxaXDrmxtO
+coIOU4GLAwM37cxvO8AVuQkfMRFUKk/DqPTlRdbeO2B2JHLhGpJdXTwAo+Gn/SHM
+b/JIPjQfoJlnpxJ4r6nPQFvTXDnMlyYl3uZPygJWm7v/mD/C0bVfPIKxbzIujC4d
+QsIXS31O7zlnXCc5G/6TkjdOgw+yqYX2kT3qV+12Si4PudIyPuXFjbaIPLcJ1TAc
+LaK0a1YS9ZDkwPzKl2RwlHIYi1ar1lWE66nnjlBwze3AyW0L1JxVkWer3QmxD85u
+LIYIhBoj16mRFcsVrUJ1plcoXKAOATjlH9UIDP3xcoT4peG+9bFFlgGTo3/8Q4mT
+hslmWz3unst4GyUvJl7OoojyidgyiaamJvygB4WT6jYYv1nG8jW7OHTjaFZLc95r
+bhGwDlVJzEJ6Bw++UcqgGN6mQi+8CBqOD0i/COwtgzHA/U8mjrfCeIS6H0adT6Hv
+91ZMdb+4TIlAeZLTl0me1AcCAwEAAQ==
+-----END PUBLIC KEY-----

+ 14 - 0
KittyFallWs/etc/key/MYJOB_MONTHLY/PublicKeyVT.pem

@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmYTjwe5Uno4Zf3x53QVL
+KykJWRqvPLH3O+MUK7lepZkIoTdMRE+DEXd3lTON9uPig8iw2Wm5CTNbdgMeUrkw
+jpP4CZFBJ05jwcR8RMDqTUlK8NvhkUcF6uIzJTGWnMKoCkcwlt3CmG2FRPIM2+3J
+qwWhM75mIkE8pPP6pN/mTT5vDggyFUNbgDZntCu/+W/mkFbkA0eg7DbJZtR2ssWO
+/2qh7auC4Yrc36LYTcUmf9m/4l6Xa55NznsPfxm78951aH7ag2jO1INdKktWSYvW
+hStJ0F1dDKfxa/MHrIQG62FtQ4ymoIzPHdXaRuuUVk79tumGrw8ZLUnR/7ExntRC
+ieP0gzC7f//VsMy6MpI6+RC5MCZsMbkMNcB0X9NB5ljKA/vyYyxkjdYfay1d9UN+
+4toK3DsmQxtIKd1SoM1b5VhuIqxNaMG7pFzl+X3HpXBvObLVqUFt+c/KgCMfhQsG
+E4RtiGmt1DDD75niCM+AFNlCmh979ahkMVZRPfhFlelSqjx6YozSyI8C9BgTReZg
+E52twmwR/vHlNvNXPbNV8lDODhYGBvZm5ggYaMB82kDwgpAWyR5j+6eF7lKW/aYO
+dhFoTGetOL6ySMhWKBhEUN1XmM3rldfJsyNlVNJJSRyBYaP6dzKLLlmyzcOYBagt
+/Mg+rlOKeH0+r9VNV5nIdS0CAwEAAQ==
+-----END PUBLIC KEY-----

+ 50 - 0
KittyFallWs/etc/log.conf

@@ -0,0 +1,50 @@
+#=================================================
+# Log4j configuration - Message module
+# Viettel Payment Gateway
+#=================================================
+
+#log4j.rootLogger=debug,stdout,full,error
+log4j.rootLogger=debug, MM_SOCK, full, error, errorFilter,stdout
+
+
+#stdout appender
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %5p [%t] %c{1}: %m%n
+log4j.appender.stdout.Threshold=INFO
+
+
+# full appender
+log4j.appender.full=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.full.File=../log/full/full.log
+log4j.appender.full.DatePattern='.'yyyy-MM-dd
+log4j.appender.full.layout=org.apache.log4j.PatternLayout
+log4j.appender.full.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %5p [%t] %c{1}: %m%n
+log4j.appender.full.Threshold=INFO
+
+# error appender
+log4j.appender.error=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.error.File=../log/error/error.log
+log4j.appender.error.DatePattern='.'yyyy-MM-dd
+log4j.appender.error.layout=org.apache.log4j.PatternLayout
+log4j.appender.error.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %5p [%t] %c{1}: %m%n
+log4j.appender.error.Threshold=ERROR
+
+# Define appender MM_SOCK
+log4j.appender.MM_SOCK=com.viettel.mmserver.log.appender.AdvanceSocketHubAppender
+log4j.appender.MM_SOCK.port=8267
+#So luong cac doi tuong LoggingEvent luu trong queue cua Appender.
+#5000 doi tuong LoggingEvent co dung luong tam 2M - 5M 
+log4j.appender.MM_SOCK.maxQueue=5000
+#So luong log offline
+log4j.appender.MM_SOCK.offlineMaxQueue=100	
+#Gioi han so ket noi tu client den Server de xem log
+log4j.appender.MM_SOCK.maxConnection=20
+
+
+# errorFilter
+log4j.appender.errorFilter=com.viettel.mmserver.log.appender.ErrorFilterJDBCAppender
+log4j.appender.errorFilter.maxQueue=5000
+
+
+

+ 22 - 0
KittyFallWs/etc/loglevel.conf

@@ -0,0 +1,22 @@
+#Define DB log times level
+DB_TIMES=100,500,1000
+DB_MESSAGE_KEY=CHAM_DB_LEVEL1,CHAM_DB_LEVEL2,CHAM_DB_LEVEL3
+
+#Define OCS log times level
+OCS_TIMES=100,500,1000
+OCS_MESSAGE_KEY=CHAM_OCS_LEVEL1,CHAM_OCS_LEVEL2,CHAM_OCS_LEVEL3
+
+
+#Define RIM log times level
+RIM_TIMES=100,500,1000
+RIM_MESSAGE_KEY=CHAM_RIM_LEVEL1,CHAM_RIM_LEVEL2,CHAM_RIM_LEVEL3
+
+
+#Define 3G log times level
+3G_TIMES=100,500,1000
+3G_MESSAGE_KEY=CHAM_3G_LEVEL1,CHAM_3G_LEVEL2,CHAM_3G_LEVEL3
+
+#Define data reg log times level
+DATA_WS_TIMES=100,200,300
+DATA_WS_MESSAGE_KEY=CHAM_DATA_LEVEL1,CHAM_DATA_LEVEL2,CHAM_DATA_LEVEL3
+

+ 3 - 0
KittyFallWs/etc/route.xml

@@ -0,0 +1,3 @@
+<list>
+	<route name='ht1' listDbName='dbProcess' prefixMsisdn='509'/>
+</list>

+ 1 - 0
KittyFallWs/etc/route.xml.ept

@@ -0,0 +1 @@
+IsEnCrypted=false

+ 116 - 0
KittyFallWs/etc/server.cfg

@@ -0,0 +1,116 @@
+#********************************************************************
+# TestWrapper Properties
+#
+# NOTE - Please use src/conf/wrapper.conf.in as a template for your
+#        own application rather than the values used for the
+#        TestWrapper sample.
+#********************************************************************
+# Java Application
+wrapper.java.command=java
+
+# Java Main class.  This class must implement the WrapperListener interface
+#  or guarantee that the WrapperManager class is initialized.  Helper
+#  classes are provided to do this for you.  See the Integration section
+#  of the documentation for details.
+wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperStartStopApp
+
+# Java Classpath (include wrapper.jar)  Add class path elements as
+#  needed starting from 1
+wrapper.java.classpath.1=../lib/*.jar
+wrapper.java.classpath.2=../module/*.jar
+
+# Java Additional Parameters
+wrapper.java.additional.1=-Dorg.tanukisoftware.wrapper.WrapperManager.mbean=true
+wrapper.java.additional.2=-javaagent:../lib/mmserver-3.2.jar
+wrapper.java.additional.3=-Dcom.viettel.mmserver.agent.ip=127.0.0.1
+wrapper.java.additional.4=-Dcom.viettel.mmserver.agent.port=8847
+wrapper.java.additional.5=-Dcom.viettel.mmserver.log4j.port=8845
+#wrapper.java.additional.6=-Dcom.viettel.mmserver.appid=
+wrapper.java.additional.6=-Dcom.viettel.mmserver.log4j.path=../etc/log.cfg
+wrapper.java.additional.7=-Dcom.viettel.mmserver.scheduling=0
+wrapper.java.additional.8=-Dcom.viettel.mmserver.actionLog=0
+
+
+
+
+#TIMEOUT start, don vi: s
+wrapper.startup.timeout=300
+
+# Java Library Path (location of Wrapper.DLL or libwrapper.so)
+wrapper.java.library.path.1=../lib
+# Java Additional Parameters
+
+# Initial Java Heap Size (in MB)
+wrapper.java.initmemory=256
+
+# Maximum Java Heap Size (in MB)
+wrapper.java.maxmemory=512
+
+# Application parameters.  Add parameters as needed starting from 1
+wrapper.app.parameter.1=com.vas.kittyfallwsvas.wsfw.main.Start
+wrapper.app.parameter.2=0
+wrapper.app.parameter.3=com.vas.kittyfallwsvas.wsfw.main.Stop
+wrapper.app.parameter.4=true
+wrapper.app.parameter.5=0
+#********************************************************************
+# Wrapper Logging Properties
+#********************************************************************
+# Format of output for the console.  (See docs for formats)
+wrapper.console.format=PM
+
+# Log Level for console output.  (See docs for log levels)
+wrapper.console.loglevel=INFO
+
+# Log file to use for wrapper output logging.
+wrapper.logfile=../log/wrapper/wrapper.log
+
+# Format of output for the log file.  (See docs for formats)
+wrapper.logfile.format=LPTM
+
+# Log Level for log file output.  (See docs for log levels)
+wrapper.logfile.loglevel=INFO
+
+# Maximum size that the log file will be allowed to grow to before
+#  the log is rolled. Size is specified in bytes.  The default value
+#  of 0, disables log rolling.  May abbreviate with the 'k' (kb) or
+#  'm' (mb) suffix.  For example: 10m = 10 megabytes.
+wrapper.logfile.maxsize=50m
+
+# Maximum number of rolled log files which will be allowed before old
+#  files are deleted.  The default value of 0 implies no limit.
+wrapper.logfile.maxfiles=20
+
+# Log Level for sys/event log output.  (See docs for log levels)
+wrapper.syslog.loglevel=NONE
+
+#********************************************************************
+# Wrapper Windows Properties
+#********************************************************************
+# Title to use when running as a console
+wrapper.console.title=IVR Application
+
+#********************************************************************
+# Wrapper Windows NT/2000/XP Service Properties
+#********************************************************************
+# WARNING - Do not modify any of these properties when an application
+#  using this configuration file has been installed as a service.
+#  Please uninstall the service before modifying this section.  The
+#  service can then be reinstalled.
+
+# Name of the service
+wrapper.ntservice.name=ivrapp
+
+# Display name of the service
+wrapper.ntservice.displayname=IVR Application
+
+# Description of the service
+wrapper.ntservice.description=IVR services
+
+# Service dependencies.  Add dependencies as needed starting from 1
+wrapper.ntservice.dependency.1=
+
+# Mode in which the service is installed.  AUTO_START or DEMAND_START
+wrapper.ntservice.starttype=AUTO_START
+
+# Allow the service to interact with the desktop.
+wrapper.ntservice.interactive=false

+ 13 - 0
KittyFallWs/etc/webservice.cfg

@@ -0,0 +1,13 @@
+#=================================================
+
+# Time out ws (ms)
+CONNECTION_TIME_OUT = 20000
+
+#sleep time when check ws (ms)
+WS_ACTIVE_IDLE=10000
+
+#config database id to load webservice obj
+DATABASE_ID=dbProcess
+
+#number of list httpclient to send webservice request
+NUMER_HTTPCLIENT=10

+ 3 - 0
KittyFallWs/etc/webservices.xml

@@ -0,0 +1,3 @@
+<list>
+	<webservice name='KittyFallWs' implementClass='com.vas.webservices.KittyFallWs' ip='127.0.0.1' port='8199' path='KittyFallWs'/>
+</list>

BIN
KittyFallWs/lib/CollaborationAgent-2.1.jar


BIN
KittyFallWs/lib/PropertiesUtils.jar


BIN
KittyFallWs/lib/VasgwFW.jar


BIN
KittyFallWs/lib/activation.jar


BIN
KittyFallWs/lib/annotations-1.3.2.jar


BIN
KittyFallWs/lib/axis-ant.jar


BIN
KittyFallWs/lib/axis.jar


BIN
KittyFallWs/lib/bcprov-jdk16-141.jar


BIN
KittyFallWs/lib/c3p0-0.9.2.1.jar


BIN
KittyFallWs/lib/commons-codec-1.3.jar


BIN
KittyFallWs/lib/commons-collections-3.2.jar


BIN
KittyFallWs/lib/commons-dbcp-1.2.2.jar


BIN
KittyFallWs/lib/commons-discovery-0.2.jar


BIN
KittyFallWs/lib/commons-httpclient-3.1.jar


BIN
KittyFallWs/lib/commons-io-1.4.jar


BIN
KittyFallWs/lib/commons-lang-2.4.jar


BIN
KittyFallWs/lib/commons-logging-1.0.4.jar


BIN
KittyFallWs/lib/commons-net-2.0.jar


BIN
KittyFallWs/lib/commons-pool-1.3.jar


BIN
KittyFallWs/lib/commons-v2.1-yc14.jar


BIN
KittyFallWs/lib/commons-v2.2.jar


BIN
KittyFallWs/lib/commons.jar


BIN
KittyFallWs/lib/gson-2.2.2.jar


BIN
KittyFallWs/lib/httpclient-4.0.jar


BIN
KittyFallWs/lib/httpcore-4.0.1.jar


BIN
KittyFallWs/lib/httpmime-4.0.jar


BIN
KittyFallWs/lib/javax.ws.rs-api-2.0.jar


BIN
KittyFallWs/lib/javax.ws.rs.jar


BIN
KittyFallWs/lib/javax.xml.soap-3.1.jar


BIN
KittyFallWs/lib/jaxrpc.jar


BIN
KittyFallWs/lib/jep.jar


BIN
KittyFallWs/lib/jgroups-2.10.0.GA.jar


BIN
KittyFallWs/lib/json-lib-2.4-jdk15.jar


BIN
KittyFallWs/lib/json.jar


BIN
KittyFallWs/lib/jsonwebservice-ri-0.8.0.jar


BIN
KittyFallWs/lib/log4j-1.2.15-ext.jar


BIN
KittyFallWs/lib/log4j-1.2.15.jar


BIN
KittyFallWs/lib/mail.jar


BIN
KittyFallWs/lib/mchange-commons-java-0.2.3.4.jar


BIN
KittyFallWs/lib/mina-core-2.0.0-M5.jar


BIN
KittyFallWs/lib/mmserver-3.2.jar


BIN
KittyFallWs/lib/mysql-connector-java-5.1.37-bin.jar


BIN
KittyFallWs/lib/ojdbc7-12.1.0.2.jar


BIN
KittyFallWs/lib/org-netbeans-modules-java-j2seproject-copylibstask.jar


BIN
KittyFallWs/lib/org-openide-util.jar


BIN
KittyFallWs/lib/portal-kernel.jar


BIN
KittyFallWs/lib/sendmt.jar


BIN
KittyFallWs/lib/slf4j-api-1.5.6.jar


BIN
KittyFallWs/lib/slf4j-jdk14-1.5.6.jar


BIN
KittyFallWs/lib/telnetd2.jar


BIN
KittyFallWs/lib/ultis.jar


BIN
KittyFallWs/lib/utils.jar


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff