Commit 56b41129 authored by 顾俭's avatar 顾俭

copy from fcn srm

parents

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

/META-INF
# Created by .ignore support plugin (hsz.mobi)
.gradle
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
build
!/src/main/resources/static/node_modules/toastr/build
!/src/main/resources/static/node_modules/eonasdan-bootstrap-datetimepicker/build
!/src/main/resources/static/node_modules/pdfmake/build
log
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
### Maven template
target/
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
release.properties
dependency-reduced-pom.xml
META-INF/persistence.xml
/web
lib/
/report
.sonar_lock
*.scssc
hs_err_pid*.log
# minify css and js
/src/main/resources/static/minify/*
/script/*_config.sh
/oracle_dev_db/dump
/oracle_dev_db/data
/oracle_dev_db/script/create_user.log
*.log
.sass-cache/**
all.js
all.js.gz
pipeline {
agent any
stages {
stage('Init build parameter') {
steps {
echo "[ INFO ] [ Init ] ========== initialize build parameter =========="
sh "env"
}
}
stage('Deploy') {
steps {
echo '[ INFO ] [ Deploy ] ========== start sit deploy =========='
sh "chmod 777 ./run-docker.sh"
sh "chmod 777 ./issue.sh"
script {
if ( env.BRANCH_NAME == 'master' ){
sh "./run-docker.sh"
}else{
def branchNames = "${env.BRANCH_NAME}".split('#')
def branchName = branchNames[1]
echo "${branchName}"
sh "./issue.sh ${branchName}"
}
}
}
}
}
}
apply from: 'combinedJs.gradle'
buildscript {
ext {
springBootVersion = '1.5.6.RELEASE'
}
repositories {
jcenter()
mavenCentral()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
classpath "org.flywaydb:flyway-gradle-plugin:4.2.0"
classpath "com.eriwen:gradle-js-plugin:2.12.0"
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'war'
apply plugin: 'org.flywaydb.flyway'
group 'com.i1.srm'
version 'latest'
sourceCompatibility = 1.8
flyway {
url = 'jdbc:mysql://localhost:3306/'
user = 'root'
password = ''
schemas = ['srm_fcn']
locations = ['filesystem:upgrade/sql/mysql']
outOfOrder = true
validateOnMigrate = false
}
configurations {
providedRuntime
}
repositories {
mavenCentral()
mavenLocal()
maven { url "https://repo.spring.io/snapshot" }
maven { url "https://repo.spring.io/milestone" }
}
dependencies {
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
compile("org.springframework.boot:spring-boot-starter-actuator")
compile("org.springframework.boot:spring-boot-starter-cache")
compile("org.springframework.boot:spring-boot-starter-mail")
compile("org.springframework.security:spring-security-acl:4.2.0.RELEASE")
compile('org.thymeleaf.extras:thymeleaf-extras-springsecurity4')
compile('org.springframework.boot:spring-boot-starter-tomcat')
compile('org.apache.commons:commons-lang3:3.5')
compile group: 'com.alibaba', name: 'druid-spring-boot-starter', version: '1.1.10'
compile group: 'org.reflections', name: 'reflections', version: '0.9.11'
compile group: 'mysql', name: 'mysql-connector-java', version: '5.1.6'
compile group: 'joda-time', name: 'joda-time', version: '2.9.9'
compile group: 'org.apache.cxf', name: 'cxf-spring-boot-starter-jaxws', version: '3.1.11'
compile group: 'org.xhtmlrenderer', name: 'flying-saucer-pdf', version: '9.1.6'
compile group: 'org.jsoup', name: 'jsoup', version: '1.10.3'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.3'
compile group: 'commons-validator', name: 'commons-validator', version: '1.6'
compile group: 'commons-io', name: 'commons-io', version: '2.5'
compile group: 'com.github.spullara.mustache.java', name: 'compiler', version: '0.9.5'
compile group: 'net.glxn', name: 'qrgen', version: '1.4'
compile group: 'net.sf.ehcache', name: 'ehcache-core', version: '2.6.3'
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.16'
compile group: 'de.codecentric', name: 'spring-boot-admin-starter-client', version: '1.5.6'
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile group: 'com.h2database', name: 'h2', version: '1.4.196'
}
bootRun {
systemProperties = System.properties
}
tasks.processResources.dependsOn tasks.gzipJs
tasks.gzipJs.dependsOn tasks.combineJs
\ No newline at end of file
This diff is collapsed.
#!/usr/bin/env bash
GROUP_NAME=fcn
PROJECT_NAME=srm
ISSUE_ID=prod
PORT=57002
MEMORY=1024
DOCKER_NAME=${GROUP_NAME}-${PROJECT_NAME}-${ISSUE_ID}
echo "============================================="
echo GROUP_NAME=${GROUP_NAME}
echo PROJECT_NAME=${PROJECT_NAME}
echo PORT=${PORT}
echo MEMORY=${MEMORY}
echo DOCKER_NAME=${DOCKER_NAME}
echo "============================================="
echo "stop docker ${DOCKER_NAME}"
docker rm -f ${DOCKER_NAME}
echo "Update code..."
git checkout "master"
git branch -d "#${ISSUE_ID}"
git fetch
git checkout -b "#${ISSUE_ID}" "origin/#${ISSUE_ID}"
echo "Checkout branch origin/"${ISSUE_ID}
cp /alidata1/dev/bq/gradle-cache-fcn /alidata1/dev/bq/gradle-cache-fcn-${ISSUE_ID} -R
echo "start docker ${DOCKER_NAME}"
docker run -d \
--user $UID \
--name ${DOCKER_NAME} \
-v "$PWD":/${PROJECT_NAME} \
-v /alidata1/dev/bq/gradle-cache-fcn-${ISSUE_ID}:/root/.gradle \
-p ${PORT}:1098 \
-w /${PROJECT_NAME} \
gradle:alpine \
bash -c "gradle flywayRepair -Pflyway.url=jdbc:mysql://project.benchmarkchina.com:3306/srm_fcn -Pflyway.user=root -Pflyway.password=benchmark123 -Pflyway.locations=filesystem:upgrade/sql/mysql; gradle flywayMigrate -Pflyway.url=jdbc:mysql://project.benchmarkchina.com:3306/srm -Pflyway.user=root -Pflyway.password=benchmark123 -Pflyway.locations=filesystem:upgrade/sql/mysql -Pflyway.outOfOrder=true -Pflyway.validateOnMigrate=false -Pflyway.ignoreMissingMigrations=true -Pflyway.ignoreFutureMigrations=true; gradle build; gradle bootRun"
#Thu May 04 09:51:00 NZST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-bin.zip
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
[ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
#!/usr/bin/env bash
if [ -z "$1" ]
then
echo "Usage: issue.sh issue_no, ex: issue.sh 101"
exit;
fi
GROUP_NAME=fcn
PROJECT_NAME=srm
ISSUE_ID=$1
PORT=57001
MEMORY=1024
DOCKER_NAME=${GROUP_NAME}-${PROJECT_NAME}-ISSUE
echo "============================================="
echo GROUP_NAME=${GROUP_NAME}
echo PROJECT_NAME=${PROJECT_NAME}
echo PORT=${PORT}
echo MEMORY=${MEMORY}
echo DOCKER_NAME=${DOCKER_NAME}
echo "============================================="
echo "stop docker ${DOCKER_NAME}"
docker rm -f ${DOCKER_NAME}
echo "Update code..."
git checkout "master"
git branch -d "#${ISSUE_ID}"
git fetch
git checkout -b "#${ISSUE_ID}" "origin/#${ISSUE_ID}"
echo "Checkout branch origin/"${ISSUE_ID}
cp /alidata1/dev/bq/gradle-cache-fcn /alidata1/dev/bq/gradle-cache-fcn-new -R
echo "start docker ${DOCKER_NAME}"
docker run -d \
--user $UID \
--name ${DOCKER_NAME} \
-v "$PWD":/${PROJECT_NAME} \
-v /alidata1/dev/bq/gradle-cache-fcn-new:/root/.gradle \
-v /etc/localtime:/etc/localtime:ro \
-p ${PORT}:1098 \
-w /${PROJECT_NAME} \
gradle:alpine \
bash -c "gradle flywayRepair -Pflyway.url=jdbc:mysql://project.benchmarkchina.com:3306/srm_fcn -Pflyway.user=root -Pflyway.password=benchmark123 -Pflyway.locations=filesystem:upgrade/sql/mysql; gradle flywayMigrate -Pflyway.url=jdbc:mysql://project.benchmarkchina.com:3306/srm -Pflyway.user=root -Pflyway.password=benchmark123 -Pflyway.locations=filesystem:upgrade/sql/mysql -Pflyway.outOfOrder=true -Pflyway.validateOnMigrate=false -Pflyway.ignoreMissingMigrations=true -Pflyway.ignoreFutureMigrations=true; gradle bootRun"
SIT:
URL: http://project.benchmarkchina.com:57000/
Database:jdbc:mysql://project.benchmarkchina.com:3306/srm_fcn?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
环境启动:目录:/alidata1/dev/fcn/srm 脚本:run-docker.sh
ISSUE:
URL: http://project.benchmarkchina.com:57001/
Database:jdbc:mysql://project.benchmarkchina.com:3306/srm_fcn?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
环境启动:目录:/alidata1/dev/launcher/fcn/srm 脚本:issue.sh issueNo(如执行:sh issue.sh 2)
Staging:
URL: http://58.210.204.82:1098/
Database: srm_staging
Prod:
URL: http://58.210.204.82:1099/
Database: srm
MySql backup:
/home/srm/SRM/backup
\ No newline at end of file
#!/usr/bin/env bash
GROUP_NAME=fcn
PROJECT_NAME=srm
PORT=57000
PROFILE=default
MEMORY=1024
DOCKER_NAME=${GROUP_NAME}-${PROJECT_NAME}
echo "============================================="
echo GROUP_NAME=${GROUP_NAME}
echo PROJECT_NAME=${PROJECT_NAME}
echo PORT=${PORT}
echo PROFILE=${PROFILE}
echo MEMORY=${MEMORY}
echo DOCKER_NAME=${DOCKER_NAME}
echo "============================================="
echo "stop docker ${DOCKER_NAME}"
docker rm -f ${DOCKER_NAME}
echo "Update code..."
git pull
echo "start docker ${DOCKER_NAME}"
docker run -d \
--user $UID \
--name ${DOCKER_NAME} \
-v "$PWD":/${PROJECT_NAME} \
-v /alidata1/dev/bq/gradle-cache-fcn:/root/.gradle \
-v /etc/localtime:/etc/localtime:ro \
-p ${PORT}:1098 \
-w /${PROJECT_NAME} \
gradle:alpine \
bash -c "gradle flywayRepair -Pflyway.url=jdbc:mysql://project.benchmarkchina.com:3306/srm_fcn -Pflyway.user=root -Pflyway.password=benchmark123 -Pflyway.locations=filesystem:upgrade/sql/mysql; gradle flywayMigrate -Pflyway.url=jdbc:mysql://project.benchmarkchina.com:3306/srm -Pflyway.user=root -Pflyway.password=benchmark123 -Pflyway.locations=filesystem:upgrade/sql/mysql -Pflyway.outOfOrder=true -Pflyway.validateOnMigrate=false -Pflyway.ignoreMissingMigrations=true -Pflyway.ignoreFutureMigrations=true; gradle build;gradle bootRun"
#!/usr/bin/env bash
echo $JAVE_HOME
echo $PWD
echo 'Starting SRM...'
BASEPATH=$(cd `dirname $0`;pwd)
echo $BASEPATH
cd $BASEPATH
nohup java -Xms512m -Xmx2048m -Xss2048k -jar -Dspring.profiles.active=prod srm-latest.war >/dev/null 2>&1 & echo $! > ./pid &
echo `date "+%Y-%m-%d %H:%M:%S"`
echo 'SRM running...'
#!/usr/bin/env bash
echo $JAVE_HOME
echo $PWD
echo 'Starting SRM...'
BASEPATH=$(cd `dirname $0`;pwd)
echo $BASEPATH
cd $BASEPATH
nohup java -Xms512m -Xmx1024m -Xss2048k -jar -Dspring.profiles.active=staging srm-latest.war >/dev/null 2>&1 & echo $! > ./pid &
echo `date "+%Y-%m-%d %H:%M:%S"`
echo 'SRM running...'
package com.i1;
import com.i1.base.dao.BaseJpaRepositoryImpl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* Created by WLLY on 2017/8/14.
*/
@SpringBootApplication
@EnableScheduling
@EnableJpaRepositories(repositoryBaseClass = BaseJpaRepositoryImpl.class)
@EnableConfigurationProperties
@EnableAspectJAutoProxy
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
// @Bean
// public DataSource dataSource() {
// return DruidDataSourceBuilder.create().build();
// }
}
package com.i1.base.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Sort the result automatically if put it on a field. ONLY WORKING FOR PAGEABLE QUERY
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SortField {
SortOrder order() default SortOrder.ASC;
}
package com.i1.base.annotation;
public enum SortOrder {
ASC,
DESC,
}
package com.i1.base.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Mark on a field if you want to this field to be queried by like.
*/
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface StringMatchQuery {
}
package com.i1.base.dao;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import java.util.List;
import java.util.Optional;
/**
* Created by Ethan on 8/23/2017.
*/
@NoRepositoryBean
public interface BaseJpaRepository<T> extends JpaRepository<T, Long> {
/**
* Example query with customized conditions.
* @param example
* @param queryCustom
* @param <S>
* @return
*/
<S extends T> List<S> findAll(Example<S> example, IQueryCustom queryCustom);
/**
* Example query with order and customized conditions.
* @param example
* @param sort
* @param queryCustom
* @param <S>
* @return
*/
<S extends T> List<S> findAll(Example<S> example, Sort sort, IQueryCustom queryCustom);
/**
* Pageable query with customized conditions.
* @param example
* @param pageable
* @param queryCustom
* @param <S>
* @return
*/
<S extends T> Page<S> findAll(Example<S> example, Pageable pageable, IQueryCustom queryCustom);
/**
* Find by Id with Optional support.
* @param id
* @return
*/
Optional<T> findById(Long id);
}
package com.i1.base.dao;
import org.springframework.data.domain.*;
import org.springframework.data.jpa.convert.QueryByExamplePredicateBuilder;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.util.Assert;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Optional;
import static org.springframework.data.jpa.repository.query.QueryUtils.toOrders;
/**
* A customized Jpa repository which we can customized JPA Query object.
* Created by Ethan on 8/23/2017.
*/
@NoRepositoryBean
public class BaseJpaRepositoryImpl<T> extends SimpleJpaRepository<T, Long> implements BaseJpaRepository<T> {
protected final EntityManager em;
public BaseJpaRepositoryImpl(Class domainClass, EntityManager em) {
super(domainClass, em);
this.em = em;
}
public BaseJpaRepositoryImpl(JpaEntityInformation<T, ?> entityInformation, EntityManager entityManager) {
super(entityInformation, entityManager);
this.em = entityManager;
}
/**
* Example query with customized conditions.
* @param example
* @param queryCustom
* @param <S>
* @return
*/
@Override
public <S extends T> List<S> findAll(Example<S> example, IQueryCustom queryCustom) {
return getQuery(new ExampleSpecification<S>(example), example.getProbeType(), (Sort) null, queryCustom).getResultList();
}
/**
* Example query with order and customized conditions.
* @param example
* @param sort
* @param queryCustom
* @param <S>
* @return
*/
@Override
public <S extends T> List<S> findAll(Example<S> example, Sort sort, IQueryCustom queryCustom) {
return getQuery(new ExampleSpecification<S>(example), example.getProbeType(), sort, queryCustom).getResultList();
}
/**
* Pageable query with customized conditions.
* @param example
* @param pageable
* @param queryCustom
* @param <S>
* @return
*/
@Override
public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable, IQueryCustom queryCustom) {
ExampleSpecification<S> spec = new ExampleSpecification<S>(example);
Class<S> probeType = example.getProbeType();
TypedQuery<S> query = getQuery(new ExampleSpecification<S>(example), probeType, pageable, queryCustom);
//System.out.println(query.getResultList().size());//TODO delete after test,readPage里spec计算总笔数少queryCustom条件
return pageable == null ? new PageImpl<S>(query.getResultList()) : readPage(query, probeType, pageable, spec);
}
/**
* Copied from Spring JPA and change totalSize
*/
@Override
protected <S extends T> Page<S> readPage(TypedQuery<S> query, final Class<S> domainClass, Pageable pageable,
final Specification<S> spec) {
long totalSize = query.getResultList().size();
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
// return PageableExecutionUtils.getPage(query.getResultList(), pageable, new PageableExecutionUtils.TotalSupplier() {
//
// @Override
// public long get() {
// return executeCountQuery(getCountQuery(spec, domainClass));
// }
// });
return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> totalSize);
}
/**
* Find by Id with Optional support.
* @param id
* @return
*/
@Override
public Optional<T> findById(Long id) {
T entity = findOne(id);
return entity != null ? Optional.of(entity) : Optional.empty();
}
/**
* Don't change it. Copied from Spring JPA.
*/
protected <S extends T> TypedQuery<S> getQuery(Specification<S> spec, Class<S> domainClass, Pageable pageable, IQueryCustom queryCustom) {
Sort sort = pageable == null ? null : pageable.getSort();
return getQuery(spec, domainClass, sort, queryCustom);
}
/**
* Don't change it. Copied from Spring JPA.
*/
protected <S extends T> TypedQuery<S> getQuery(Specification<S> spec, Class<S> domainClass, Sort sort, IQueryCustom<S> queryCustom) {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<S> query = builder.createQuery(domainClass);
Root<S> root = applySpecificationToCriteria(spec, domainClass, query);
query.select(root);
if (sort != null) {
query.orderBy(toOrders(sort, root, builder));
}
if (queryCustom != null) {
query = queryCustom.customQuery(root, builder, query);
}
return applyRepositoryMethodMetadata(em.createQuery(query));
}
/**
* Don't change it. Copied from Spring JPA.
*/
private <S, U extends T> Root<U> applySpecificationToCriteria(Specification<U> spec, Class<U> domainClass,
CriteriaQuery<S> query) {
Assert.notNull(domainClass, "Domain class must not be null!");
Assert.notNull(query, "CriteriaQuery must not be null!");
Root<U> root = query.from(domainClass);
if (spec == null) {
return root;
}
CriteriaBuilder builder = em.getCriteriaBuilder();
Predicate predicate = spec.toPredicate(root, query, builder);
if (predicate != null) {
query.where(predicate);
}
return root;
}
/**
* Don't change it. Copied from Spring JPA.
*/
private <S> TypedQuery<S> applyRepositoryMethodMetadata(TypedQuery<S> query) {
if (getRepositoryMethodMetadata() == null) {
return query;
}
LockModeType type = getRepositoryMethodMetadata().getLockModeType();
TypedQuery<S> toReturn = type == null ? query : query.setLockMode(type);
applyQueryHints(toReturn);
return toReturn;
}
/**
* Don't change it. Copied from Spring JPA.
*/
private void applyQueryHints(Query query) {
// for (Map.Entry<String, Object> hint : getQueryHints().asMap()) {
// query.setHint(hint.getKey(), hint.getValue());
// }
}
/**
* Don't change it. Copied from Spring JPA.
*/
private static class ExampleSpecification<T> implements Specification<T> {
private final Example<T> example;
/**
* Creates new {@link ExampleSpecification}.
*
* @param example
*/
public ExampleSpecification(Example<T> example) {
Assert.notNull(example, "Example must not be null!");
this.example = example;
}
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
return QueryByExamplePredicateBuilder.getPredicate(root, cb, example);
}
}
// private static Long executeCountQuery(TypedQuery<Long> query) {
//
// Assert.notNull(query, "TypedQuery must not be null!");
//
// List<Long> totals = query.getResultList();
// Long total = 0L;
//
// for (Long element : totals) {
// total += element == null ? 0 : element;
// }
//
// return total;
// }
}
package com.i1.base.dao;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
/**
* Interface for customizing JPA querys.
*
* Created by Ethan on 8/23/2017.
*/
public interface IQueryCustom<T> {
CriteriaQuery customQuery(Root<T> root, CriteriaBuilder builder, CriteriaQuery<T> query);
}
package com.i1.base.dao;
import javax.persistence.*;
import java.io.Serializable;
/**
* Created by WLLY on 2017/8/15.
*/
@MappedSuperclass
public class IdentifiableObject implements Serializable {
// @Id
// @Column(name = "ID")
// @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SRM_SEQ")
// @SequenceGenerator(name = "SRM_SEQ", sequenceName = "SRM_SEQ", allocationSize = 1)
// private Long id;
@Id
@Column(name = "ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
package com.i1.base.exception;
import com.i1.base.web.ResponseDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice
public class GlobalExceptionHandler {
private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@Value("${srm.dev:}")
private boolean isDev;
/**
* Handle all ajax call exceptions.
*
* @param request
* @param e
* @return
*/
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(IOneWebRestfulException.class)
public ResponseDto handleRestfulError(HttpServletRequest request, IOneWebRestfulException e) {
//Print the stack
logger.error(e.getMessage(), e);
ResponseDto restfulError;
if (isDev) {
restfulError = new ResponseDto(request.getRequestURI(), e, e.getExternalMsg());
} else {
restfulError = new ResponseDto(request.getRequestURI(),
e.getCause() == null ? e.toString() : e.getCause().getLocalizedMessage(),
e.getExternalMsg());
}
return restfulError;
}
@ResponseBody
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
public ResponseDto handleRestfulError(HttpServletRequest request, Exception e) {
//Print the stack
logger.error(e.getMessage(), e);
ResponseDto restfulError;
if (isDev) {
restfulError = new ResponseDto(request.getRequestURI(), e);
} else {
restfulError = new ResponseDto(request.getRequestURI(),
e.getCause() == null ? e.toString() : e.getCause().getLocalizedMessage(), "");
}
return restfulError;
}
}
package com.i1.base.exception;
/**
* Created by WLLY on 2017/8/15.
*/
public class IOneDaoException extends Exception {
}
package com.i1.base.exception;
/**
* Created by WLLY on 2017/8/15.
*/
public class IOneServiceException extends Exception {
private String externalMsg;
public IOneServiceException() {
}
public IOneServiceException(String message) {
super(message);
}
public IOneServiceException(String message, String externalMsg) {
super(message);
this.externalMsg = externalMsg;
}
public IOneServiceException(String message, Throwable cause) {
super(message, cause);
}
public IOneServiceException(Throwable cause) {
super(cause);
}
public String getExternalMsg() {
return externalMsg;
}
public void setExternalMsg(String externalMsg) {
this.externalMsg = externalMsg;
}
}
package com.i1.base.exception;
/**
* Created by WLLY on 2017/8/15.
*/
public class IOneWebRestfulException extends RuntimeException {
private String externalMsg;
public IOneWebRestfulException() {
}
public IOneWebRestfulException(String message) {
super(message);
}
public IOneWebRestfulException(String message, String externalMsg) {
super(message);
this.externalMsg = externalMsg;
}
public IOneWebRestfulException(String message, Throwable cause) {
super(message, cause);
}
public IOneWebRestfulException(Throwable cause) {
super(cause);
if(cause instanceof IOneServiceException) {
this.setExternalMsg(((IOneServiceException)cause).getExternalMsg());
}
}
public String getExternalMsg() {
return externalMsg;
}
public void setExternalMsg(String externalMsg) {
this.externalMsg = externalMsg;
}
}
package com.i1.base.security;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Arrays;
import static org.apache.commons.codec.CharEncoding.UTF_8;
public class AESEncryptionAlgorithm {
private static final Logger log = LoggerFactory.getLogger(AESEncryptionAlgorithm.class);
private static final String AES_CBC_PKCS5PADDING = "AES/CBC/PKCS5PADDING";
private static final Integer IV_SIZE_BYTES = 16;
private SecretKeySpec secretKey;
private byte[] key;
/**
* We use this static IV only for compatibility with older versions. Just to be able to decrypt previously stored
* cookies. All new Cookies and entities ID's that we show to user are encrypted with dynamic IV
*/
//fuel50isawesome!
private static byte[] iv = { 102,117,101,108,53,48,105,115,97,119,101,115,111,109,101,33 };
/*
* Constructor. Takes a key (the passphrase used to encrypt or decrypt the text)
*/
public AESEncryptionAlgorithm(String key) {
setKey(key);
}
/*
* Use this method to override the key used to encrypt/decrypt the text that
* was used to intialize the class.
*/
public void setKey(String key) {
MessageDigest sha;
try {
this.key = key.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1"); //use the SHA-1 hashing algorithm to hash the key
this.key = sha.digest(this.key);
this.key = Arrays.copyOf(this.key, 16); //pad or truncate the array to be 16 bits in length as required by AES
secretKey = new SecretKeySpec(this.key, "AES");
} catch (Exception e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
public String getSecretKey() {
return secretKey.toString();
}
public String getKey() {
return new String(key);
}
/**
* Encrypt text
* @param plaintext
* @return
*/
public String encryptCBC(String plaintext) {
return encryptCbcDynamicIv(plaintext);//from now on we encrypt all text with dynamic initialisation vector
}
/**
* Decrypt text
* @param encryptedBase64Text
* @return
*/
public String decryptCBC(String encryptedBase64Text){
//Try to decrypt with dynamic initialisation vector (dynamic IV is prepended to cypher)
String decryptedText;
try{
decryptedText = this.decryptCbcDynamicIv(encryptedBase64Text);
}catch (Exception e){
decryptedText = null;
}
if(decryptedText != null && !decryptedText.equalsIgnoreCase("")){
return decryptedText;
}else{//Fallback method that we use for transition period as all newly encrypted COOKIES and obfuscated entities IDs will be encrypted with dynamic IV
return decryptCBCStaticIVFallback(encryptedBase64Text);
}
}
/**
* Encrypt plaintext with CBC and dynamically generated IV
* @param plaintext
* @return
*/
private String encryptCbcDynamicIv(String plaintext){
try {
final IvParameterSpec ivSpec = createDynamicInitialisationVector();
final Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING); //This algorithm does padding of the cipher text for you
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
final ByteArrayOutputStream bytesStream = new ByteArrayOutputStream();
//prepend encrypted content with Initialisation Vector
bytesStream.write(ivSpec.getIV());
try(final CipherOutputStream cypherOutStream = new CipherOutputStream(bytesStream, cipher)){
cypherOutStream.write(plaintext.getBytes(UTF_8));//write encrypted content into the underlying byte stream with cypher output stream
}
return Base64.encodeBase64URLSafeString(bytesStream.toByteArray());
} catch (Exception e) {
log.error("error while encrypting CBC with dynamic IV '"+plaintext+"'", e);
throw new RuntimeException(e);
}
}
/**
* Decrypt text with dynamic Initialisation vector prepended.
* @param ivPrependedBase64CypherText
* @return
*/
public String decryptCbcDynamicIv(String ivPrependedBase64CypherText){
try {
final byte[] ivPrependedCypher = Base64.decodeBase64(ivPrependedBase64CypherText);
final ByteArrayInputStream bytesInputStream = new ByteArrayInputStream(ivPrependedCypher);
//we have initialisation vector prepended to encrypted text, read these first bytes and create IvParameter out of them
final IvParameterSpec ivSpec = readInitialisationVector(bytesInputStream);
final Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
final byte[] buffer = new byte[1024];
try(final CipherInputStream cis = new CipherInputStream(bytesInputStream, cipher);
final ByteArrayOutputStream bytesOutputStream = new ByteArrayOutputStream()){
int read;
while ((read = cis.read(buffer)) != -1){
bytesOutputStream.write(buffer, 0, read);//do not allow anything to creep in in last read
}
return StringUtils.newStringUtf8(bytesOutputStream.toByteArray());
}
} catch (Exception e) {
log.warn("error while decrypting CBC with dynamic IV'"+ivPrependedBase64CypherText+"', reason: {}", e.getMessage());
return null;
}
}
/**
* We use this type of encryption specifically for encrypting IDs of the entities that we transfer to client side
* WE NEED STATIC INITIALISATION VECTOR HERE in order to produce consistent encrypted UIDs that can be compared fro EQUALITY
* Some of our client side code needs this comparisons by UID to operate and we can not go past that.
* So for equal plaintext strings this this code will get equal result.
* @param string
* @return
*/
public String encryptCBCStaticIV(String string) {
try {
IvParameterSpec ivSpec = new IvParameterSpec(iv);//WE NEED CONSISTENT OUTPUT FOR SO WE USE STATIC IV, See note above
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING); //This algorithm does padding of the cipher text for you
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
return Base64.encodeBase64URLSafeString(cipher.doFinal(string.getBytes()));
} catch (Exception e) {
log.error("error while encrypting '"+string+"'", e);
throw new RuntimeException(e);
}
}
public String decryptCBCStaticIVFallback(String string) {
try {
IvParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5PADDING);
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
return StringUtils.newStringUtf8(cipher.doFinal(Base64.decodeBase64(string)));
} catch (Exception e) {
log.warn("error while decrypting '"+string+"', reason: {}", e.getMessage());
return null;
}
}
/**
* Creates dynamic initialisation vector
* @return
*/
private static IvParameterSpec createDynamicInitialisationVector() {
final byte[] iv = new byte[IV_SIZE_BYTES];
final SecureRandom theRNG = new SecureRandom();
theRNG.nextBytes(iv);
return new IvParameterSpec(iv);
}
/**
* We prepend RANDOM initialisation vector to cypher.
* This code read this initialisation vector.
* @param is
* @return
* @throws IOException
*/
private static IvParameterSpec readInitialisationVector(final InputStream is) throws IOException {
final byte[] iv = new byte[IV_SIZE_BYTES];
int offset = 0;
while (offset < IV_SIZE_BYTES) {
final int read = is.read(iv, offset, IV_SIZE_BYTES - offset);
if (read == -1) {
throw new IOException("Too few bytes for IV in input stream");
}
offset += read;
}
return new IvParameterSpec(iv);
}
}
package com.i1.base.security;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
public class IdDeserializer extends JsonDeserializer<String> {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String encryptedId = p.getValueAsString();
if(StringUtils.isNotBlank(encryptedId)) {
if(StringUtils.isNumeric(encryptedId)) {
return encryptedId;
} else {
return IdEncrypt.decrypt2(encryptedId);
}
}
return "";
}
}
package com.i1.base.security;
public class IdEncrypt {
private static final String password = "JHYI67%$#";
public static String encrypt(Long id) {
AESEncryptionAlgorithm aes = new AESEncryptionAlgorithm(password);
return aes.encryptCBC(String.valueOf(id));
}
public static Long decrypt(String encryptedId) {
AESEncryptionAlgorithm aes = new AESEncryptionAlgorithm(password);
return Long.valueOf(aes.decryptCBC(encryptedId));
}
public static String decrypt2(String encryptedId) {
AESEncryptionAlgorithm aes = new AESEncryptionAlgorithm(password);
return aes.decryptCBC(encryptedId);
}
}
package com.i1.base.security;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
public class IdSerializer extends JsonSerializer<String> {
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
if(StringUtils.isNotBlank(value)) {
if(StringUtils.isNumeric(value)) {
gen.writeString(IdEncrypt.encrypt(Long.valueOf(value)));
} else {
gen.writeString(value);
}
}
}
}
package com.i1.base.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.i1.base.dao.BaseJpaRepository;
import com.i1.base.dao.IdentifiableObject;
import com.i1.base.exception.IOneServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.ParameterizedType;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.contains;
/**
* Public service for all other services.
* All other services are supposed to inherit from this interface.
*
* Created by WLLY on 2017/8/15.
*/
public abstract class AbstractService<T extends IdentifiableObject> extends BaseService<T> implements IService<T> {
/**
* Query by example with Sort. The usage of querying by example can refer to List<T> getAll(T example) throws IOneServiceException
* @param example
* @param sort
* @return
* @throws IOneServiceException
*/
@Override
public List<T> getAll(T example, Sort sort) throws IOneServiceException {
if(example != null) {
return getDao().findAll(Example.of(example), sort);
} else {
return getDao().findAll();
}
}
/**
* Query by example with string matching and sort.
* With the stringMatchFields contains ['name', 'desc'], We can query the records that the name contains 'abc' and the desc contains 'desc'.
* {
* name: 'abc',
* desc: 'desc'
* }
*
* class Entity {
* private String name;
* private String desc;
* private SubEntity subEntity;
* }
* @param example
* @param stringMatchFields
* @param sort
* @return
* @throws IOneServiceException
*/
@Override
public List<T> getAll(T example, List<String> stringMatchFields, Sort sort) throws IOneServiceException {
if(example != null) {
return getDao().findAll(Example.of(example, getExampleStringMatcher(stringMatchFields)), sort);
} else {
return getDao().findAll();
}
}
/**
* The abstract service doesn't implement this method. Only when the existing methods are all not suitable and then you can implement it by you own sub classes.
* Normally when you want to use IQueryCustom interface to build your own queries.
*
* @param queryExample: the same to List<T> getAll(T example)
* @param stringMatchFields: the same to List<T> getAll(T example, List<String> stringMatchFields, Sort sort)
* @param otherParams: any other parameters that you want to pass to database query.
* @param pageable
* @return
* @throws IOneServiceException
*/
@Override
public Page<T> getAll(T queryExample, List<String> stringMatchFields, Map<String, Object> otherParams, Pageable pageable) throws IOneServiceException {
throw new IOneServiceException("Not supported in base class. Please implements it in your extended service.");
}
}
package com.i1.base.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.i1.base.dao.BaseJpaRepository;
import com.i1.base.dao.IdentifiableObject;
import com.i1.base.exception.IOneServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.transaction.annotation.Transactional;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.contains;
/**
* Basic methods that using by Abstract controller
* @param <T>
*/
public abstract class BaseService<T extends IdentifiableObject> implements IBaseService<T> {
@Autowired
protected ObjectMapper objectMapper;
abstract protected BaseJpaRepository<T> getDao();
/**
* Query by example which will construct the query automatically by Spring JPA. Normally use it from the client side using Javascirpt through Controller.
*
* We can query Entity by pass the json.
* {
* name: 'abc',
* desc: 'desc',
* subEntity: {
* firstName: 'Bob',
* age: 55
* }
* }
*
* class Entity {
* private String name;
* private String desc;
* private SubEntity subEntity;
* }
*
* Class SubEntity {
* private String firstName;
* private Long age;
* }
* @param example
* @return
* @throws IOneServiceException
*/
@Override
public List<T> getAllByExample(T example) throws IOneServiceException {
if(example != null) {
return getDao().findAll(Example.of(example));
} else {
return getDao().findAll();
}
}
/**
* Get all records with pagination by example and matcher fields.
* @param queryExample: the same to List<T> getAll(T example)
* @param stringMatchFields: the same to List<T> getAll(T example, List<String> stringMatchFields, Sort sort)
* @param pageable
* @return
* @throws IOneServiceException
*/
@Override
public Page<T> getAllByPageAndExample(T queryExample, List<String> stringMatchFields, Pageable pageable) throws IOneServiceException {
if(queryExample != null) {
Example<T> example;
if(stringMatchFields != null && stringMatchFields.size() > 0) {
example = Example.of(queryExample, getExampleStringMatcher(stringMatchFields));
} else {
example = Example.of(queryExample);
}
return getDao().findAll(example, pageable);
} else {
return getDao().findAll(pageable);
}
}
/**
* Build the string matchers for the parameters which will be used to create the query with "LIKE".
* @param matcherFieldList
* @return
*/
protected ExampleMatcher getExampleStringMatcher(List<String> matcherFieldList) {
ExampleMatcher matcher = ExampleMatcher.matching();
for(String field: matcherFieldList) {
matcher = matcher.withMatcher(field, contains());
}
return matcher;
}
/**
* Get by id.
* @param id
* @return null if not found
* @throws IOneServiceException
*/
@Override
public T get(Long id) throws IOneServiceException {
Optional<T> optional = getDao().findById(id);
return optional.isPresent() ? optional.get() : null;
}
/**
* Create new record
* @param entity
* @param <S>
* @return created entity.
* @throws IOneServiceException
*/
@Override
public <S extends T> S add(S entity) throws IOneServiceException {
return (S) getDao().save(entity);
}
/**
* Update existing record.
* @param entity
* @param <S>
* @return updated entity.
* @throws IOneServiceException
*/
@Override
public <S extends T> S update(S entity) throws IOneServiceException {
return (S) getDao().save(entity);
}
/**
* Delete an existing record by id.
* @param id
* @throws IOneServiceException
*/
@Override
public void delete(Long id) throws IOneServiceException {
getDao().delete(id);
}
/**
* Delete existing records by Ids.
* @param ids
* @throws IOneServiceException
*/
@Override
@Transactional
public void deleteAll(List<Long> ids) throws IOneServiceException {
if(ids != null && ids.size() > 0) {
for(Long id: ids) {
getDao().delete(id);
}
}
}
public Class<T> getEntityClass() {
ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
return (Class <T>) genericSuperclass.getActualTypeArguments()[0];
}
public T getFirstOne(List<T> list) {
if(list != null && list.size() > 0) {
return list.get(0);
} else{
return null;
}
}
}
package com.i1.base.service;
import com.i1.base.dao.IdentifiableObject;
import com.i1.base.exception.IOneServiceException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
public interface IBaseService<T extends IdentifiableObject> {
/**
* Query by example which will construct the query automatically by Spring JPA. Normally use it from the client side using Javascirpt through Controller.
*
* We can query Entity by pass the json.
* {
* name: 'abc',
* desc: 'desc',
* subEntity: {
* firstName: 'Bob',
* age: 55
* }
* }
*
* class Entity {
* private String name;
* private String desc;
* private SubEntity subEntity;
* }
*
* Class SubEntity {
* private String firstName;
* private Long age;
* }
* @param example
* @return
* @throws IOneServiceException
*/
List<T> getAllByExample(T example) throws IOneServiceException;
/**
* Get all records with pagination by example and matcher fields.
* @param queryExample: the same to List<T> getAll(T example)
* @param stringMatchFields: the same to List<T> getAll(T example, List<String> stringMatchFields, Sort sort)
* @param pageable
* @return
* @throws IOneServiceException
*/
Page<T> getAllByPageAndExample(T queryExample, List<String> stringMatchFields, Pageable pageable) throws IOneServiceException;
/**
* Get by id.
* @param id
* @return null if not found
* @throws IOneServiceException
*/
T get(Long id) throws IOneServiceException;
/**
* Create new record
* @param entity
* @param <S>
* @return created entity.
* @throws IOneServiceException
*/
<S extends T> S add(S entity) throws IOneServiceException;
/**
* Update existing record.
* @param entity
* @param <S>
* @return updated entity.
* @throws IOneServiceException
*/
<S extends T> S update(S entity) throws IOneServiceException;
/**
* Delete an existing record by id.
* @param id
* @throws IOneServiceException
*/
void delete(Long id) throws IOneServiceException;
/**
* Delete existing records by Ids.
* @param ids
* @throws IOneServiceException
*/
@Transactional
void deleteAll(List<Long> ids) throws IOneServiceException;
}
package com.i1.base.service;
import com.i1.base.dao.IdentifiableObject;
import com.i1.base.exception.IOneServiceException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
/**
* Public service for all other services.
* All other services are supposed to inherit from this interface.
*
* Created by WLLY on 2017/8/15.
*/
public interface IService<T extends IdentifiableObject> extends IBaseService<T> {
/**
* Query by example with Sort. The usage of querying by example can refer to List<T> getAll(T example) throws IOneServiceException
* @param example
* @param sort
* @return
* @throws IOneServiceException
*/
List<T> getAll(T example, Sort sort) throws IOneServiceException;
/**
* Query by example with string matching and sort.
* With the stringMatchFields contains ['name', 'desc'], We can query the records that the name contains 'abc' and the desc contains 'desc'.
* {
* name: 'abc',
* desc: 'desc'
* }
*
* class Entity {
* private String name;
* private String desc;
* private SubEntity subEntity;
* }
* @param example
* @param stringMatchFields
* @param sort
* @return
* @throws IOneServiceException
*/
List<T> getAll(T example, List<String> stringMatchFields, Sort sort) throws IOneServiceException;
/**
* The abstract service doesn't implement this method. Only when the existing methods are all not suitable and then you can implement it by you own sub classes.
* Normally when you want to use IQueryCustom interface to build your own queries.
*
* @param queryExample: the same to List<T> getAll(T example)
* @param stringMatchFields: the same to List<T> getAll(T example, List<String> stringMatchFields, Sort sort)
* @param otherParams: any other parameters that you want to pass to database query.
* @param pageable
* @return
* @throws IOneServiceException
*/
Page<T> getAll(T queryExample, List<String> stringMatchFields, Map<String, Object> otherParams, Pageable pageable) throws IOneServiceException;
}
package com.i1.base.service;
import java.util.List;
import java.util.Map;
/**
* Created by WLLY on 2016/1/3.
*/
public interface ISqlExecuteservice {
List<?> query(String sql);
List<?> query(String sql, Map<String, Object> parameters);
}
package com.i1.base.service;
import com.google.common.collect.ImmutableMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.List;
import java.util.Map;
/**
* Created by WLLY on 2016/1/3.
*/
@Service
public class SqlExecuteservice implements ISqlExecuteservice {
private EntityManager entityManager;
private NamedParameterJdbcTemplate jdbcTemplate;
@Autowired
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Autowired
public void setJdbcTemplate(DataSource dataSource) {
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}
@Override
public List<?> query(String sql) {
return jdbcTemplate.queryForList(sql, ImmutableMap.of());
}
@Override
public List<?> query(String sql, Map<String, Object> parameters) {
return jdbcTemplate.queryForList(sql, parameters);
}
}
package com.i1.base.service.email;
public interface EmailService {
void sendTextMessage(String[] recipient, String subject, String message);
void sendMimeMessage(String[] recipient, String subject, String message, Boolean isHtml, String attachmentName, String attachmentPath, String inLineName, String inLinePath);
void sendBccTextMessage(String[] recipient, String subject, String message);
}
package com.i1.base.service.email;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.MailException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
/**
* @author srm admin
*/
@Service
public class EmailServiceImpl implements EmailService {
private final static Logger logger = LoggerFactory.getLogger(EmailServiceImpl.class);
private JavaMailSender javaMailSender;
@Value("${spring.mail.username}")
private String sender;
@Autowired
public void setJavaMailSender(JavaMailSender javaMailSender) {
this.javaMailSender = javaMailSender;
}
@Override
public void sendTextMessage(String[] recipient, String subject, String message) {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setTo(recipient);
simpleMailMessage.setFrom(sender);
simpleMailMessage.setReplyTo(sender);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(message);
try {
logger.info("Send email with subject {} to {}", subject, recipient);
javaMailSender.send(simpleMailMessage);
} catch (MailException e) {
logger.error("Failed to send a email", e);
}
}
@Override
public void sendMimeMessage(String[] recipient, String subject, String message, Boolean isHtml,
String attachmentName, String attachmentPath, String inLineName, String inLinePath) {
MimeMessage msg = javaMailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(msg, true, "UTF-8");
helper.setTo(recipient);
helper.setFrom(sender);
helper.setReplyTo(sender);
helper.setSubject(subject);
helper.setText(message, isHtml);
if (StringUtils.isNotBlank(attachmentPath)) {
FileSystemResource file = new FileSystemResource(new File(attachmentPath));
helper.addAttachment(attachmentName, file);
}
if (StringUtils.isNotBlank(inLinePath)) {
FileSystemResource file = new FileSystemResource(new File(inLinePath));
helper.addInline(inLineName, file);
}
try {
logger.info("Send email with subject {} to {}", subject, recipient);
javaMailSender.send(msg);
} catch (MailException e) {
logger.error("Failed to send a email", e);
}
} catch (MessagingException e) {
logger.error("Failed to send a email", e);
}
}
@Override
public void sendBccTextMessage(String[] recipient, String subject, String message) {
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setBcc(recipient);
simpleMailMessage.setFrom(sender);
simpleMailMessage.setReplyTo(sender);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(message);
try {
logger.info("Send email with subject {} to {}", subject, recipient);
javaMailSender.send(simpleMailMessage);
} catch (MailException e) {
logger.error("Failed to send a email", e);
}
}
}
This diff is collapsed.
package com.i1.base.web;
import com.i1.base.service.email.EmailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
@RestController
@RequestMapping("/baseEmail")
public class BaseEmailController {
@Autowired
private EmailService emailService;
// http://localhost:8080/baseEmail/send?receipt=gujian@benchmarkchina.com
@GetMapping(value = "/send")
public String sendEmail(@RequestParam String receipt) {
String[] receipts = new String[1];
receipts[0] = receipt;
emailService.sendTextMessage(receipts, "email test", "email test " + new Date());
return "success";
}
}
package com.i1.base.web;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.i1.base.dao.IdentifiableObject;
/**
* Created by WLLY on 2017/8/15.
*/
@JsonIgnoreProperties(ignoreUnknown = true)
public class Dto<T extends IdentifiableObject> {
// @JsonSerialize(using = IdSerializer.class)
// @JsonDeserialize(using = IdDeserializer.class)
private String id;
@JsonIgnore
private T entity;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public T getEntity() {
return entity;
}
public void setEntity(T entity) {
this.entity = entity;
}
}
package com.i1.base.web;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.i1.base.dao.IdentifiableObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@Component
public class DtoTransformer {
@Autowired
private ObjectMapper om;
public DtoTransformer() {
}
@PostConstruct
public void post() {
SimpleModule module = new SimpleModule();
module.addDeserializer(String.class, new StdDeserializer<String>(String.class) {
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
String result = StringDeserializer.instance.deserialize(p, ctxt);
if (StringUtils.isEmpty(result)) {
return null;
}
return result;
}
});
om.registerModule(module);
}
public <T extends IdentifiableObject, D extends Dto<T>> T dtoToEntity(D dto, Class<T> entityClass) {
return om.convertValue(dto, entityClass);
}
public <T extends IdentifiableObject, D extends Dto<T>> List<T> dtoListToEntityList(List<D> dtoList, Class<T> entityClass) {
List<T> result = new ArrayList<>();
for(D dto: dtoList) {
result.add(dtoToEntity(dto, entityClass));
}
return result;
}
public <T extends IdentifiableObject, D extends Dto<T>> D entityToDto(T t, Class<D> dtoClass) {
if(t != null) {
D dto = om.convertValue(t, dtoClass);
dto.setEntity(t);
return dto;
}
return null;
}
public <T extends IdentifiableObject, D extends Dto<T>> List<D> entityListToDtoList(List<T> tList, Class<D> dtoClass) {
List<D> dtoList = new ArrayList<>();
for(T t: tList) {
dtoList.add(entityToDto(t, dtoClass));
}
return dtoList;
}
}
package com.i1.base.web;
import com.i1.base.exception.IOneWebRestfulException;
import java.util.HashMap;
import java.util.Map;
public class ResponseDto {
public int code = 0;
public String url;
public StackTraceElement[] ex;
public String error = null;
public String externalError = null;
public Map<String, Object> extra = new HashMap<>();
public ResponseDto() {
}
public ResponseDto(String url, String error, String externalError) {
this.url = url;
this.error = error;
this.ex = null;
this.externalError = externalError;
}
public ResponseDto(String url, IOneWebRestfulException exception, String externalError) {
this.url = url;
this.error = exception.getCause() == null ? exception.toString() : exception.getCause().getLocalizedMessage();
this.ex = exception.getStackTrace();
this.externalError = externalError;
}
public ResponseDto(String url, Exception exception) {
this.url = url;
this.ex = exception.getStackTrace();
this.error = exception.getCause() == null ? exception.toString() : exception.getCause().getLocalizedMessage();
}
public ResponseDto withExtra(Map<String, Object> extra) {
this.extra = extra;
return this;
}
public static ResponseDto success() {
return new ResponseDto();
}
}
package com.i1.config;
import com.i1.srm.acl.service.SrmPermission;
import com.i1.srm.am.entity.Function;
import com.i1.srm.am.entity.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.acls.AclPermissionEvaluator;
import org.springframework.security.acls.domain.*;
import org.springframework.security.acls.jdbc.BasicLookupStrategy;
import org.springframework.security.acls.jdbc.JdbcMutableAclService;
import org.springframework.security.acls.jdbc.LookupStrategy;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.security.acls.model.PermissionGrantingStrategy;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.method.configuration.GlobalMethodSecurityConfiguration;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import javax.sql.DataSource;
import java.util.*;
/**
* Created by Alan on 17/02/2017.
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class ACLConfig extends GlobalMethodSecurityConfiguration {
@Autowired
private DataSource dataSource;
@Value("${srm.aclSchema:}")
public String aclSchema;
private List<Function> functions = Function.getAll();
@Bean
EhCacheBasedAclCache aclCache() {
return new EhCacheBasedAclCache(ehCacheCacheManager().getObject().getCache("aclCache"), permissionGrantingStrategy(), aclAuthorizationStrategy());
}
@Bean
public EhCacheManagerFactoryBean ehCacheCacheManager() {
EhCacheManagerFactoryBean cacheManagerFactoryBean = new EhCacheManagerFactoryBean();
cacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
cacheManagerFactoryBean.setShared(true);
return cacheManagerFactoryBean;
}
@Bean
AuditLogger auditLogger(){
return new ConsoleAuditLogger();
}
@Bean
LookupStrategy lookupStrategy() {
BasicLookupStrategy basicLookupStrategy = new BasicLookupStrategy(dataSource, aclCache(), aclAuthorizationStrategy(), auditLogger());
basicLookupStrategy.setPermissionFactory(permissionFactory());
return basicLookupStrategy;
}
@Bean
AclAuthorizationStrategy aclAuthorizationStrategy() {
return new AclAuthorizationStrategyImpl(new SimpleGrantedAuthority("ROLE_ACL_ADMIN"),
new SimpleGrantedAuthority("ROLE_ACL_ADMIN"),
new SimpleGrantedAuthority("ROLE_ACL_ADMIN"));
}
@Bean
PermissionGrantingStrategy permissionGrantingStrategy(){
return new DefaultPermissionGrantingStrategy(auditLogger());
}
@Bean
MutableAclService aclService() {
JdbcMutableAclService service = new JdbcMutableAclService(dataSource, lookupStrategy(), aclCache());
service.setSidIdentityQuery("SELECT AUTO_INCREMENT -1 FROM information_schema.tables WHERE table_name = 'acl_sid' AND table_schema = '" + aclSchema + "'");
service.setClassIdentityQuery("SELECT AUTO_INCREMENT -1 FROM information_schema.tables WHERE table_name = 'acl_class' AND table_schema = '" + aclSchema + "'");
return service;
}
@Bean
PermissionFactory permissionFactory(){
Map<String, SrmPermission> namedPermissions = new HashMap<>();
for(Resource resource : Resource.values()){
SrmPermission permission = new SrmPermission(resource.getId(), resource.name());
namedPermissions.put(resource.name(), permission);
}
DefaultPermissionFactory srmPermissionFactory = new DefaultPermissionFactory(namedPermissions);
return srmPermissionFactory;
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler(){
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new AclPermissionEvaluator(aclService()));
return expressionHandler;
}
}
package com.i1.config;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class AjaxAwareAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Ajax Request Denied (Session Expired)");
}
}
package com.i1.config;
import org.springframework.security.web.util.matcher.RequestMatcher;
import javax.servlet.http.HttpServletRequest;
public class AjaxRequestMatcher implements RequestMatcher {
@Override
public boolean matches(HttpServletRequest request) {
String ajaxHeader = request.getHeader("IOne_Ajax_Call");
return "IOne_Ajax_Call".equals(ajaxHeader);
}
}
\ No newline at end of file
package com.i1.config;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
public CustomAuthenticationFailureHandler() {
setDefaultFailureUrl("/login?error");
}
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
if(exception instanceof AccountExpiredException) {
setDefaultFailureUrl("/login?supplier_blocked");
} else if(exception instanceof DisabledException){
setDefaultFailureUrl("/login?account_disabled");
}else {
setDefaultFailureUrl("/login?error");
}
super.onAuthenticationFailure(request, response, exception);
}
}
package com.i1.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class GlobalProperties {
@Value("${srm.bannerInfo:}")
private String srmBannerInfo;
public String getSrmBannerInfo() {
return srmBannerInfo;
}
public void setSrmBannerInfo(String srmBannerInfo) {
this.srmBannerInfo = srmBannerInfo;
}
}
package com.i1.config;
public class GlobalPropertyNames {
public static final String SRM_BANNER_INFO = "SRM_BANNER_INFO";
}
package com.i1.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@Controller
public class HomeController {
@Value("${srm.dev:}")
private boolean dev;
@RequestMapping("/")
public String welcome(Map<String, Object> model) {
model.put("dev", this.dev);
return "index";
}
}
package com.i1.config;
import com.i1.srm.am.entity.SrmUser;
import com.i1.srm.base.dao.entity.BaseSupplierFile;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsChecker;
import org.springframework.stereotype.Component;
import java.util.Set;
import static com.i1.srm.am.entity.Account.SYSTEM_TYPE_SUPPLIER;
@Component
public class PreUserDetailsChecker implements UserDetailsChecker {
@Override
public void check(UserDetails toCheck) throws AuthenticationException {
SrmUser srmUser = (SrmUser) toCheck;
Set<BaseSupplierFile> supplierFileList = srmUser.getSuppliers();
if (!srmUser.isEnabled()) {
throw new DisabledException("账号已经停用");
}
if (StringUtils.equalsIgnoreCase(srmUser.getSystemType(), SYSTEM_TYPE_SUPPLIER)) {
if (supplierFileList != null && supplierFileList.size() > 0) {
String status = supplierFileList.iterator().next().getStatus();
if (StringUtils.isNotBlank(status) && StringUtils.equals(status, BaseSupplierFile.STATUS_STOPPED)) {
throw new AccountExpiredException("供应商账号已经停用");
}
}
}
}
}
package com.i1.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}
package com.i1.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.acls.AclPermissionEvaluator;
import org.springframework.security.acls.model.AclService;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
private final String[] permitUrls = new String[]{
"/app/**",
"/css/**",
"/demo/**",
"/tmp/**",
"/node_modules/**",
"/templates/login.html",
"/login",
"/login.do",
"/report/**",
"/services/**",
"/admin/**",
};
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private PreUserDetailsChecker preUserDetailsChecker;
@Autowired
private CustomAuthenticationFailureHandler failureHandler;
@Autowired
private AclService aclService;
@Autowired
private SessionRegistry sessionRegistry;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.formLogin()
.failureHandler(failureHandler)
.loginPage("/login")
.usernameParameter("username")
.passwordParameter("password")
.loginProcessingUrl("/login.do")
.permitAll()
.and()
.logout()
.logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
.permitAll()
.and()
.authorizeRequests()
.antMatchers(permitUrls).permitAll()
.anyRequest().authenticated()
.and().sessionManagement().sessionFixation().migrateSession()
.maximumSessions(10).expiredUrl("/login").sessionRegistry(sessionRegistry).and()
.and()
.exceptionHandling().defaultAuthenticationEntryPointFor(new AjaxAwareAuthenticationEntryPoint(), new AjaxRequestMatcher());
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setPasswordEncoder(new BCryptPasswordEncoder());
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPreAuthenticationChecks(preUserDetailsChecker);
auth.authenticationProvider(authProvider);
}
@Bean
public AclPermissionEvaluator permissionEvaluator(){
return new AclPermissionEvaluator(aclService);
}
@Bean
public SessionRegistry sessionRegistry() {
return new SessionRegistryImpl();
}
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
}
package com.i1.erp;
import com.i1.base.exception.IOneServiceException;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.ByteArrayInputStream;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
/**
* Base client for webservice client.
*/
public abstract class WebServiceClient {
/**
* Get Client with wsdl URL.
*
* @param wsdl
* @return
*/
protected Client getClient(String wsdl) {
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
Client client = dcf.createClient(wsdl);
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = new HTTPClientPolicy();
policy.setAllowChunking(false);
policy.setConnectionTimeout(150000);
policy.setReceiveTimeout(300000);
conduit.setClient(policy);
return client;
}
protected <T> String covertObjectToXML(T request, Class<T> clazz) throws IOneServiceException {
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Marshaller marshaller = context.createMarshaller();
StringWriter sw = new StringWriter();
marshaller.marshal(request, sw);
return sw.toString();
} catch (JAXBException e) {
throw new IOneServiceException(e);
}
}
protected <T> T convertXMLToObject(String xml, Class<T> clazz) throws IOneServiceException {
try {
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller unmarshaller = context.createUnmarshaller();
T response = (T) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8)));
return response;
} catch (JAXBException e) {
throw new IOneServiceException(e);
}
}
}
package com.i1.erp;
import com.i1.erp.soap.ISrmSoapService;
import com.i1.erp.soap.SrmSoapService;
import org.apache.cxf.Bus;
import org.apache.cxf.jaxws.EndpointImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.xml.ws.Endpoint;
@Configuration
public class WebServiceConfig {
@Autowired
private Bus bus;
@Bean
public ISrmSoapService srmSoapService() {
return new SrmSoapService();
}
// @Bean
// public IPurchaseOrderService purchaseOrderService() {
// return new PurchaseOrderService();
// }
//
// @Bean
// public IQualityControlService qualityControlService() {
// return new QualityControlService();
// }
//
// @Bean
// public IWarehouseVoucherService warehouseVoucherService() {
// return new WarehouseVoucherService();
// }
//
// @Bean
// public IReceiptService receiptService() {
// return new ReceiptService();
// }
//
// @Bean
// public IPoChgService poChgService() {
// return new PoChgService();
// }
//
//
// @Bean
// public Endpoint poEndpoint() {
// EndpointImpl endpoint = new EndpointImpl(bus, purchaseOrderService());
// endpoint.publish("/purchaseOrders");
// return endpoint;
// }
//
// @Bean
// public Endpoint qcEndpoint() {
// EndpointImpl endpoint = new EndpointImpl(bus, qualityControlService());
// endpoint.publish("/qualityControls");
// return endpoint;
// }
//
// @Bean
// public Endpoint wvEndpoint() {
// EndpointImpl endpoint = new EndpointImpl(bus, warehouseVoucherService());
// endpoint.publish("/warehouseVouchers");
// return endpoint;
// }
//
// @Bean
// public Endpoint endpointReceipt() {
// EndpointImpl endpoint = new EndpointImpl(bus, receiptService());
// endpoint.publish("/receipts");
// return endpoint;
// }
//
// @Bean
// public Endpoint poChgEndpoint() {
// EndpointImpl endpoint = new EndpointImpl(bus, poChgService());
// endpoint.publish("/poChgs");
// return endpoint;
// }
@Bean
public Endpoint endpoint() {
EndpointImpl endpoint = new EndpointImpl(bus, srmSoapService());
endpoint.publish("/srmSoaps");
return endpoint;
}
}
package com.i1.erp;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tw.com.dsc.tiptop.tiptopservicegateway.TIPTOPServiceGateWayPortType;
@Configuration
public class WebServiceJaxWsProxyClient {
@Value("${srm.soapWs.wsUrl}")
private String address;
@Bean(name = "tiptopWsProxy")
public TIPTOPServiceGateWayPortType tiptopWsProxy() {
JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
jaxWsProxyFactoryBean.setServiceClass(TIPTOPServiceGateWayPortType.class);
jaxWsProxyFactoryBean.setAddress(address);
TIPTOPServiceGateWayPortType tiptopServiceGateWayPortType = (TIPTOPServiceGateWayPortType) jaxWsProxyFactoryBean.create();
Client client = ClientProxy.getClient(tiptopServiceGateWayPortType);
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = conduit.getClient();
policy.setConnectionTimeout(150000);
policy.setReceiveTimeout(300000);
policy.setAllowChunking(false);
return tiptopServiceGateWayPortType;
}
}
package com.i1.erp.base.service;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class BaseFetchService implements IBaseFetchService {
private Logger logger = LoggerFactory.getLogger(BaseFetchService.class);
@Override
public Map getMapFromXml(String xmlStream) throws ParserConfigurationException, IOException, SAXException {
List<Map<String, String>> mstLit;
List<Map<String, String>> dtlList;
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new ByteArrayInputStream(xmlStream.getBytes(StandardCharsets.UTF_8)));
doc.getDocumentElement().normalize();
mstLit = getNodeChild("MST", doc);
dtlList = getNodeChild("DTL", doc);
return ImmutableMap.of("mstList", mstLit, "dtlList", dtlList);
}
private List<Map<String, String>> getNodeChild(String nodeName, Document doc) {
NodeList nList = doc.getElementsByTagName(nodeName);
List<Map<String, String>> returnList = new ArrayList<>();
//System.out.println("-- get node child list of " + nodeName + " --");
for (int i = 0; i < nList.getLength(); i++) {
Node nParent = nList.item(i);
//System.out.println("---- node child of " + nodeName + "[" + i + "] --");
if (nParent.getNodeType() == Node.ELEMENT_NODE) {
NodeList nChildList = nParent.getChildNodes();
Map<String, String> childMap = new HashMap<>();
for (int j = 0; j < nChildList.getLength(); j++) {
Node nChild = nChildList.item(j);
if (nChild.getNodeType() == Node.ELEMENT_NODE) {
if (nChild.getChildNodes().getLength() <= 1) {
childMap.put(nChild.getNodeName(), nChild.getTextContent());
//System.out.println(" " + nChild.getNodeName() + ":" + nChild.getTextContent());
}
}
}
returnList.add(childMap);
}
}
return returnList;
}
}
package com.i1.erp.base.service;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.util.Map;
public interface IBaseFetchService {
Map getMapFromXml(String xmlStream) throws ParserConfigurationException, IOException, SAXException;
}
package com.i1.erp.base.service;
import com.i1.erp.entity.request.Request;
public interface IProductSyncService {
Request productRequestXml(String imadate, String plant);
}
package com.i1.erp.base.service;
import com.i1.base.exception.IOneServiceException;
import com.i1.erp.entity.request.Request;
public interface ISupplierCheckService {
Request supplierCheckXml(String supplierUid, String abbrName, String supplierName, String type, String plant) throws IOneServiceException;
}
package com.i1.erp.base.service;
import com.i1.base.exception.IOneServiceException;
import com.i1.erp.entity.request.Request;
public interface ISupplierSendService {
Request supplierSendXml(String supplierUid, String plant) throws IOneServiceException;
}
package com.i1.erp.base.service;
import com.i1.erp.entity.request.Request;
public interface ISupplierSyncService {
Request supplierRequestXml(String pmcdate, String plant);
}
package com.i1.erp.base.service;
import com.i1.erp.entity.request.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ProductSyncService implements IProductSyncService {
private Logger logger = LoggerFactory.getLogger(ProductSyncService.class);
@Override
public Request productRequestXml(String imadate, String plant) {
//<Access>
Access access = Access.of(Authentication.of("tiptop", "tiptop"),
Connection.of("SRM", "192.168.1.1"),
Organization.of(plant),
Locale.of("zh_cn"));
//RequestContent
List<Field> fieldList = new ArrayList<>();
fieldList.add(Field.of("imadate", imadate));
fieldList.add(Field.of("plant", plant));
Record record = Record.of(fieldList);
Master mst = Master.of(record, "MST");
RecordSet recordSet = RecordSet.of("1", mst);
List<RecordSet> recordSetList = new ArrayList<>();
recordSetList.add(recordSet);
RequestContent requestContent = new RequestContent();
requestContent.setDocument(Document.of(recordSetList));
requestContent.setParameter(Parameter.of(Record.of(null)));
return Request.of(access, requestContent);
}
}
package com.i1.erp.base.service;
import com.i1.base.exception.IOneServiceException;
import com.i1.erp.entity.request.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class SupplierCheckService implements ISupplierCheckService {
private Logger logger = LoggerFactory.getLogger(SupplierCheckService.class);
@Override
public Request supplierCheckXml(String supplierUid, String abbrName, String supplierName, String type, String plant) throws IOneServiceException {
// if (StringUtils.isBlank(plant)) {
// plant = "DATA";
// }
if (StringUtils.isBlank(plant)) {
throw new IOneServiceException("供应商检测接口:营运中心不能为空");
}
if (StringUtils.isBlank(abbrName)) {
abbrName = "";
}
if (StringUtils.isBlank(type)) {
type = "";
}
if (StringUtils.isBlank(supplierName)) {
throw new IOneServiceException("供应商检测接口:供应商全称不能为空");
}
//<Access>
Access access = Access.of(Authentication.of("017552", "tiptop"),
Connection.of("SRM", "192.168.1.1"),
Organization.of(plant),
Locale.of("zh_cn"));
//RequestContent
List<Field> fieldList = new ArrayList<>();
fieldList.add(Field.of("pmc01", supplierUid));
fieldList.add(Field.of("pmc03", abbrName));
fieldList.add(Field.of("pmc081", supplierName));
//供应商分类
fieldList.add(Field.of("pmc02", type));
fieldList.add(Field.of("plant", plant));
Record record = Record.of(fieldList);
Master mst = Master.of(record, "MST");
RecordSet recordSet = RecordSet.of("1", mst);
List<RecordSet> recordSetList = new ArrayList<>();
recordSetList.add(recordSet);
RequestContent requestContent = new RequestContent();
requestContent.setDocument(Document.of(recordSetList));
requestContent.setParameter(Parameter.of(Record.of(null)));
return Request.of(access, requestContent);
}
private String stringFormat(String str) {
if (StringUtils.isBlank(str)) {
return "";
} else {
return str;
}
}
}
package com.i1.erp.base.service;
import com.i1.base.exception.IOneServiceException;
import com.i1.erp.entity.request.*;
import com.i1.srm.base.dao.entity.BaseSupplierFile;
import com.i1.srm.base.service.IBaseSupplierFileService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Service
public class SupplierSendService implements ISupplierSendService {
private Logger logger = LoggerFactory.getLogger(SupplierSendService.class);
@Autowired
private IBaseSupplierFileService baseSupplierFileService;
@Override
public Request supplierSendXml(String supplierUid, String plant) throws IOneServiceException {
if (StringUtils.isBlank(plant)) {
plant = "DATA";
}
if (StringUtils.isBlank(supplierUid)) {
throw new IOneServiceException("供应商更新ERP接口:供应商不能为空");
}
BaseSupplierFile supplierFile = baseSupplierFileService.findBySupplierUid(supplierUid);
if (supplierFile == null) {
throw new IOneServiceException("供应商更新ERP接口:找不到供应商" + supplierUid);
}
//<Access>
Access access = Access.of(Authentication.of("017552", "tiptop"),
Connection.of("SRM", "192.168.1.1"),
Organization.of(plant),
Locale.of("zh_cn"));
//RequestContent
List<Field> fieldList = new ArrayList<>();
fieldList.add(Field.of("pmc01", supplierFile.getSupplierUid()));
fieldList.add(Field.of("pmc03", stringFormat(supplierFile.getAbbrName())));
fieldList.add(Field.of("pmc081", stringFormat(supplierFile.getName())));
fieldList.add(Field.of("pmc02", "")); //供应商分类
fieldList.add(Field.of("pmc14", "1")); //资料性质 预留字段:默认为1.采购厂商
fieldList.add(Field.of("pmc30", "3")); //厂商性质 预留字段:默认为3.两者
fieldList.add(Field.of("pmc17", supplierFile.getPayConditionDict() == null ? "" : stringFormat(supplierFile.getPayConditionDict().getDictUid())));
fieldList.add(Field.of("pmc49", supplierFile.getPriceConditionDict() == null ? "" : stringFormat(supplierFile.getPriceConditionDict().getDictUid())));
fieldList.add(Field.of("pmc22", supplierFile.getCurrency() == null ? "" : stringFormat(supplierFile.getCurrency().getCurrencyUid())));
fieldList.add(Field.of("pmc47", supplierFile.getUsualCurrencyDict() == null ? "" : stringFormat(supplierFile.getUsualCurrencyDict().getDictUid())));
fieldList.add(Field.of("pmc29", supplierFile.getAccountDate() == null ? "0" : String.valueOf(supplierFile.getAccountDate()))); //结账日 number(5)
fieldList.add(Field.of("pmc908", "")); //地区别 预留字段
fieldList.add(Field.of("pmc07", "")); //国家 预留字段
fieldList.add(Field.of("pmc06", "")); //区域 预留字段
fieldList.add(Field.of("pmc091", stringFormat(supplierFile.getCompAddr()))); //公司地址
fieldList.add(Field.of("pmc092", stringFormat(supplierFile.getIcRegAddr()))); //工商注册地址
fieldList.add(Field.of("pmc093", stringFormat(supplierFile.getManuAddr()))); //生产地址
fieldList.add(Field.of("pmd02", stringFormat(supplierFile.getMainContact())));
fieldList.add(Field.of("pmd03", stringFormat(supplierFile.getMainPhone())));
fieldList.add(Field.of("pmc095", stringFormat(supplierFile.getAcctBankNo()))); //开户银行
fieldList.add(Field.of("pmc56", stringFormat(supplierFile.getAcctId()))); //银行账号
fieldList.add(Field.of("pmccrat", "")); //创建日期 TODO
fieldList.add(Field.of("pmcdate", dateToString(supplierFile.getModiDate()))); //更新日期
fieldList.add(Field.of("pmcud09", stringFormat(supplierFile.getStatus()))); //供应商状态
fieldList.add(Field.of("pmcud08", "1")); //供应商类型:预留字段: 0.临时 1.正式 2.其他,默认为1
fieldList.add(Field.of("pmcud15", dateToString(supplierFile.getCancelDate()))); //停用日期
fieldList.add(Field.of("pmcud05", "")); //合同号 预留字段
Record record = Record.of(fieldList);
Master mst = Master.of(record, "MST");
RecordSet recordSet = RecordSet.of("1", mst);
List<RecordSet> recordSetList = new ArrayList<>();
recordSetList.add(recordSet);
RequestContent requestContent = new RequestContent();
requestContent.setDocument(Document.of(recordSetList));
requestContent.setParameter(Parameter.of(Record.of(null)));
return Request.of(access, requestContent);
}
private String stringFormat(String str) {
if (StringUtils.isBlank(str)) {
return "";
} else {
return str;
}
}
private String dateToString(Date date) {
if (date != null) {
return new SimpleDateFormat("yyyy/MM/dd").format(date);
} else {
return "";
}
}
}
package com.i1.erp.base.service;
import com.i1.erp.entity.request.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class SupplierSyncService implements ISupplierSyncService {
private Logger logger = LoggerFactory.getLogger(SupplierSyncService.class);
@Override
public Request supplierRequestXml(String pmcdate, String plant) {
//<Access>
Access access = Access.of(Authentication.of("tiptop", "tiptop"),
Connection.of("SRM", "192.168.1.1"),
Organization.of(plant),
Locale.of("zh_cn"));
//RequestContent
List<Field> fieldList = new ArrayList<>();
fieldList.add(Field.of("pmcdate", pmcdate));
fieldList.add(Field.of("plant", plant));
Record record = Record.of(fieldList);
Master mst = Master.of(record, "MST");
RecordSet recordSet = RecordSet.of("1", mst);
List<RecordSet> recordSetList = new ArrayList<>();
recordSetList.add(recordSet);
RequestContent requestContent = new RequestContent();
requestContent.setDocument(Document.of(recordSetList));
requestContent.setParameter(Parameter.of(Record.of(null)));
return Request.of(access, requestContent);
}
}
This diff is collapsed.
package com.i1.erp.base.soap;
import com.i1.base.exception.IOneServiceException;
import com.i1.erp.WebServiceClient;
import com.i1.erp.base.service.ISupplierCheckService;
import com.i1.erp.base.web.dto.SyncResponse;
import com.i1.erp.entity.request.Request;
import com.i1.erp.entity.response.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.endpoint.Client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import tw.com.dsc.tiptop.tiptopservicegateway.SRMGyscfRequestSRMGyscfRequest;
import tw.com.dsc.tiptop.tiptopservicegateway.SRMGyscfResponseSRMGyscfResponse;
import tw.com.dsc.tiptop.tiptopservicegateway.TIPTOPServiceGateWayPortType;
import static com.i1.erp.base.web.dto.SyncResponseCode.FAIL_CODE;
import static com.i1.erp.base.web.dto.SyncResponseCode.SUCCESS_CODE;
import static com.i1.srm.utils.SafeType.safeString;
@Component
public class SupplierCheckClient extends WebServiceClient {
@Value("${srm.soapWs.wsDynamicClient}")
public Boolean wsDynamicClient;
@Value("${srm.soapWs.supplierWSDL}")
public String ERP_SUPPLIER_WSDL;
@Value("${srm.soapWs.supplierGyscf}")
public String ERP_SUPPLIER_CF_OP;
@Value("${srm.soapWs.wsUrl}")
private String WS_URL;
private Logger logger = LoggerFactory.getLogger(SupplierCheckClient.class);
@Autowired
private ISupplierCheckService supplierCheckService;
@Autowired
private TIPTOPServiceGateWayPortType tiptopWsProxy;
public SyncResponse check(String supplierUid, String abbrName, String supplierName, String type, String plant) {
try {
logger.info("prepare check supplier {}", supplierUid);
Request xml = null;
try {
xml = supplierCheckService.supplierCheckXml(supplierUid, abbrName, supplierName, type, plant);
} catch (Exception e) {
logger.error("error:", e);
return SyncResponse.of(FAIL_CODE, e.getMessage());
}
if (xml == null) {
logger.error("error:供应商检查无法生成XML结构");
return SyncResponse.of(FAIL_CODE, "供应商检查无法生成XML结构");
}
SRMGyscfRequestSRMGyscfRequest gyscfRequest = new SRMGyscfRequestSRMGyscfRequest();
gyscfRequest.setRequest(covertObjectToXML(xml, Request.class));
logger.info(gyscfRequest.getRequest());
if (wsDynamicClient) {
if (StringUtils.isBlank(ERP_SUPPLIER_WSDL) || StringUtils.isBlank(ERP_SUPPLIER_CF_OP)) {
throw new IOneServiceException("WSDL不可为空.");
}
Client client = getClient(ERP_SUPPLIER_WSDL);
Object[] objects = client.invoke(ERP_SUPPLIER_CF_OP, new Object[]{gyscfRequest});
client.destroy();
if (objects != null && objects.length > 0) {
logger.info(objects[0].toString());
SRMGyscfResponseSRMGyscfResponse originalResponse = (SRMGyscfResponseSRMGyscfResponse) objects[0];
return handleResponse(originalResponse);
} else {
logger.error("ERP无响应.");
return SyncResponse.of(FAIL_CODE, "ERP无响应");
}
} else {
if (StringUtils.isBlank(WS_URL)) {
throw new IOneServiceException("WS address 不可为空.");
}
SRMGyscfResponseSRMGyscfResponse originalResponse = tiptopWsProxy.srmGyscf(gyscfRequest);
return handleResponse(originalResponse);
}
} catch (Exception e) {
logger.error("e", e);
return SyncResponse.of(FAIL_CODE, e.getMessage());
}
}
private SyncResponse handleResponse(SRMGyscfResponseSRMGyscfResponse originalResponse) {
try {
logger.info(originalResponse.getResponse());
Response response = convertXMLToObject(originalResponse.getResponse(), Response.class);
if (response.getExecution().getStatus().getCode().equalsIgnoreCase("0")) {
logger.info("供应商检查成功");
return SyncResponse.of(SUCCESS_CODE, "供应商检查成功");
} else {
String errorDetails = String.format("失败码:%s, 原因: %s, SQL: ",
safeString(response.getExecution().getStatus().getCode()),
safeString(response.getExecution().getStatus().getDescription()),
safeString(response.getExecution().getStatus().getSqlcode()));
logger.error("供应商检查结果失败,{}", errorDetails);
return SyncResponse.of(FAIL_CODE, errorDetails);
}
} catch (IOneServiceException e) {
logger.error("e", e);
return SyncResponse.of(FAIL_CODE, e.getMessage());
}
}
}
package com.i1.erp.base.soap;
import com.i1.base.exception.IOneServiceException;
import com.i1.erp.WebServiceClient;
import com.i1.erp.base.service.ISupplierSendService;
import com.i1.erp.base.web.dto.SyncResponse;
import com.i1.erp.entity.request.Request;
import com.i1.erp.entity.response.Response;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.endpoint.Client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import tw.com.dsc.tiptop.tiptopservicegateway.SRMGongyingshangRequestSRMGongyingshangRequest;
import tw.com.dsc.tiptop.tiptopservicegateway.SRMGongyingshangResponseSRMGongyingshangResponse;
import tw.com.dsc.tiptop.tiptopservicegateway.TIPTOPServiceGateWayPortType;
import static com.i1.erp.base.web.dto.SyncResponseCode.FAIL_CODE;
import static com.i1.erp.base.web.dto.SyncResponseCode.SUCCESS_CODE;
import static com.i1.srm.utils.SafeType.safeString;
@Component
public class SupplierSendClient extends WebServiceClient {
@Value("${srm.soapWs.wsDynamicClient}")
public Boolean wsDynamicClient;
@Value("${srm.soapWs.supplierWSDL}")
public String ERP_SUPPLIER_WSDL;
@Value("${srm.soapWs.supplierGongyingshang}")
public String ERP_SUPPLIER_GYS_OP;
@Value("${srm.soapWs.wsUrl}")
private String WS_URL;
private Logger logger = LoggerFactory.getLogger(SupplierSendClient.class);
@Autowired
private ISupplierSendService supplierSendService;
@Autowired
private TIPTOPServiceGateWayPortType tiptopWsProxy;
//@Scheduled(fixedDelay = 600000)
//@Scheduled(cron = "0 0 10,15,22 * * *")
public void autoSync() {
}
public SyncResponse send(String supplierUid, String plant) {
try {
logger.info("prepare send supplier {}", supplierUid);
Request xml = null;
try {
xml = supplierSendService.supplierSendXml(supplierUid, plant);
} catch (Exception e) {
logger.error("error:", e);
return SyncResponse.of(FAIL_CODE, e.getMessage());
}
if (xml == null) {
logger.error("error:供应商同步无法生成XML结构");
return SyncResponse.of(FAIL_CODE, "供应商同步无法生成XML结构");
}
SRMGongyingshangRequestSRMGongyingshangRequest gongyingshangRequest = new SRMGongyingshangRequestSRMGongyingshangRequest();
gongyingshangRequest.setRequest(covertObjectToXML(xml, Request.class));
logger.info(gongyingshangRequest.getRequest());
if (wsDynamicClient) {
if (StringUtils.isBlank(ERP_SUPPLIER_WSDL) || StringUtils.isBlank(ERP_SUPPLIER_GYS_OP)) {
throw new IOneServiceException("WSDL不可为空.");
}
Client client = getClient(ERP_SUPPLIER_WSDL);
Object[] objects = client.invoke(ERP_SUPPLIER_GYS_OP, new Object[]{gongyingshangRequest});
client.destroy();
if (objects != null && objects.length > 0) {
logger.info(objects[0].toString());
SRMGongyingshangResponseSRMGongyingshangResponse originalResponse = (SRMGongyingshangResponseSRMGongyingshangResponse) objects[0];
return handleResponse(originalResponse);
} else {
logger.error("ERP无响应.");
return SyncResponse.of(FAIL_CODE, "ERP无响应");
}
} else {
if (StringUtils.isBlank(WS_URL)) {
throw new IOneServiceException("WS address 不可为空.");
}
SRMGongyingshangResponseSRMGongyingshangResponse originalResponse = tiptopWsProxy.srmGongyingshang(gongyingshangRequest);
return handleResponse(originalResponse);
}
} catch (Exception e) {
logger.error("e", e);
return SyncResponse.of(FAIL_CODE, e.getMessage());
}
}
private SyncResponse handleResponse(SRMGongyingshangResponseSRMGongyingshangResponse originalResponse) {
try {
logger.info(originalResponse.getResponse());
Response response = convertXMLToObject(originalResponse.getResponse(), Response.class);
if (response.getExecution().getStatus().getCode().equalsIgnoreCase("0")) {
logger.info("供应商同步成功");
return SyncResponse.of(SUCCESS_CODE, "供应商同步成功");
} else {
String errorDetails = String.format("失败码:%s, 原因: %s, SQL: ",
safeString(response.getExecution().getStatus().getCode()),
safeString(response.getExecution().getStatus().getDescription()),
safeString(response.getExecution().getStatus().getSqlcode()));
logger.error("供应商同步失败,{}", errorDetails);
return SyncResponse.of(FAIL_CODE, errorDetails);
}
} catch (IOneServiceException e) {
logger.error("e", e);
return SyncResponse.of(FAIL_CODE, e.getMessage());
}
}
}
This diff is collapsed.
package com.i1.erp.base.web;
import com.i1.erp.base.soap.ProductSyncClient;
import com.i1.erp.base.soap.SupplierCheckClient;
import com.i1.erp.base.soap.SupplierSendClient;
import com.i1.erp.base.soap.SupplierSyncClient;
import com.i1.erp.base.web.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/erpSync")
public class ErpBaseSyncController {
@Autowired
private ProductSyncClient productSyncClient;
@Autowired
private SupplierSyncClient supplierSyncClient;
@Autowired
private SupplierCheckClient supplierCheckClient;
@Autowired
private SupplierSendClient supplierSendClient;
@RequestMapping(value = "/product", method = RequestMethod.POST)
public SyncResponse syncProduct(@RequestBody ProductSyncInput productSyncInput) {
return productSyncClient.manualSync(productSyncInput.getPlant(), productSyncInput.getImadate());
}
@RequestMapping(value = "/supplier", method = RequestMethod.POST)
public SyncResponse syncSupplier(@RequestBody SupplierSyncInput supplierSyncInput) {
return supplierSyncClient.manualSync(supplierSyncInput.getPlant(), supplierSyncInput.getpmcdate());
}
@RequestMapping(value = "/supplierCheck", method = RequestMethod.POST)
public SyncResponse checkSupplier(@RequestBody SupplierCheckInput supplierCheckInput) {
return supplierCheckClient.check(supplierCheckInput.getSuppplierUid(), supplierCheckInput.getAbbrName(), supplierCheckInput.getSupplierName(), supplierCheckInput.getType(), supplierCheckInput.getPlant());
}
@RequestMapping(value = "/supplierSend", method = RequestMethod.POST)
public SyncResponse sendSupplier(@RequestBody SupplierSendInput supplierSendInput) {
return supplierSendClient.send(supplierSendInput.getSuppplierUid(), supplierSendInput.getPlant());
}
}
package com.i1.erp.base.web.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.Date;
@JsonIgnoreProperties(ignoreUnknown = true)
public class ProductSyncInput {
private Date imadate;
private String plant;
public Date getImadate() {
return imadate;
}
public void setImadate(Date imadate) {
this.imadate = imadate;
}
public String getPlant() {
return plant;
}
public void setPlant(String plant) {
this.plant = plant;
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package com.i1.erp.base.web.dto;
public class SyncResponseCode {
public static String FAIL_CODE = "1";
public static String SUCCESS_CODE = "0";
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package com.i1.erp.entity.response;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Parameter {
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment