Merge branch 'develop' into feat/new_ui

pull/1422/head
smily 2 years ago
commit 8eb0420103

@ -120,7 +120,8 @@ For full documentation & more details, visit: [Docs](https://www.hippo4j.cn)
- [[ JavaGuide ]](https://github.com/Snailclimb/JavaGuide):一份涵盖大部分 Java 程序员所需要掌握的核心知识。 - [[ JavaGuide ]](https://github.com/Snailclimb/JavaGuide):一份涵盖大部分 Java 程序员所需要掌握的核心知识。
- [[ toBeBetterJavaer ]](https://github.com/itwanger/toBeBetterJavaer):一份通俗易懂、风趣幽默的 Java 学习指南。 - [[ toBeBetterJavaer ]](https://github.com/itwanger/toBeBetterJavaer):一份通俗易懂、风趣幽默的 Java 学习指南。
- [[ Jpom ]](https://gitee.com/dromara/Jpom):简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件。 - [[ Jpom ]](https://gitee.com/dromara/Jpom):简而轻的低侵入式在线构建、自动部署、日常运维、项目监控软件。
- [[ CongoMall ]](https://gitee.com/opengoofy/congomall):作者的另一个开源项目刚果商城,包含了商城业务和基础架构两大模块。 - [[ 12306 ]](https://gitee.com/nageoffer/12306):完成高仿 12306 用户+抢票+订单+支付服务,帮助学生主打就业的项目。
- [[ CongoMall ]](https://gitee.com/nageoffer/congomall):企业级商城,基于 DDD 领域驱动模型开发,包含商城业务和基础架构。
### 贡献者 ### 贡献者

@ -107,8 +107,8 @@ const config = {
activeBaseRegex: `/community/`, activeBaseRegex: `/community/`,
}, },
/*{ to: "/team", label: "团队", position: "left" },*/ /*{ to: "/team", label: "团队", position: "left" },*/
{ to: '/users', label: '采用公司', position: 'left' }, {to: '/users', label: '采用公司', position: 'left'},
{ to: '/group', label: '加群沟通', position: 'left' }, {to: '/group', label: '加群沟通', position: 'left'},
/*{to: '/blog', label: '博客', position: 'left'},*/ /*{to: '/blog', label: '博客', position: 'left'},*/
{ {
href: 'http://console.hippo4j.cn/index.html', href: 'http://console.hippo4j.cn/index.html',
@ -116,8 +116,8 @@ const config = {
position: 'left', position: 'left',
}, },
{ {
href: 'https://gitee.com/opengoofy/congomall', href: 'https://magestack.cn',
label: '👉 刚果商城', label: '🚀 拿个offer',
position: 'left', position: 'left',
}, },
{ {
@ -126,7 +126,7 @@ const config = {
dropdownActiveClassDisabled: true, dropdownActiveClassDisabled: true,
}, },
{ type: 'localeDropdown', position: 'right' }, {type: 'localeDropdown', position: 'right'},
/*{ /*{
href: 'https://gitee.com/mabaiwancn/hippo4j', href: 'https://gitee.com/mabaiwancn/hippo4j',
label: 'Gitee', label: 'Gitee',
@ -195,10 +195,6 @@ const config = {
{ {
title: 'Links', title: 'Links',
items: [ items: [
{
label: '书源',
href: 'https://bookyuan.cn/',
},
{ {
label: '推广合作', label: '推广合作',
href: 'https://hippo4j.cn/docs/user_docs/other/operation', href: 'https://hippo4j.cn/docs/user_docs/other/operation',
@ -206,7 +202,7 @@ const config = {
], ],
}, },
], ],
copyright: `Copyright © 2021-2022 马丁版权所有 <a href="https://beian.miit.gov.cn">京ICP备2021038095号 copyright: `Copyright © 2021-2023 马丁版权所有 <a href="https://beian.miit.gov.cn">京ICP备2021038095号
</a>`, </a>`,
}, },
prism: { prism: {

@ -5,7 +5,7 @@ title: 采用公司
## 谁在使用 Hippo4j ## 谁在使用 Hippo4j
共计 39+ 家公司生产接入 Hippo4j按照公司登记时间排序。 共计 42+ 家公司生产接入 Hippo4j按照公司登记时间排序。
- [身边云](https://serviceshare.com) - [身边云](https://serviceshare.com)
- [思派健康科技](https://www.medbanks.cn) - [思派健康科技](https://www.medbanks.cn)
@ -46,6 +46,9 @@ title: 采用公司
- [广联达科技股份有限公司](https://www.glodon.com) - [广联达科技股份有限公司](https://www.glodon.com)
- [天健联创控股集团有限公司](https://www.tjlc.com.cn) - [天健联创控股集团有限公司](https://www.tjlc.com.cn)
- [知乎](https://www.zhihu.com/) - [知乎](https://www.zhihu.com/)
- [广东谷通科技有限公司](https://www.duofriend.com)
- [成都全域智旅科技有限公司](http://qyzl.com)
- [深圳市华云中盛科技股份有限公司](http://www.hua-cloud.cn)
## 登记 ## 登记

@ -5,7 +5,7 @@ title: 采用公司
## 谁在使用 Hippo4j ## 谁在使用 Hippo4j
共计 39+ 家公司生产接入 Hippo4j按照公司登记时间排序。 共计 42+ 家公司生产接入 Hippo4j按照公司登记时间排序。
- [身边云](https://serviceshare.com) - [身边云](https://serviceshare.com)
- [思派健康科技](https://www.medbanks.cn) - [思派健康科技](https://www.medbanks.cn)
@ -46,6 +46,9 @@ title: 采用公司
- [广联达科技股份有限公司](https://www.glodon.com) - [广联达科技股份有限公司](https://www.glodon.com)
- [天健联创控股集团有限公司](https://www.tjlc.com.cn) - [天健联创控股集团有限公司](https://www.tjlc.com.cn)
- [知乎](https://www.zhihu.com/) - [知乎](https://www.zhihu.com/)
- [广东谷通科技有限公司](https://www.duofriend.com)
- [成都全域智旅科技有限公司](http://qyzl.com)
- [深圳市华云中盛科技股份有限公司](http://www.hua-cloud.cn)
## 登记 ## 登记

@ -0,0 +1,94 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.common.executor.support;
import cn.hippo4j.common.toolkit.ThreadPoolExecutorUtil;
import lombok.extern.slf4j.Slf4j;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Thread pool executor util test
*/
@Slf4j
public class ThreadPoolExecutorUtilTest {
private ThreadPoolExecutor executor;
private int corePoolSize;
private int maxPoolSize;
@Before
public void testSafeSetPoolSize() {
corePoolSize = 2;
maxPoolSize = 4;
executor = new ThreadPoolExecutor(
corePoolSize,
maxPoolSize,
1L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(10));
}
@Test
public void testEquals() {
// Test when the new core pool size equals the original maximum pool size.
int newCorePoolSize1 = maxPoolSize;
int newMaxPoolSize1 = 6;
ThreadPoolExecutorUtil.safeSetPoolSize(executor, newCorePoolSize1, newMaxPoolSize1);
Assert.assertEquals(newCorePoolSize1, executor.getCorePoolSize());
Assert.assertEquals(newMaxPoolSize1, executor.getMaximumPoolSize());
}
@Test
public void testGreater() {
// Test when the new core pool size is greater than the original maximum pool size.
int newCorePoolSize2 = 8;
int newMaxPoolSize2 = 10;
ThreadPoolExecutorUtil.safeSetPoolSize(executor, newCorePoolSize2, newMaxPoolSize2);
Assert.assertEquals(newCorePoolSize2, executor.getCorePoolSize());
Assert.assertEquals(newMaxPoolSize2, executor.getMaximumPoolSize());
}
@Test
public void testLess() {
// Test when the new core pool size is less than the original maximum pool size.
int newCorePoolSize3 = 3;
int newMaxPoolSize3 = 5;
ThreadPoolExecutorUtil.safeSetPoolSize(executor, newCorePoolSize3, newMaxPoolSize3);
Assert.assertEquals(newCorePoolSize3, executor.getCorePoolSize());
Assert.assertEquals(newMaxPoolSize3, executor.getMaximumPoolSize());
}
@Test
public void testException() {
// Test when the new core pool size is greater than the new maximum pool size, which should throw an IllegalArgumentException.
int newCorePoolSize4 = 6;
int newMaxPoolSize4 = 4;
try {
ThreadPoolExecutorUtil.safeSetPoolSize(executor, newCorePoolSize4, newMaxPoolSize4);
} catch (IllegalArgumentException e) {
// Expected to throw an exception.
Assert.assertEquals("newCorePoolSize must be smaller than newMaximumPoolSize", e.getMessage());
log.error("newCorePoolSize must be smaller than newMaximumPoolSize;{}", e.getMessage());
}
}
}

@ -27,7 +27,6 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
/** /**
* Micrometer monitor auto configuration. * Micrometer monitor auto configuration.

@ -45,6 +45,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -136,7 +137,7 @@ public class ReportingEventExecutor implements Runnable, CommandLineRunner, Disp
properties.getCollectInterval(), properties.getCollectInterval(),
TimeUnit.MILLISECONDS); TimeUnit.MILLISECONDS);
Integer bufferSize = properties.getTaskBufferSize(); Integer bufferSize = properties.getTaskBufferSize();
messageCollectVessel = new ArrayBlockingQueue(bufferSize); messageCollectVessel = new LinkedBlockingQueue(bufferSize);
// Get all data collection components, currently only historical operation data collection. // Get all data collection components, currently only historical operation data collection.
collectors = ApplicationContextHolder.getBeansOfType(Collector.class); collectors = ApplicationContextHolder.getBeansOfType(Collector.class);
// Start reporting monitoring data thread. // Start reporting monitoring data thread.

@ -78,6 +78,20 @@ public class AdaptedThreadPoolDestroyPostProcessor implements DestructionAwareBe
.ifPresent(executorHolder -> destroyAdaptedThreadPoolExecutor(beanName, executorHolder)); .ifPresent(executorHolder -> destroyAdaptedThreadPoolExecutor(beanName, executorHolder));
} }
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// forked default implementation from spring-beans-5.1.14.RELEASE.jar
// org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// forked default implementation from spring-beans-5.1.14.RELEASE.jar
// org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
return bean;
}
private void destroyAdaptedThreadPoolExecutor(String beanName, ThreadPoolExecutorHolder executorHolder) { private void destroyAdaptedThreadPoolExecutor(String beanName, ThreadPoolExecutorHolder executorHolder) {
try { try {
if (log.isDebugEnabled()) { if (log.isDebugEnabled()) {

@ -744,6 +744,7 @@ export default {
} else if (value === 5) { } else if (value === 5) {
this.temp.capacity = 2147483647; this.temp.capacity = 2147483647;
} }
this.$forceUpdate();
}, },
tenantSelectList() { tenantSelectList() {

@ -128,6 +128,7 @@ export default {
if (hostname === 'console.hippo4j.cn') { if (hostname === 'console.hippo4j.cn') {
this.loginForm.username = 'hippo4j'; this.loginForm.username = 'hippo4j';
this.loginForm.password = 'hippo4j'; this.loginForm.password = 'hippo4j';
this.rememberMe = 1;
} }
console.log(hostname); console.log(hostname);
}, },

@ -58,8 +58,10 @@ public class AdapterThreadPoolMicrometerMonitorHandler extends AbstractAdapterTh
Tag.of(APPLICATION_NAME_TAG, applicationName)); Tag.of(APPLICATION_NAME_TAG, applicationName));
Metrics.gauge(metricName("core.size"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getCoreSize); Metrics.gauge(metricName("core.size"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getCoreSize);
Metrics.gauge(metricName("maximum.size"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getMaximumSize); Metrics.gauge(metricName("maximum.size"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getMaximumSize);
if (threadPoolAdapterState.getBlockingQueueCapacity() != null) {
Metrics.gauge(metricName("queue.capacity"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getBlockingQueueCapacity); Metrics.gauge(metricName("queue.capacity"), tags, threadPoolAdapterState, ThreadPoolAdapterState::getBlockingQueueCapacity);
} }
}
private String metricName(String name) { private String metricName(String name) {
return String.join(".", METRIC_NAME_PREFIX, name); return String.join(".", METRIC_NAME_PREFIX, name);

@ -62,5 +62,9 @@
<artifactId>hippo4j-threadpool-server-common</artifactId> <artifactId>hippo4j-threadpool-server-common</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-ldap</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -20,6 +20,7 @@ package cn.hippo4j.auth.config;
import cn.hippo4j.auth.constant.Constants; import cn.hippo4j.auth.constant.Constants;
import cn.hippo4j.auth.filter.JWTAuthenticationFilter; import cn.hippo4j.auth.filter.JWTAuthenticationFilter;
import cn.hippo4j.auth.filter.JWTAuthorizationFilter; import cn.hippo4j.auth.filter.JWTAuthorizationFilter;
import cn.hippo4j.auth.filter.LdapAuthenticationFilter;
import cn.hippo4j.auth.security.JwtTokenManager; import cn.hippo4j.auth.security.JwtTokenManager;
import cn.hippo4j.auth.service.impl.UserDetailsServiceImpl; import cn.hippo4j.auth.service.impl.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -28,6 +29,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.BeanIds; import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity;
@ -54,9 +56,12 @@ public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
@Value("${hippo4j.core.auth.enabled:true}") @Value("${hippo4j.core.auth.enabled:true}")
private Boolean enableAuthentication; private Boolean enableAuthentication;
@Resource @Resource(name = "userDetailsServiceImpl")
private UserDetailsService userDetailsService; private UserDetailsService userDetailsService;
@Resource(name = "ldapUserDetailsServiceImpl")
private UserDetailsService ldapUserDetailsService;
@Resource @Resource
private JwtTokenManager tokenManager; private JwtTokenManager tokenManager;
@ -93,7 +98,9 @@ public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
.antMatchers("/static/**", "/index.html", "/favicon.ico", "/avatar.jpg").permitAll() .antMatchers("/static/**", "/index.html", "/favicon.ico", "/avatar.jpg").permitAll()
.antMatchers("/doc.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs").anonymous() .antMatchers("/doc.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs").anonymous()
.and() .and()
.addFilter(new JWTAuthenticationFilter(authenticationManager())) // .addFilter(new JWTAuthenticationFilter(authenticationManager())).authenticationProvider(authenticationProvider())
.addFilter(JWTAuthenticationFilter()).authenticationProvider(ldapAuthenticationProvider())
.addFilter(LdapAuthenticationFilter()).authenticationProvider(ldapAuthenticationProvider())
.addFilter(new JWTAuthorizationFilter(tokenManager, authenticationManager())) .addFilter(new JWTAuthorizationFilter(tokenManager, authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
disableAuthenticationIfNeeded(http); disableAuthenticationIfNeeded(http);
@ -106,6 +113,20 @@ public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
web.ignoring().antMatchers(ignores); web.ignoring().antMatchers(ignores);
} }
private LdapAuthenticationFilter LdapAuthenticationFilter() throws Exception {
LdapAuthenticationFilter filter = new LdapAuthenticationFilter(authenticationManager());
filter.setLdapUserDetailsService(ldapUserDetailsService);
filter.setAuthenticationManager(authenticationManagerBean());
return filter;
}
private JWTAuthenticationFilter JWTAuthenticationFilter() throws Exception {
JWTAuthenticationFilter filter = new JWTAuthenticationFilter(authenticationManager());
filter.setLdapUserDetailsService(userDetailsService);
filter.setAuthenticationManager(authenticationManagerBean());
return filter;
}
/** /**
* Injection DaoAuthenticationProvider * Injection DaoAuthenticationProvider
* Modify hideUserNotFoundExceptions initial value to false * Modify hideUserNotFoundExceptions initial value to false
@ -120,6 +141,20 @@ public class GlobalSecurityConfig extends WebSecurityConfigurerAdapter {
return provider; return provider;
} }
@Bean
public DaoAuthenticationProvider ldapAuthenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(ldapUserDetailsService);
authProvider.setPasswordEncoder(bCryptPasswordEncoder());
return authProvider;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(authenticationProvider())
.authenticationProvider(ldapAuthenticationProvider());
}
private void disableAuthenticationIfNeeded(HttpSecurity http) throws Exception { private void disableAuthenticationIfNeeded(HttpSecurity http) throws Exception {
if (Boolean.FALSE.equals(enableAuthentication)) { if (Boolean.FALSE.equals(enableAuthentication)) {
http.authorizeRequests().antMatchers("/hippo4j/v1/cs/**").permitAll(); http.authorizeRequests().antMatchers("/hippo4j/v1/cs/**").permitAll();

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;
import java.util.HashMap;
import java.util.Map;
/**
* Ldap config.
*/
@Configuration
public class LdapConfiguration {
private LdapTemplate ldapTemplate;
@Value("${spring.ldap.urls:}")
private String url;
@Value("${spring.ldap.base:}")
private String base;
@Value("${spring.ldap.embedded.credential.username:}")
private String username;
@Value("${spring.ldap.embedded.credential.password:}")
private String password;
@Bean
public LdapContextSource contextSource() {
LdapContextSource contextSource = new LdapContextSource();
Map<String, Object> config = new HashMap<>(10);
contextSource.setUrl(url);
contextSource.setBase(base);
contextSource.setUserDn(username);
contextSource.setPassword(password);
// fix garbled characters
config.put("java.naming.ldap.attributes.binary", "objectGUID");
contextSource.setPooled(true);
contextSource.setBaseEnvironmentProperties(config);
return contextSource;
}
@Bean
public LdapTemplate ldapTemplate() {
if (null == ldapTemplate) {
ldapTemplate = new LdapTemplate(contextSource());
}
return ldapTemplate;
}
}

@ -25,23 +25,25 @@ import cn.hippo4j.auth.toolkit.ReturnT;
import cn.hippo4j.common.toolkit.JSONUtil; import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.server.common.base.Results; import cn.hippo4j.server.common.base.Results;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.core.codec.DecodingException; import org.springframework.core.codec.DecodingException;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import javax.servlet.FilterChain; import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.IOException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -60,11 +62,18 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
private final ThreadLocal<Integer> rememberMe = new ThreadLocal(); private final ThreadLocal<Integer> rememberMe = new ThreadLocal();
private UserDetailsService userDetailsService;
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) { public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager; this.authenticationManager = authenticationManager;
super.setFilterProcessesUrl(BASE_PATH + "/auth/login"); super.setFilterProcessesUrl(BASE_PATH + "/auth/login");
} }
public void setLdapUserDetailsService(UserDetailsService userDetailsServiceImpl) {
this.userDetailsService = userDetailsServiceImpl;
}
@SneakyThrows
@Override @Override
public Authentication attemptAuthentication(HttpServletRequest request, public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) throws AuthenticationException { HttpServletResponse response) throws AuthenticationException {
@ -78,8 +87,9 @@ public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilte
request.setAttribute("loginUser", loginUser); request.setAttribute("loginUser", loginUser);
rememberMe.set(loginUser.getRememberMe()); rememberMe.set(loginUser.getRememberMe());
authenticate = authenticationManager.authenticate( UserDetails userDetails = userDetailsService.loadUserByUsername(loginUser.getUsername());
new UsernamePasswordAuthenticationToken(loginUser.getUsername(), loginUser.getPassword(), new ArrayList())); authenticate = new PreAuthenticatedAuthenticationToken(userDetails, null, userDetails.getAuthorities());
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
log.warn("Password decode exception: {}", e.getMessage()); log.warn("Password decode exception: {}", e.getMessage());
throw new DecodingException(e.getMessage()); throw new DecodingException(e.getMessage());

@ -0,0 +1,155 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.filter;
import cn.hippo4j.auth.model.biz.user.JwtUser;
import cn.hippo4j.auth.model.biz.user.LoginUser;
import cn.hippo4j.auth.toolkit.AESUtil;
import cn.hippo4j.auth.toolkit.JwtTokenUtil;
import cn.hippo4j.auth.toolkit.ReturnT;
import cn.hippo4j.common.toolkit.JSONUtil;
import cn.hippo4j.server.common.base.Results;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import static cn.hippo4j.auth.constant.Constants.SPLIT_COMMA;
import static cn.hippo4j.common.constant.Constants.BASE_PATH;
import static cn.hippo4j.common.constant.Constants.MAP_INITIAL_CAPACITY;
/**
* Ldap Filter
*/
@Slf4j
public class LdapAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private final ThreadLocal<Integer> rememberMe = new ThreadLocal<>();
private UserDetailsService ldapUserDetailsService;
public void setLdapUserDetailsService(UserDetailsService ldapUserDetailsServiceImpl) {
this.ldapUserDetailsService = ldapUserDetailsServiceImpl;
}
public LdapAuthenticationFilter(AuthenticationManager authenticationManager) {
super.setFilterProcessesUrl(BASE_PATH + "/auth/ldap/login");
}
/**
* Whether it's just the post way
*/
private boolean postOnly = true;
/**
* filter obtains the username and password of LDAP and assembles it on the token.
* Then give the token for authorization
*/
@Override
public Authentication attemptAuthentication(HttpServletRequest request
, HttpServletResponse response) throws AuthenticationException {
if (postOnly && !"POST".equals(request.getMethod())) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} else {
// Get logged in information from the input stream.
Authentication authenticate = null;
try {
LoginUser loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class);
String key = new StringBuffer(loginUser.getTag()).reverse().toString();
String password = AESUtil.decrypt(loginUser.getPassword(), key);
loginUser.setPassword(password);
request.setAttribute("loginUser", loginUser);
rememberMe.set(loginUser.getRememberMe());
// ldap validated
UserDetails userDetails = ldapUserDetailsService.loadUserByUsername(loginUser.getUsername());
authenticate = new PreAuthenticatedAuthenticationToken(userDetails, null, userDetails.getAuthorities());
} catch (UsernameNotFoundException e) {
log.debug("User {} not found", e.getMessage());
throw e;
} catch (BadCredentialsException e) {
log.debug("Bad credentials exception: {}", e.getMessage());
throw e;
} catch (Exception e) {
log.debug("Attempt authentication error", e);
}
return authenticate;
}
}
@Override
protected void successfulAuthentication(HttpServletRequest request,
HttpServletResponse response,
FilterChain chain,
Authentication authResult) throws IOException {
try {
JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
boolean isRemember = rememberMe.get() == 1;
String role = "";
Collection<? extends GrantedAuthority> authorities = jwtUser.getAuthorities();
for (GrantedAuthority authority : authorities) {
role = authority.getAuthority();
}
String token = JwtTokenUtil.createToken(jwtUser.getId(), jwtUser.getUsername(), role, isRemember);
response.setHeader("token", JwtTokenUtil.TOKEN_PREFIX + token);
response.setCharacterEncoding("UTF-8");
Map<String, Object> maps = new HashMap<>(MAP_INITIAL_CAPACITY);
maps.put("data", JwtTokenUtil.TOKEN_PREFIX + token);
maps.put("roles", role.split(SPLIT_COMMA));
response.getWriter().write(JSONUtil.toJSONString(Results.success(maps)));
} finally {
rememberMe.remove();
}
}
@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) throws IOException {
response.setCharacterEncoding("UTF-8");
response.getWriter().write(JSONUtil.toJSONString(new ReturnT<>(ReturnT.JWT_FAIL_CODE, getMessage(failed))));
}
/**
* Return different echo information to the front end according to different exception types
*/
private String getMessage(AuthenticationException failed) {
String message = "Server Error";
if (failed instanceof UsernameNotFoundException) {
message = "用户不存在";
} else if (failed instanceof BadCredentialsException) {
message = "密码错误";
}
return message;
}
}

@ -0,0 +1,39 @@
package cn.hippo4j.auth.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.annotations.Entry;
import org.springframework.ldap.odm.annotations.Id;
import javax.naming.Name;
@Data
@Entry(objectClasses = {"inetOrgPerson", "top"})
public class LdapUserInfo {
@JsonIgnore
@Id
private Name dn;
@Attribute(name = "cn")
@DnAttribute(value = "cn")
private String userName;
@Attribute(name = "sn")
private String lastName;
@Attribute(name = "description")
private String description;
@Attribute(name = "telephoneNumber")
private String telephoneNumber;
@Attribute(name = "userPassword")
private String password;
@Attribute(name = "ou")
private String organizational;
}

@ -0,0 +1,28 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.service;
/**
* Ldap service.
*/
public interface LdapService {
/**
* Login ldap
*/
void login(String username, String password);
}

@ -0,0 +1,72 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.service.impl;
import cn.hippo4j.auth.service.LdapService;
import cn.hippo4j.server.common.base.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.ldap.AuthenticationException;
import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.query.LdapQueryBuilder;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import static org.springframework.ldap.query.LdapQueryBuilder.query;
@Service
@Slf4j
public class LdapServiceImpl implements LdapService {
private final LdapTemplate ldapTemplate;
@Value("${spring.ldap.object-class:}")
private String objectClassName;
@Value("${spring.ldap.account-attribute:}")
private String accountAttribute;
public LdapServiceImpl(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
@Override
public void login(String username, String password) {
try {
ldapTemplate.authenticate(LdapQueryBuilder.query()
.where(accountAttribute).is(username)
.and(query().where("objectClass").is(objectClassName))
, password);
log.debug("{} ldap Login successful", username);
} catch (EmptyResultDataAccessException e) {
throw new UsernameNotFoundException("ldap Can't find the user information ");
} catch (AuthenticationException e) {
log.debug("The user name or account error");
throw new BadCredentialsException("The username or password error");
} catch (UncategorizedLdapException e) {
log.debug("Please check whether the user name password input");
throw new BadCredentialsException("Please check whether the username password input");
} catch (Exception e) {
throw new ServiceException("Abnormal server");
}
}
}

@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.auth.service.impl;
import cn.hippo4j.auth.mapper.UserMapper;
import cn.hippo4j.auth.model.UserInfo;
import cn.hippo4j.auth.model.biz.user.JwtUser;
import cn.hippo4j.auth.model.biz.user.LoginUser;
import cn.hippo4j.auth.service.LdapService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
/**
* User details service impl.
*/
@Slf4j
@Service
public class LdapUserDetailsServiceImpl implements UserDetailsService {
@Value("${hippo4j.core.auth.enabled:true}")
private Boolean enableAuthentication;
@Resource
private UserMapper userMapper;
@Resource
private LdapService ldapService;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
JwtUser anonymous = dealWithAnonymous();
if (!Objects.isNull(anonymous)) {
return anonymous;
}
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(requestAttributes)).getRequest();
LoginUser loginUser = (LoginUser) request.getAttribute("loginUser");
// ldap authentication
ldapService.login(userName, loginUser.getPassword());
// By querying the data inventory this user does not exist
UserInfo userInfo = userMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class)
.eq(UserInfo::getUserName, userName)
);
// the database does not, create a ROLE_USER permission to the default user, password is empty
if (Objects.isNull(userInfo)) {
userInfo = new UserInfo();
userInfo.setPassword("");
userInfo.setUserName(loginUser.getUsername());
userInfo.setRole("ROLE_USER");
userMapper.insert(userInfo);
}
// structure jwtUser
JwtUser jwtUser = new JwtUser();
jwtUser.setId(userInfo.getId());
jwtUser.setUsername(userName);
jwtUser.setPassword("");
Set<SimpleGrantedAuthority> authorities = Collections.singleton(new SimpleGrantedAuthority(userInfo.getRole() + ""));
jwtUser.setAuthorities(authorities);
return jwtUser;
}
private JwtUser dealWithAnonymous() {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
if (requestAttributes == null) {
return null;
}
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
LoginUser loginUser = (LoginUser) request.getAttribute("loginUser");
if (Objects.isNull(loginUser)) {
return null;
}
if (Boolean.FALSE.equals(enableAuthentication)) {
JwtUser jwtUser = new JwtUser();
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
jwtUser.setId(1L);
jwtUser.setUsername("anonymous");
jwtUser.setPassword(bCryptPasswordEncoder.encode(loginUser.getPassword()));
Set<SimpleGrantedAuthority> authorities = Collections.singleton(new SimpleGrantedAuthority("ROLE_ADMIN"));
jwtUser.setAuthorities(authorities);
return jwtUser;
}
return null;
}
}

