feat:合并
This commit is contained in:
parent
e4fa2ada44
commit
996c487908
|
@ -1,12 +1,17 @@
|
||||||
package org.jeecg.common.util;
|
package org.jeecg.common.util;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||||
|
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.SymbolConstant;
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
import org.jeecg.modules.base.dto.RuleDto;
|
import org.jeecg.modules.base.dto.RuleDto;
|
||||||
|
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.connection.RedisConnection;
|
import org.springframework.data.redis.connection.RedisConnection;
|
||||||
import org.springframework.data.redis.connection.stream.*;
|
import org.springframework.data.redis.connection.stream.*;
|
||||||
import org.springframework.data.redis.core.*;
|
import org.springframework.data.redis.core.*;
|
||||||
|
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -187,4 +192,23 @@ public class RedisStreamUtil {
|
||||||
return keys;
|
return keys;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRules(Map<String, AlarmRule> ruleMap){
|
||||||
|
Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
// 使Jackson支持Java8的新日期API
|
||||||
|
// objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||||
|
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
||||||
|
jacksonSerializer.setObjectMapper(objectMapper);
|
||||||
|
// 返回批处理的执行结果
|
||||||
|
List<Object> execResult = redisTemplate.executePipelined((RedisConnection connection) -> {
|
||||||
|
Set<String> keySet = ruleMap.keySet();
|
||||||
|
for (String key : keySet) {
|
||||||
|
AlarmRule rule = ruleMap.get(key);
|
||||||
|
connection.set(key.getBytes(),jacksonSerializer.serialize(rule));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import org.jeecg.modules.base.entity.Rule;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
@ -103,4 +104,6 @@ public class AlarmRule implements Serializable {
|
||||||
@TableField(value = "update_by")
|
@TableField(value = "update_by")
|
||||||
private String updateBy;
|
private String updateBy;
|
||||||
|
|
||||||
|
@TableField(exist = false)
|
||||||
|
private Rule rule;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package org.jeecg.common.util;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
|
||||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
|
||||||
import org.jeecg.modules.entity.AlarmRuleAbnormal;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.redis.connection.RedisConnection;
|
|
||||||
import org.springframework.data.redis.core.*;
|
|
||||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class RedisStreamAlarmUtil extends RedisStreamUtil {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate<String,Object> redisTemplate;
|
|
||||||
|
|
||||||
public void setRules(Map<String, AlarmRuleAbnormal> ruleMap){
|
|
||||||
Jackson2JsonRedisSerializer jacksonSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
// 使Jackson支持Java8的新日期API
|
|
||||||
// objectMapper.registerModule(new JavaTimeModule());
|
|
||||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
|
||||||
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
|
|
||||||
jacksonSerializer.setObjectMapper(objectMapper);
|
|
||||||
// 返回批处理的执行结果
|
|
||||||
List<Object> execResult = redisTemplate.executePipelined((RedisConnection connection) -> {
|
|
||||||
Set<String> keySet = ruleMap.keySet();
|
|
||||||
for (String key : keySet) {
|
|
||||||
AlarmRule rule = ruleMap.get(key);
|
|
||||||
connection.set(key.getBytes(),jacksonSerializer.serialize(rule));
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -8,7 +8,6 @@ import org.jeecg.modules.base.entity.monitor.Host;
|
||||||
import org.jeecg.modules.base.entity.monitor.Servers;
|
import org.jeecg.modules.base.entity.monitor.Servers;
|
||||||
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
||||||
import org.jeecg.modules.base.vo.AlarmRuleVo;
|
import org.jeecg.modules.base.vo.AlarmRuleVo;
|
||||||
import org.jeecg.modules.entity.AlarmRuleAbnormal;
|
|
||||||
import org.jeecg.modules.feignclient.MonitorAlarm;
|
import org.jeecg.modules.feignclient.MonitorAlarm;
|
||||||
import org.jeecg.modules.service.IAlarmRuleService;
|
import org.jeecg.modules.service.IAlarmRuleService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -43,13 +42,13 @@ public class AlarmRuleController {
|
||||||
|
|
||||||
@PostMapping("create")
|
@PostMapping("create")
|
||||||
@ApiOperation(value = "新增规则信息", notes = "新增规则信息")
|
@ApiOperation(value = "新增规则信息", notes = "新增规则信息")
|
||||||
public Result create(@RequestBody AlarmRuleAbnormal alarmRule){
|
public Result create(@RequestBody AlarmRule alarmRule){
|
||||||
return alarmRuleService.create(alarmRule);
|
return alarmRuleService.create(alarmRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("update")
|
@PutMapping("update")
|
||||||
@ApiOperation(value = "修改规则信息", notes = "修改规则信息")
|
@ApiOperation(value = "修改规则信息", notes = "修改规则信息")
|
||||||
public Result update(@RequestBody AlarmRuleAbnormal alarmRule){
|
public Result update(@RequestBody AlarmRule alarmRule){
|
||||||
return alarmRuleService.update(alarmRule);
|
return alarmRuleService.update(alarmRule);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
package org.jeecg.modules.entity;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.jeecg.modules.base.entity.Rule;
|
|
||||||
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@TableName(value = "alarm_rule")
|
|
||||||
public class AlarmRuleAbnormal extends AlarmRule {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用于新增报警规则
|
|
||||||
*/
|
|
||||||
@TableField(exist = false)
|
|
||||||
private Rule rule;
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,12 +3,12 @@ package org.jeecg.modules.mapper;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.jeecg.modules.base.dto.AlarmRuleDto;
|
import org.jeecg.modules.base.dto.AlarmRuleDto;
|
||||||
import org.jeecg.modules.base.dto.AlarmRuleInfo;
|
import org.jeecg.modules.base.dto.AlarmRuleInfo;
|
||||||
import org.jeecg.modules.entity.AlarmRuleAbnormal;
|
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface AlarmRuleMapper extends BaseMapper<AlarmRuleAbnormal> {
|
public interface AlarmRuleMapper extends BaseMapper<AlarmRule> {
|
||||||
|
|
||||||
List<AlarmRuleDto> findPage(Map<String, Object> params);
|
List<AlarmRuleDto> findPage(Map<String, Object> params);
|
||||||
|
|
||||||
|
|
|
@ -2,18 +2,18 @@ package org.jeecg.modules.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.jeecg.common.api.vo.Result;
|
import org.jeecg.common.api.vo.Result;
|
||||||
|
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
||||||
import org.jeecg.modules.base.vo.AlarmRuleVo;
|
import org.jeecg.modules.base.vo.AlarmRuleVo;
|
||||||
import org.jeecg.modules.entity.AlarmRuleAbnormal;
|
|
||||||
|
|
||||||
public interface IAlarmRuleService extends IService<AlarmRuleAbnormal> {
|
public interface IAlarmRuleService extends IService<AlarmRule> {
|
||||||
|
|
||||||
Result findPage(AlarmRuleVo alarmRuleVo);
|
Result findPage(AlarmRuleVo alarmRuleVo);
|
||||||
|
|
||||||
Result findInfo(String alarmRuleId);
|
Result findInfo(String alarmRuleId);
|
||||||
|
|
||||||
Result create(AlarmRuleAbnormal alarmRule);
|
Result create(AlarmRule alarmRule);
|
||||||
|
|
||||||
Result update(AlarmRuleAbnormal alarmRule);
|
Result update(AlarmRule alarmRule);
|
||||||
|
|
||||||
Result deleteById(String alarmRuleId);
|
Result deleteById(String alarmRuleId);
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,13 @@ import org.jeecg.common.api.vo.Result;
|
||||||
import org.jeecg.common.constant.CommonConstant;
|
import org.jeecg.common.constant.CommonConstant;
|
||||||
import org.jeecg.common.constant.Prompt;
|
import org.jeecg.common.constant.Prompt;
|
||||||
import org.jeecg.common.constant.SymbolConstant;
|
import org.jeecg.common.constant.SymbolConstant;
|
||||||
import org.jeecg.common.util.RedisStreamAlarmUtil;
|
import org.jeecg.common.util.RedisStreamUtil;
|
||||||
import org.jeecg.modules.base.dto.AlarmRuleDto;
|
import org.jeecg.modules.base.dto.AlarmRuleDto;
|
||||||
import org.jeecg.modules.base.dto.AlarmRuleInfo;
|
import org.jeecg.modules.base.dto.AlarmRuleInfo;
|
||||||
import org.jeecg.modules.base.dto.SourceDto;
|
import org.jeecg.modules.base.dto.SourceDto;
|
||||||
import org.jeecg.modules.base.entity.Rule;
|
import org.jeecg.modules.base.entity.Rule;
|
||||||
|
import org.jeecg.modules.base.entity.postgre.AlarmRule;
|
||||||
import org.jeecg.modules.base.vo.AlarmRuleVo;
|
import org.jeecg.modules.base.vo.AlarmRuleVo;
|
||||||
import org.jeecg.modules.entity.AlarmRuleAbnormal;
|
|
||||||
import org.jeecg.modules.mapper.AlarmRuleMapper;
|
import org.jeecg.modules.mapper.AlarmRuleMapper;
|
||||||
import org.jeecg.modules.service.IAlarmRuleService;
|
import org.jeecg.modules.service.IAlarmRuleService;
|
||||||
import org.jeecg.modules.service.ISysDatabaseService;
|
import org.jeecg.modules.service.ISysDatabaseService;
|
||||||
|
@ -34,10 +34,10 @@ import java.util.Map;
|
||||||
import static org.jeecg.modules.base.enums.SourceType.*;
|
import static org.jeecg.modules.base.enums.SourceType.*;
|
||||||
|
|
||||||
@Service("alarmRuleService")
|
@Service("alarmRuleService")
|
||||||
public class AlarmRuleServiceImpl extends ServiceImpl<AlarmRuleMapper, AlarmRuleAbnormal> implements IAlarmRuleService {
|
public class AlarmRuleServiceImpl extends ServiceImpl<AlarmRuleMapper, AlarmRule> implements IAlarmRuleService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisStreamAlarmUtil redisStreamUtil;
|
private RedisStreamUtil redisStreamUtil;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ISysEmailService emailService;
|
private ISysEmailService emailService;
|
||||||
|
@ -73,7 +73,7 @@ public class AlarmRuleServiceImpl extends ServiceImpl<AlarmRuleMapper, AlarmRule
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result create(AlarmRuleAbnormal alarmRule) {
|
public Result create(AlarmRule alarmRule) {
|
||||||
Rule rule = alarmRule.getRule();
|
Rule rule = alarmRule.getRule();
|
||||||
if (ObjectUtil.isNotNull(rule)){
|
if (ObjectUtil.isNotNull(rule)){
|
||||||
String operator = JSON.toJSONString(rule);
|
String operator = JSON.toJSONString(rule);
|
||||||
|
@ -85,10 +85,10 @@ public class AlarmRuleServiceImpl extends ServiceImpl<AlarmRuleMapper, AlarmRule
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result update(AlarmRuleAbnormal alarmRule) {
|
public Result update(AlarmRule alarmRule) {
|
||||||
LambdaQueryWrapper<AlarmRuleAbnormal> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<AlarmRule> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(AlarmRuleAbnormal::getId, alarmRule.getId());
|
wrapper.eq(AlarmRule::getId, alarmRule.getId());
|
||||||
AlarmRuleAbnormal alarmRuleOld = this.baseMapper.selectOne(wrapper);
|
AlarmRule alarmRuleOld = this.baseMapper.selectOne(wrapper);
|
||||||
if (ObjectUtil.isNull(alarmRuleOld)){
|
if (ObjectUtil.isNull(alarmRuleOld)){
|
||||||
return Result.error(Prompt.DATA_NOT_EXITS);
|
return Result.error(Prompt.DATA_NOT_EXITS);
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ public class AlarmRuleServiceImpl extends ServiceImpl<AlarmRuleMapper, AlarmRule
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result updateStatus(String alarmRuleId,Integer enabled) {
|
public Result updateStatus(String alarmRuleId,Integer enabled) {
|
||||||
AlarmRuleAbnormal alarmRule = new AlarmRuleAbnormal();
|
AlarmRule alarmRule = new AlarmRule();
|
||||||
alarmRule.setId(alarmRuleId);
|
alarmRule.setId(alarmRuleId);
|
||||||
alarmRule.setEnabled(enabled);
|
alarmRule.setEnabled(enabled);
|
||||||
if (updateById(alarmRule))
|
if (updateById(alarmRule))
|
||||||
|
@ -142,12 +142,12 @@ public class AlarmRuleServiceImpl extends ServiceImpl<AlarmRuleMapper, AlarmRule
|
||||||
String colon = SymbolConstant.COLON;
|
String colon = SymbolConstant.COLON;
|
||||||
String prefixRule = CommonConstant.PREFIX_RULE;
|
String prefixRule = CommonConstant.PREFIX_RULE;
|
||||||
String prefixSilence = CommonConstant.PREFIX_SILENCE;
|
String prefixSilence = CommonConstant.PREFIX_SILENCE;
|
||||||
LambdaQueryWrapper<AlarmRuleAbnormal> wrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<AlarmRule> wrapper = new LambdaQueryWrapper<>();
|
||||||
wrapper.eq(AlarmRuleAbnormal::getEnabled,1);
|
wrapper.eq(AlarmRule::getEnabled,1);
|
||||||
List<AlarmRuleAbnormal> alarmRules = this.list(wrapper);
|
List<AlarmRule> alarmRules = this.list(wrapper);
|
||||||
Map<String, AlarmRuleAbnormal> ruleMap = new HashMap<>();
|
Map<String, AlarmRule> ruleMap = new HashMap<>();
|
||||||
Map<String, Long> silenceMap = new HashMap<>();
|
Map<String, Long> silenceMap = new HashMap<>();
|
||||||
for (AlarmRuleAbnormal alarmRule : alarmRules) {
|
for (AlarmRule alarmRule : alarmRules) {
|
||||||
String sourceType = alarmRule.getSourceType();
|
String sourceType = alarmRule.getSourceType();
|
||||||
String ruleId = alarmRule.getId();
|
String ruleId = alarmRule.getId();
|
||||||
Long silence = alarmRule.getSilenceCycle();
|
Long silence = alarmRule.getSilenceCycle();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.jeecg.modules.email;
|
package org.jeecg.modules.email;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jeecg.modules.base.entity.SysEmailLog;
|
import org.jeecg.modules.base.entity.postgre.SysEmailLog;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package org.jeecg.modules.email;
|
package org.jeecg.modules.email;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.jeecg.modules.base.entity.SysEmail;
|
import org.jeecg.modules.base.entity.postgre.SysEmail;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.jeecg.modules.mapper;
|
package org.jeecg.modules.mapper;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.jeecg.modules.base.entity.SysEmail;
|
import org.jeecg.modules.base.entity.postgre.SysEmail;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 邮件数据表Mapper
|
* 邮件数据表Mapper
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.jeecg.modules.service;
|
package org.jeecg.modules.service;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import org.jeecg.modules.base.entity.SysEmail;
|
import org.jeecg.modules.base.entity.postgre.SysEmail;
|
||||||
import org.jeecg.modules.email.EmailProperties;
|
import org.jeecg.modules.email.EmailProperties;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jeecg.common.email.emuns.SysMailType;
|
import org.jeecg.common.email.emuns.SysMailType;
|
||||||
import org.jeecg.modules.base.entity.SysEmail;
|
import org.jeecg.modules.base.entity.postgre.SysEmail;
|
||||||
import org.jeecg.modules.email.EmailProperties;
|
import org.jeecg.modules.email.EmailProperties;
|
||||||
import org.jeecg.modules.emuns.SysMailEnableType;
|
import org.jeecg.modules.emuns.SysMailEnableType;
|
||||||
import org.jeecg.modules.mapper.SysMailMapper;
|
import org.jeecg.modules.mapper.SysMailMapper;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.jeecg.modules.spectrum;
|
package org.jeecg.modules.spectrum;
|
||||||
|
|
||||||
import org.jeecg.modules.base.entity.GardsSampleData;
|
import org.jeecg.modules.base.entity.original.GardsSampleData;
|
||||||
import org.jeecg.modules.native_jni.struct.EnergySpectrumStruct;
|
import org.jeecg.modules.native_jni.struct.EnergySpectrumStruct;
|
||||||
|
|
||||||
public class SpecturmDataStorage {
|
public class SpecturmDataStorage {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user