2019-01-02 11:59:25 +06:00
|
|
|
|
package com.nis.util;
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2019-01-02 17:17:15 +06:00
|
|
|
|
import java.util.Date;
|
2019-01-02 11:59:25 +06:00
|
|
|
|
import java.util.List;
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
|
|
2019-01-02 17:17:15 +06:00
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
2019-01-02 11:59:25 +06:00
|
|
|
|
import com.google.common.collect.Lists;
|
2019-01-02 17:17:15 +06:00
|
|
|
|
import com.nis.domain.configuration.AppPolicyCfg;
|
2019-01-02 11:59:25 +06:00
|
|
|
|
import com.nis.domain.configuration.AvFileSampleCfg;
|
|
|
|
|
|
import com.nis.domain.configuration.AvSignSampleCfg;
|
|
|
|
|
|
import com.nis.domain.configuration.BaseCfg;
|
|
|
|
|
|
import com.nis.domain.configuration.CfgIndexInfo;
|
|
|
|
|
|
import com.nis.domain.configuration.DnsIpCfg;
|
|
|
|
|
|
import com.nis.domain.configuration.DnsResStrategy;
|
2019-01-02 17:17:15 +06:00
|
|
|
|
import com.nis.domain.configuration.FileDigestCfg;
|
2019-01-02 11:59:25 +06:00
|
|
|
|
import com.nis.domain.configuration.IpPortCfg;
|
|
|
|
|
|
import com.nis.domain.configuration.PxyObjKeyring;
|
|
|
|
|
|
import com.nis.domain.configuration.PxyObjTrustedCaCert;
|
|
|
|
|
|
import com.nis.domain.configuration.PxyObjTrustedCaCrl;
|
2019-01-02 17:17:15 +06:00
|
|
|
|
import com.nis.domain.maat.MaatCfg;
|
|
|
|
|
|
import com.nis.domain.maat.ToMaatBean;
|
|
|
|
|
|
import com.nis.domain.maat.ToMaatResult;
|
|
|
|
|
|
import com.nis.domain.maat.ToUpdateMaatBeanStatus;
|
|
|
|
|
|
import com.nis.domain.maat.MaatCfg.DigestCfg;
|
|
|
|
|
|
import com.nis.domain.maat.MaatCfg.GroupCfg;
|
|
|
|
|
|
import com.nis.domain.maat.MaatCfg.IpCfg;
|
|
|
|
|
|
import com.nis.domain.maat.MaatCfg.NumBoundaryCfg;
|
|
|
|
|
|
import com.nis.domain.maat.MaatCfg.StringCfg;
|
|
|
|
|
|
import com.nis.domain.maat.ToUpdateMaatBeanStatus.UpdateMaatCfgStatus;
|
2019-01-02 11:59:25 +06:00
|
|
|
|
import com.nis.web.dao.configuration.ConfigSynchronizationDao;
|
|
|
|
|
|
import com.nis.web.service.BaseService;
|
|
|
|
|
|
import com.nis.web.service.SpringContextHolder;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 配置任务调度通用类
|
|
|
|
|
|
* 定时任务调用,处理界面配置状态修改,以及下发综合服务处理
|
|
|
|
|
|
* @author ThinkPad
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
|
|
|
|
|
public class SchedulerTaskUtil {
|
|
|
|
|
|
|
|
|
|
|
|
//调度任务的配置信息,复用配置同步DAO
|
|
|
|
|
|
private static ConfigSynchronizationDao configSynchronizationDao = SpringContextHolder.getBean(ConfigSynchronizationDao.class);
|
2019-01-02 17:17:15 +06:00
|
|
|
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
2019-01-02 11:59:25 +06:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据业务与编译ID查询配置,修改失效或生效状态,并下发至综合服务
|
|
|
|
|
|
* @param serviceId 不可空
|
|
|
|
|
|
* @param compileId 不可空
|
|
|
|
|
|
* @param oldIsValid 配置当前状态 0无效,1有效,可空
|
|
|
|
|
|
* @param newIsValid 配置最新修改状态 0无效,1有效,不可空
|
|
|
|
|
|
* @return boolean
|
|
|
|
|
|
*/
|
|
|
|
|
|
public boolean updateConfigByServiceAndCompile(Integer serviceId,Integer compileId,Integer oldIsValid,Integer newIsValid){
|
|
|
|
|
|
//根据业务查询配置文件,获取该业务的配置域表信息
|
|
|
|
|
|
ServiceConfigTemplateUtil serviceTemplate = new ServiceConfigTemplateUtil();
|
|
|
|
|
|
List<Map<String,Object>> serviceList = serviceTemplate.getServiceListByServiceId(serviceId);
|
|
|
|
|
|
//根据编译ID查询配置表中的配置信息
|
|
|
|
|
|
for(Map<String,Object> service:serviceList){
|
|
|
|
|
|
String tableName = service.get("tableName").toString();
|
|
|
|
|
|
String serviceType = service.get("serviceType").toString();
|
|
|
|
|
|
String className = service.get("className").toString();
|
|
|
|
|
|
BaseCfg entity = new BaseCfg();
|
|
|
|
|
|
entity.setServiceId(serviceId);
|
|
|
|
|
|
entity.setTableName(tableName);
|
|
|
|
|
|
List list = Lists.newArrayList();
|
2019-01-02 17:17:15 +06:00
|
|
|
|
List callBackCfgList = Lists.newArrayList();
|
|
|
|
|
|
boolean isUpdateContent = false;
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 根据编译ID查询配置,如果配置当前审核状态为未审核(is_audit=0),并且newIsValid=1需要查询详细的域配置信息,下发配置详细内容,
|
|
|
|
|
|
* 如果已审核(is_audit=1),则只查询配置主表,更新配置状态即可,
|
|
|
|
|
|
* 如果审核取消(is_audit=3)则删除定时任务,表示配置已最终删除,此状态处理原则上在配置修改拦截器中处理
|
|
|
|
|
|
*/
|
2019-01-02 11:59:25 +06:00
|
|
|
|
if("1".equals(serviceType)){//maat类配置
|
2019-01-02 17:17:15 +06:00
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
//下发并修改配置状态的参数类
|
|
|
|
|
|
ToUpdateMaatBeanStatus maatStatusBean = new ToUpdateMaatBeanStatus();
|
|
|
|
|
|
UpdateMaatCfgStatus updateCfg = new UpdateMaatCfgStatus();
|
|
|
|
|
|
List<UpdateMaatCfgStatus> configCompileStartStopList = new ArrayList();
|
|
|
|
|
|
maatStatusBean.setVersion(Constants.MAAT_VERSION);
|
|
|
|
|
|
maatStatusBean.setOpAction(Constants.INSERT_ACTION);
|
|
|
|
|
|
maatStatusBean.setAuditTime(updateTime);
|
|
|
|
|
|
maatStatusBean.setCreatorName("TaskScheduler");//任务调度定时修改状态
|
|
|
|
|
|
|
|
|
|
|
|
//下发带有配置内容的参数对象
|
|
|
|
|
|
ToMaatBean maatBean = new ToMaatBean();
|
|
|
|
|
|
MaatCfg maatCfg = new MaatCfg();
|
|
|
|
|
|
List<MaatCfg> configCompileList = new ArrayList();
|
|
|
|
|
|
List<GroupCfg> groupRelationList = new ArrayList();
|
|
|
|
|
|
List<IpCfg> ipRegionList = new ArrayList();
|
|
|
|
|
|
List<StringCfg> strRegionList = new ArrayList();
|
|
|
|
|
|
List<NumBoundaryCfg> numRegionList = new ArrayList();
|
|
|
|
|
|
List<DigestCfg> digestRegionList = new ArrayList();
|
|
|
|
|
|
List<IpCfg> areaIpRegionList = new ArrayList();
|
|
|
|
|
|
|
|
|
|
|
|
// for(Integer compileId:compileIds){
|
|
|
|
|
|
entity.setCompileId(compileId);
|
|
|
|
|
|
//查询配置
|
|
|
|
|
|
if("cfg_index_info".equals(tableName)){
|
|
|
|
|
|
list = configSynchronizationDao.getCfgIndexList(entity);
|
|
|
|
|
|
List<Map<String,Object>> cfgList = (List<Map<String, Object>>) service.get("cfgList");
|
2019-01-02 11:59:25 +06:00
|
|
|
|
for(int i=0;i<list.size();i++){
|
|
|
|
|
|
CfgIndexInfo cfg = (CfgIndexInfo) list.get(i);
|
2019-01-02 17:17:15 +06:00
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
//需要查询详细的域配置信息,下发配置内容,并修改数据库is_valid=1,is_audit=1
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改状态与当前配置状态不符合业务逻辑!");
|
|
|
|
|
|
}
|
|
|
|
|
|
}else{//修改各个配置域的配置状态
|
|
|
|
|
|
BaseCfg config = new BaseCfg();
|
|
|
|
|
|
config.setIsValid(newIsValid);
|
|
|
|
|
|
config.setEditTime(updateTime);
|
|
|
|
|
|
config.setCompileId(cfg.getCompileId());
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
if(cfgList!=null){
|
|
|
|
|
|
for(Map<String,Object> m:cfgList){
|
|
|
|
|
|
String regionTableName = m.get("tableName").toString();
|
|
|
|
|
|
config.setTableName(regionTableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|
2019-01-02 17:17:15 +06:00
|
|
|
|
}else if("file_digest_cfg".equals(tableName)){
|
|
|
|
|
|
list = configSynchronizationDao.getFileDigestListByService(entity);
|
|
|
|
|
|
List<Map<String,Object>> cfgList = (List<Map<String, Object>>) service.get("cfgList");
|
2019-01-02 11:59:25 +06:00
|
|
|
|
for(int i=0;i<list.size();i++){
|
2019-01-02 17:17:15 +06:00
|
|
|
|
FileDigestCfg cfg = (FileDigestCfg) list.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
//需要查询详细的域配置信息,下发配置内容,并修改数据库is_valid=1,is_audit=1
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改状态与当前配置状态不符合业务逻辑!");
|
|
|
|
|
|
}
|
|
|
|
|
|
}else{//修改各个配置域的配置状态
|
|
|
|
|
|
BaseCfg config = new BaseCfg();
|
|
|
|
|
|
config.setIsValid(newIsValid);
|
|
|
|
|
|
config.setEditTime(updateTime);
|
|
|
|
|
|
config.setCompileId(cfg.getCompileId());
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
if(cfgList!=null){
|
|
|
|
|
|
for(Map<String,Object> m:cfgList){
|
|
|
|
|
|
String regionTableName = m.get("tableName").toString();
|
|
|
|
|
|
config.setTableName(regionTableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|
2019-01-02 17:17:15 +06:00
|
|
|
|
|
|
|
|
|
|
}else if("app_policy_cfg".equals(tableName)){
|
|
|
|
|
|
list = configSynchronizationDao.getAppPolicyList(entity);
|
|
|
|
|
|
List<Map<String,Object>> cfgList = (List<Map<String, Object>>) service.get("cfgList");
|
2019-01-02 11:59:25 +06:00
|
|
|
|
for(int i=0;i<list.size();i++){
|
2019-01-02 17:17:15 +06:00
|
|
|
|
AppPolicyCfg cfg = (AppPolicyCfg) list.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
//需要查询详细的域配置信息,下发配置内容,并修改数据库is_valid=1,is_audit=1
|
|
|
|
|
|
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改状态与当前配置状态不符合业务逻辑!");
|
|
|
|
|
|
}
|
|
|
|
|
|
}else{//修改各个配置域的配置状态
|
|
|
|
|
|
BaseCfg config = new BaseCfg();
|
|
|
|
|
|
config.setIsValid(newIsValid);
|
|
|
|
|
|
config.setEditTime(updateTime);
|
|
|
|
|
|
config.setCompileId(cfg.getCompileId());
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
if(cfgList!=null){
|
|
|
|
|
|
for(Map<String,Object> m:cfgList){
|
|
|
|
|
|
String regionTableName = m.get("tableName").toString();
|
|
|
|
|
|
config.setTableName(regionTableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-02 17:17:15 +06:00
|
|
|
|
}
|
|
|
|
|
|
if(!isUpdateContent){
|
|
|
|
|
|
updateCfg.setIsValid(newIsValid);
|
|
|
|
|
|
updateCfg.setCompileId(compileId);
|
|
|
|
|
|
updateCfg.setAuditTime(updateTime);
|
|
|
|
|
|
configCompileStartStopList.add(updateCfg);
|
|
|
|
|
|
}
|
|
|
|
|
|
// }
|
|
|
|
|
|
if(isUpdateContent){//修改配置内容以及状态
|
|
|
|
|
|
//下发配置内容
|
|
|
|
|
|
|
|
|
|
|
|
}else{//只修改配置状态
|
|
|
|
|
|
maatStatusBean.setConfigCompileStartStopList(configCompileStartStopList);
|
|
|
|
|
|
String json=BaseService.gsonToJson(maatBean);
|
|
|
|
|
|
//调用服务启停接口
|
|
|
|
|
|
String result = ConfigServiceUtil.configStatusUpdate(json);
|
|
|
|
|
|
logger.debug("MAAT类配置启停状态修改结果:"+result);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}else if("2".equals(serviceType)){//回调类配置
|
|
|
|
|
|
List ids = Lists.newArrayList();
|
|
|
|
|
|
// for(Integer compileId:compileIds){
|
|
|
|
|
|
entity.setCompileId(compileId);
|
|
|
|
|
|
//查询配置
|
|
|
|
|
|
if(entity.getServiceId().equals(3)){//ip drop回调类配置用了主表和子表关系
|
|
|
|
|
|
list = configSynchronizationDao.getCfgIndexList(entity);
|
|
|
|
|
|
if(!StringUtil.isEmpty(list)){
|
|
|
|
|
|
List<Integer> compileIdArray = Lists.newArrayList();
|
|
|
|
|
|
for(int i=0;i<list.size();i++){
|
|
|
|
|
|
CfgIndexInfo cfg = (CfgIndexInfo) list.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
cfg.setIsAudit(1);
|
|
|
|
|
|
cfg.setAuditTime(updateTime);
|
|
|
|
|
|
cfg.setTableName(tableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
}
|
|
|
|
|
|
compileIdArray.add(cfg.getCompileId());
|
|
|
|
|
|
}
|
|
|
|
|
|
List subList = configSynchronizationDao.getIpDropList("ip_port_cfg", compileIdArray);
|
|
|
|
|
|
for(int i=0;i<subList.size();i++){
|
|
|
|
|
|
IpPortCfg cfg = (IpPortCfg) subList.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
cfg.setIsValid(newIsValid);
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
cfg.setIsAudit(1);
|
|
|
|
|
|
cfg.setAuditTime(updateTime);
|
|
|
|
|
|
cfg.setTableName("ip_port_cfg");
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
callBackCfgList.add(BaseService.convertCallBackIp(cfg,cfg.getGroupId()));
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改与配置当前状态不符合业务逻辑");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-01-02 17:17:15 +06:00
|
|
|
|
}else{
|
|
|
|
|
|
if(className.equals("AvFileSampleCfg")){
|
|
|
|
|
|
list = configSynchronizationDao.getAvFileCfgList(entity);
|
|
|
|
|
|
for(int i=0;i<list.size();i++){
|
|
|
|
|
|
AvFileSampleCfg cfg = (AvFileSampleCfg) list.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
cfg.setIsValid(newIsValid);
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
cfg.setIsAudit(1);
|
|
|
|
|
|
cfg.setAuditTime(updateTime);
|
|
|
|
|
|
cfg.setTableName(tableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
callBackCfgList.add(cfg);
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改与配置当前状态不符合业务逻辑");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}else if(className.equals("AvSignSampleCfg")){//音视频场景配置
|
|
|
|
|
|
list = configSynchronizationDao.getAvSignCfgList(entity);
|
|
|
|
|
|
for(int i=0;i<list.size();i++){
|
|
|
|
|
|
AvSignSampleCfg cfg = (AvSignSampleCfg) list.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
cfg.setIsValid(newIsValid);
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
cfg.setIsAudit(1);
|
|
|
|
|
|
cfg.setAuditTime(updateTime);
|
|
|
|
|
|
cfg.setTableName(tableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
callBackCfgList.add(cfg);
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改与配置当前状态不符合业务逻辑");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}else if(className.equals("IpPortCfg")){
|
|
|
|
|
|
list = configSynchronizationDao.getIpPortListByService(entity);
|
|
|
|
|
|
for(int i=0;i<list.size();i++){
|
|
|
|
|
|
IpPortCfg cfg = (IpPortCfg) list.get(i);
|
|
|
|
|
|
if(cfg.getIsAudit()==0){
|
|
|
|
|
|
isUpdateContent = true;
|
|
|
|
|
|
cfg.setIsValid(newIsValid);
|
|
|
|
|
|
if(newIsValid==1){
|
|
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
cfg.setIsAudit(1);
|
|
|
|
|
|
cfg.setAuditTime(updateTime);
|
|
|
|
|
|
cfg.setTableName(tableName);
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(cfg);//修改界面数据库配置状态
|
|
|
|
|
|
callBackCfgList.add(BaseService.convertCallBackIp(cfg,cfg.getGroupId()));
|
|
|
|
|
|
}else{
|
|
|
|
|
|
logger.debug("配置修改与配置当前状态不符合业务逻辑");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2019-01-02 17:17:15 +06:00
|
|
|
|
if(!isUpdateContent){//如果没有内容修改,则只更新状态
|
|
|
|
|
|
Date updateTime = new Date();
|
|
|
|
|
|
BaseCfg updateCfg = new BaseCfg();
|
|
|
|
|
|
updateCfg.setIsValid(newIsValid);
|
|
|
|
|
|
updateCfg.setCompileId(compileId);
|
|
|
|
|
|
updateCfg.setServiceId(serviceId);
|
|
|
|
|
|
updateCfg.setAuditTime(updateTime);
|
|
|
|
|
|
updateCfg.setEditTime(updateTime);
|
|
|
|
|
|
updateCfg.setCreatorName("TaskScheduler");
|
|
|
|
|
|
configSynchronizationDao.updateCfgStatus(updateCfg);//修改界面数据库配置状态
|
|
|
|
|
|
callBackCfgList.add(updateCfg);
|
|
|
|
|
|
}
|
|
|
|
|
|
// }
|
|
|
|
|
|
if(!StringUtil.isEmpty(callBackCfgList)){
|
|
|
|
|
|
//调用服务接口下发配置数据
|
|
|
|
|
|
String json=BaseService.gsonToJson(callBackCfgList);
|
|
|
|
|
|
//调用服务接口修改回调类配置状态
|
|
|
|
|
|
ToMaatResult result = ConfigServiceUtil.put(json,2);
|
|
|
|
|
|
logger.debug("回调类配置启停状态修改结果:"+result);
|
|
|
|
|
|
}
|
2019-01-02 11:59:25 +06:00
|
|
|
|
|
|
|
|
|
|
}
|
2019-01-02 17:17:15 +06:00
|
|
|
|
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2019-01-02 17:17:15 +06:00
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
|
|
|
|
|
|
|
}
|
2019-01-02 11:59:25 +06:00
|
|
|
|
}
|