@ -24,11 +24,13 @@ import cn.hippo4j.auth.model.biz.user.LoginUser;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestAttributes; import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.context.request.ServletRequestAttributes;
@ -43,6 +45,7 @@ import java.util.Set;
* User details service impl. * User details service impl.
*/ */
@Slf4j @Slf4j
@Service
public class UserDetailsServiceImpl implements UserDetailsService { public class UserDetailsServiceImpl implements UserDetailsService {
@Value("${hippo4j.core.auth.enabled:true}") @Value("${hippo4j.core.auth.enabled:true}")
@ -57,10 +60,20 @@ public class UserDetailsServiceImpl implements UserDetailsService {
if (!Objects.isNull(anonymous)) { if (!Objects.isNull(anonymous)) {
return anonymous; return anonymous;
} }
UserInfo userInfo = userMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserName, userName)); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
LoginUser loginUser = (LoginUser) request.getAttribute("loginUser");
String loginPassword = loginUser.getPassword();
UserInfo userInfo = userMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class)
.eq(UserInfo::getUserName, userName)
);
if (Objects.isNull(userInfo)) { if (Objects.isNull(userInfo)) {
throw new UsernameNotFoundException(userName); throw new UsernameNotFoundException(userName);
} }
// Validation password
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
if (!bCryptPasswordEncoder.matches(loginPassword, userInfo.getPassword())) {
throw new BadCredentialsException(userName + "密码错误,请重新输入");
}
JwtUser jwtUser = new JwtUser(); JwtUser jwtUser = new JwtUser();
jwtUser.setId(userInfo.getId()); jwtUser.setId(userInfo.getId());
jwtUser.setUsername(userName); jwtUser.setUsername(userName);

