mirror of
https://github.com/chatopera/cosin.git
synced 2025-07-16 00:22:22 +08:00
https://github.com/cskefu/cskefu/issues/937 init license schema as metakv
Signed-off-by: Hai Liang Wang <hai@chatopera.com>
This commit is contained in:
parent
e69dfd398d
commit
629abe88d2
@ -88,6 +88,7 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>3.1.3</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
|
@ -217,4 +217,13 @@ public class Constants {
|
||||
public static final String AUTH_TOKEN_TYPE_BEARER = "Bearer";
|
||||
public static final String AUTH_TOKEN_TYPE_BASIC = "Basic";
|
||||
|
||||
/**
|
||||
* License
|
||||
*/
|
||||
public static final String LICENSE_SERVER_INST_ID = "SERVERINSTID";
|
||||
public static final String LICENSE_SERVICE_NAME = "SERVICENAME";
|
||||
public static final String LICENSE_SERVICE_NAME_PREFIX = "春松客服";
|
||||
public static final String LICENSES = "LICENSES";
|
||||
public static final String METAKV_DATATYPE_STRING = "string";
|
||||
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import com.cskefu.cc.model.BlackEntity;
|
||||
import com.cskefu.cc.model.SysDic;
|
||||
import com.cskefu.cc.model.SystemConfig;
|
||||
import com.cskefu.cc.persistence.repository.*;
|
||||
import com.cskefu.cc.proxy.LicenseProxy;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -36,7 +37,6 @@ public class AppCtxRefreshEventListener implements ApplicationListener<ContextRe
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(AppCtxRefreshEventListener.class);
|
||||
|
||||
|
||||
private void setupSysdicCacheAndExtras(final ContextRefreshedEvent event, final String cacheSetupStrategy, final Cache cache, final SysDicRepository sysDicRes, final BlackListRepository blackListRes) {
|
||||
if (!StringUtils.equalsIgnoreCase(cacheSetupStrategy, Constants.cache_setup_strategy_skip)) {
|
||||
|
||||
@ -138,6 +138,9 @@ public class AppCtxRefreshEventListener implements ApplicationListener<ContextRe
|
||||
logger.info("[Plugins] registered plugin id {}, class {}", p.getPluginId(), p.getClass().getName());
|
||||
}
|
||||
|
||||
// 初始化 ServerInstId
|
||||
LicenseProxy licenseProxy = event.getApplicationContext().getBean(LicenseProxy.class);
|
||||
licenseProxy.checkOnStartup();
|
||||
} else {
|
||||
logger.info("[onApplicationEvent] bypass, initialization has been done already.");
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ import jakarta.persistence.EntityManager;
|
||||
import jakarta.persistence.PersistenceContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.validation.Valid;
|
||||
import java.sql.Connection;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -31,7 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -31,7 +31,6 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.domain.Specification;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
@ -0,0 +1,77 @@
|
||||
package com.cskefu.cc.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 存储元数据
|
||||
*/
|
||||
@Entity
|
||||
@Table(name = "cs_metakv")
|
||||
@org.hibernate.annotations.Proxy(lazy = false)
|
||||
public class Metakv implements java.io.Serializable {
|
||||
|
||||
@Id
|
||||
private String metakey;
|
||||
|
||||
private String metavalue;
|
||||
|
||||
private String datatype;
|
||||
|
||||
private String comment;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date updatetime;
|
||||
|
||||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date createtime;
|
||||
|
||||
public String getMetakey() {
|
||||
return metakey;
|
||||
}
|
||||
|
||||
public void setMetakey(String metakey) {
|
||||
this.metakey = metakey;
|
||||
}
|
||||
|
||||
public String getMetavalue() {
|
||||
return metavalue;
|
||||
}
|
||||
|
||||
public void setMetavalue(String metavalue) {
|
||||
this.metavalue = metavalue;
|
||||
}
|
||||
|
||||
public String getDatatype() {
|
||||
return datatype;
|
||||
}
|
||||
|
||||
public void setDatatype(String datatype) {
|
||||
this.datatype = datatype;
|
||||
}
|
||||
|
||||
public String getComment() {
|
||||
return comment;
|
||||
}
|
||||
|
||||
public void setComment(String comment) {
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
public Date getUpdatetime() {
|
||||
return updatetime;
|
||||
}
|
||||
|
||||
public void setUpdatetime(Date updatetime) {
|
||||
this.updatetime = updatetime;
|
||||
}
|
||||
|
||||
public Date getCreatetime() {
|
||||
return createtime;
|
||||
}
|
||||
|
||||
public void setCreatetime(Date createtime) {
|
||||
this.createtime = createtime;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
|
||||
* <https://www.chatopera.com>, Licensed under the Chunsong Public
|
||||
* License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html
|
||||
* 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 com.cskefu.cc.persistence.repository;
|
||||
|
||||
import com.cskefu.cc.model.Metakv;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public interface MetakvRepository extends JpaRepository<Metakv, String> {
|
||||
|
||||
Optional<Metakv> findFirstByMetakey(final String p1);
|
||||
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Beijing Huaxia Chunsong Technology Co., Ltd.
|
||||
* <https://www.chatopera.com>, Licensed under the Chunsong Public
|
||||
* License, Version 1.0 (the "License"), https://docs.cskefu.com/licenses/v1.html
|
||||
* 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 com.cskefu.cc.proxy;
|
||||
|
||||
import com.cskefu.cc.basic.Constants;
|
||||
import com.cskefu.cc.basic.MainUtils;
|
||||
import com.cskefu.cc.model.Metakv;
|
||||
import com.cskefu.cc.persistence.repository.MetakvRepository;
|
||||
import com.cskefu.cc.util.Base62;
|
||||
import org.json.JSONArray;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Optional;
|
||||
|
||||
@Service
|
||||
public class LicenseProxy {
|
||||
private final static Logger logger = LoggerFactory.getLogger(LicenseProxy.class);
|
||||
|
||||
@Autowired
|
||||
private MetakvRepository metkvRes;
|
||||
|
||||
/**
|
||||
* 初始化 serverinstId
|
||||
* serverinstId 作为服务唯一的实例ID
|
||||
*/
|
||||
public void checkOnStartup() {
|
||||
Optional<Metakv> metaServerinstIdOpt = metkvRes.findFirstByMetakey(Constants.LICENSE_SERVER_INST_ID);
|
||||
if (metaServerinstIdOpt.isEmpty()) {
|
||||
// 没有 serverinstId 信息,初始化
|
||||
final String serverinstId = MainUtils.getUUID();
|
||||
createMetakv(Constants.LICENSE_SERVER_INST_ID, serverinstId, Constants.METAKV_DATATYPE_STRING);
|
||||
}
|
||||
|
||||
Optional<Metakv> metaServicenameOpt = metkvRes.findFirstByMetakey(Constants.LICENSE_SERVICE_NAME);
|
||||
if (metaServicenameOpt.isEmpty()) {
|
||||
// 没有 Service Name 信息,初始化
|
||||
final String serviceName = generateLicenseServiceName();
|
||||
createMetakv(Constants.LICENSE_SERVICE_NAME, serviceName, Constants.METAKV_DATATYPE_STRING);
|
||||
}
|
||||
|
||||
Optional<Metakv> metaLicensesOpt = metkvRes.findFirstByMetakey(Constants.LICENSES);
|
||||
if (metaLicensesOpt.isEmpty()) {
|
||||
// 没有 license 信息,初始化
|
||||
createMetakv(Constants.LICENSES, (new JSONArray()).toString(), Constants.METAKV_DATATYPE_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 建立 Metakv 数据
|
||||
*
|
||||
* @param key
|
||||
* @param value
|
||||
* @param datatype
|
||||
*/
|
||||
public void createMetakv(final String key, final String value, final String datatype) {
|
||||
Date now = new Date();
|
||||
Metakv metakv = new Metakv();
|
||||
metakv.setCreatetime(now);
|
||||
metakv.setUpdatetime(now);
|
||||
metakv.setMetakey(key);
|
||||
metakv.setMetavalue(value);
|
||||
metakv.setDatatype(datatype);
|
||||
|
||||
metkvRes.save(metakv);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机字符串,作为服务名称
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String generateLicenseServiceName() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
sb.append(Constants.LICENSE_SERVICE_NAME_PREFIX);
|
||||
sb.append(Base62.generatingRandomAlphanumericString(5));
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -17,27 +17,29 @@ package com.cskefu.cc.util;
|
||||
import org.apache.commons.codec.digest.DigestUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Base62 {
|
||||
private static final int BINARY = 0x2;
|
||||
|
||||
private static final int NUMBER_61 = 0x0000003d;
|
||||
|
||||
static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B',
|
||||
'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
|
||||
'X', 'Y', 'Z' };
|
||||
'X', 'Y', 'Z'};
|
||||
|
||||
|
||||
public static String encode(long value){
|
||||
return encode(String.valueOf(value)).toLowerCase() ;
|
||||
public static String encode(long value) {
|
||||
return encode(String.valueOf(value)).toLowerCase();
|
||||
}
|
||||
|
||||
public static String encode(String str){
|
||||
public static String encode(String str) {
|
||||
String md5Hex = DigestUtils.md5Hex(str);
|
||||
// 6 digit binary can indicate 62 letter & number from 0-9a-zA-Z
|
||||
int binaryLength = 6 * 6;
|
||||
long binaryLengthFixer = Long.valueOf(StringUtils.repeat("1", binaryLength), BINARY);
|
||||
for (int i = 0; i < 4;) {
|
||||
for (int i = 0; i < 4; ) {
|
||||
String subString = StringUtils.substring(md5Hex, i * 8, (i + 1) * 8);
|
||||
subString = Long.toBinaryString(Long.valueOf(subString, 16) & binaryLengthFixer);
|
||||
subString = StringUtils.leftPad(subString, binaryLength, "0");
|
||||
@ -48,7 +50,7 @@ public class Base62 {
|
||||
sbBuilder.append(DIGITS[charIndex]);
|
||||
}
|
||||
String shortUrl = sbBuilder.toString();
|
||||
if(shortUrl!=null){
|
||||
if (shortUrl != null) {
|
||||
return shortUrl;
|
||||
}
|
||||
}
|
||||
@ -57,7 +59,26 @@ public class Base62 {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void print(Object messagr){
|
||||
private static void print(Object messagr) {
|
||||
System.out.println(messagr);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机字符串
|
||||
* @param targetStringLength
|
||||
* @return
|
||||
*/
|
||||
public static String generatingRandomAlphanumericString(final int targetStringLength) {
|
||||
int leftLimit = 48; // numeral '0'
|
||||
int rightLimit = 122; // letter 'z'
|
||||
Random random = new Random();
|
||||
|
||||
String generatedString = random.ints(leftLimit, rightLimit + 1)
|
||||
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
|
||||
.limit(targetStringLength)
|
||||
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
|
||||
.toString();
|
||||
|
||||
return generatedString;
|
||||
}
|
||||
}
|
@ -138,6 +138,24 @@ CREATE TABLE `cs_fb_otn_follow` (
|
||||
-- Records of cs_fb_otn_follow
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for cs_metakv
|
||||
-- ----------------------------
|
||||
DROP TABLE IF EXISTS `cs_metakv`;
|
||||
CREATE TABLE `cs_metakv` (
|
||||
`metakey` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '元数据字段名,唯一标识',
|
||||
`metavalue` text COLLATE utf8mb4_unicode_ci COMMENT '元数据值',
|
||||
`createtime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updatetime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`datatype` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'string' COMMENT '数据类型',
|
||||
`comment` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '字段备注描述',
|
||||
PRIMARY KEY (`metakey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统内置元数据';
|
||||
|
||||
-- ----------------------------
|
||||
-- Records of cs_metakv
|
||||
-- ----------------------------
|
||||
|
||||
-- ----------------------------
|
||||
-- Table structure for cs_organ_user
|
||||
-- ----------------------------
|
||||
|
@ -0,0 +1,14 @@
|
||||
USE `cosinee`;
|
||||
-- -----------------
|
||||
-- prepare variables
|
||||
-- -----------------
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cs_metakey` (
|
||||
`metakey` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '元数据字段名,唯一标识',
|
||||
`metavalue` text COLLATE utf8mb4_unicode_ci COMMENT '元数据值',
|
||||
`createtime` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updatetime` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
|
||||
`datatype` varchar(256) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'string' COMMENT '数据类型',
|
||||
`comment` varchar(1024) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '字段备注描述',
|
||||
PRIMARY KEY (`metakey`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='系统内置元数据';
|
@ -400,12 +400,19 @@
|
||||
<artifactId>compose4j</artifactId>
|
||||
<version>1.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.chatopera.bot</groupId>
|
||||
<artifactId>sdk</artifactId>
|
||||
<version>3.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.chatopera.store</groupId>
|
||||
<artifactId>store-sdk</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Required for Java 11 https://github.com/cskefu/cskefu/issues/714 -->
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
|
Loading…
x
Reference in New Issue
Block a user