@ -0,0 +1,20 @@
package cn.hippo4j.auth.toolkit;
import cn.hippo4j.common.toolkit.Assert;
import org.junit.Test;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
public class BCryptPasswordEncoderTest {
@Test
public void bCryptPasswordEncoderTest() {
String password = "12345abc";
BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
String encode = bCryptPasswordEncoder.encode(password);
boolean matches = bCryptPasswordEncoder.matches(password, encode);
Assert.isTrue(matches);
}
}

@ -0,0 +1,14 @@
#*************** Ldap Sample Configurations ***************#
### This configuration file does not take effect
### Change the LDAP server information to yourself
### Configure the following configuration file into application.properties
# Ldap Config
spring.ldap.urls=ldap://127.0.0.1:389
spring.ldap.base=dc=xxx,dc=com
spring.ldap.embedded.credential.username=cn=xxxx,dc=xxx,dc=com
spring.ldap.embedded.credential.password=password
# Ldap Entry object-class
spring.ldap.object-class=person
# Ldap account-attribute CommonName ( cn / uid / username / ... )
spring.ldap.account-attribute=cn

@ -0,0 +1,100 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cn.hippo4j.server.common.base;
import cn.hippo4j.common.toolkit.Assert;
import cn.hippo4j.server.common.base.exception.ErrorCode;
import cn.hippo4j.server.common.base.exception.ErrorCodeEnum;
import cn.hippo4j.server.common.base.exception.ServiceException;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import org.checkerframework.checker.units.qual.A;
import org.junit.jupiter.api.Test;
import java.util.Objects;
/**
* Service exception test
*/
public class ServiceExceptionTest {
@Test
public void ServiceExceptionTest1() {
ServiceException serviceException = new ServiceException();
Assert.isTrue(Objects.equals(serviceException.getErrorCode().getCode(), "3"));
Assert.isTrue(Objects.equals(serviceException.getMessage(), "SERVICE_ERROR"));
}
@Test
public void ServiceExceptionTest2() {
ErrorCode errorCode = ErrorCodeEnum.LOGIN_TIMEOUT;
ServiceException serviceException = new ServiceException(errorCode);
Assert.isTrue(Objects.equals(serviceException.getErrorCode().getCode(), ErrorCodeEnum.LOGIN_TIMEOUT.getCode()));
Assert.isTrue(Objects.equals(serviceException.getMessage(), ErrorCodeEnum.LOGIN_TIMEOUT.getMessage()));
}
@Test
public void ServiceExceptionTest3() {
String message = ErrorCodeEnum.SERVICE_ERROR.getMessage();
ServiceException serviceException = new ServiceException(message);
Assert.isTrue(Objects.equals(serviceException.getMessage(), message));
}
@Test
public void ServiceExceptionTest4() {
Throwable cause = new Throwable();
ServiceException serviceException = new ServiceException(cause);
Assert.isTrue(Objects.equals(serviceException.getCause().getMessage(), cause.getMessage()));
}
@Test
public void ServiceExceptionTest5() {
String message = ErrorCodeEnum.SERVICE_ERROR.getMessage();
Throwable cause = new Throwable();
ServiceException serviceException = new ServiceException(message, cause);
Assert.isTrue(Objects.equals(serviceException.getCause().getMessage(), cause.getMessage()));
Assert.isTrue(Objects.equals(serviceException.getMessage(), message));
}
@Test
public void ServiceExceptionTest6() {
String message = ErrorCodeEnum.SERVICE_ERROR.getMessage();
Throwable cause = new Throwable();
ServiceException serviceException = new ServiceException(cause, message);
Assert.isTrue(Objects.equals(serviceException.getCause().getMessage(), cause.getMessage()));
Assert.isTrue(Objects.equals(serviceException.getMessage(), message));
}
@Test
public void ServiceExceptionTest7() {
Throwable cause = new Throwable();
ErrorCode errorCode = ErrorCodeEnum.LOGIN_TIMEOUT;
ServiceException serviceException = new ServiceException(cause, errorCode);
Assert.isTrue(Objects.equals(serviceException.getCause().getMessage(), cause.getMessage()));
Assert.isTrue(Objects.equals(serviceException.getErrorCode().getCode(), ErrorCodeEnum.LOGIN_TIMEOUT.getCode()));
}
@Test
public void ServiceExceptionTest8() {
Throwable cause = new Throwable();
ErrorCode errorCode = ErrorCodeEnum.LOGIN_TIMEOUT;
String message = ErrorCodeEnum.SERVICE_ERROR.getMessage();
ServiceException serviceException = new ServiceException(message, cause, errorCode);
Assert.isTrue(Objects.equals(serviceException.getCause().getMessage(), cause.getMessage()));
Assert.isTrue(Objects.equals(serviceException.getErrorCode().getCode(), ErrorCodeEnum.LOGIN_TIMEOUT.getCode()));
Assert.isTrue(Objects.equals(serviceException.getMessage(), message));
}
}

@ -47,8 +47,8 @@ public class Lease<T> {
public Lease(T r) { public Lease(T r) {
holder = r; holder = r;
registrationTimestamp = System.currentTimeMillis(); registrationTimestamp = System.currentTimeMillis();
lastUpdateTimestamp = registrationTimestamp;
duration = DEFAULT_DURATION_IN_SECS; duration = DEFAULT_DURATION_IN_SECS;
lastUpdateTimestamp = registrationTimestamp + duration;
} }
public void renew() { public void renew() {

Loading…
Cancel
Save