Merge branch '3.1' into leng_dev

# Conflicts:
#	pigx-upms/pigx-upms-biz/src/main/java/com/pig4cloud/pigx/admin/config/DynamicRouteInitRunner.java
This commit is contained in:
冷冷 committed 2019-04-29 21:06:16 +08:00
commit 277a5bbe56
345 files changed
+54272 -2919

No files matched your search

+5 -2
View File
@@ -10,5 +10,8 @@ create database `pigxx_zipkin` default character set utf8mb4 collate utf8mb4_gen
-- pigx 任务相关库
create database `pigxx_job` default character set utf8mb4 collate utf8mb4_general_ci;
-- pigx 公众号管理模块
create database `pigxx_mp` default character set utf8mb4 collate utf8mb4_general_ci;
-- pigx 公众号管理相关库
create database `pigxx_mp` default character set utf8mb4 collate utf8mb4_general_ci;
-- pigx nacos配置相关库
create database `pigxx_config` default character set utf8mb4 collate utf8mb4_general_ci;
File renamed without changes.
-79
View File
@@ -1,79 +0,0 @@
/*
Navicat Premium Data Transfer
Source Server : 本机mysql
Source Server Type : MySQL
Source Server Version : 50724
Source Host : localhost:3306
Source Schema : pigxx_zipkin
Target Server Type : MySQL
Target Server Version : 50724
File Encoding : 65001
Date: 22/02/2019 11:44:20
*/
USE pigxx_zipkin;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for zipkin_annotations
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_annotations`;
CREATE TABLE `zipkin_annotations` (
`trace_id_high` bigint(20) NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
`span_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.id',
`a_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
`a_value` blob NULL COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
`a_type` int(11) NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
`a_timestamp` bigint(20) NULL DEFAULT NULL COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
`endpoint_ipv4` int(11) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_ipv6` binary(16) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
`endpoint_port` smallint(6) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
`endpoint_service_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
UNIQUE INDEX `trace_id_high`(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) USING BTREE COMMENT 'Ignore insert on duplicate',
INDEX `trace_id_high_2`(`trace_id_high`, `trace_id`, `span_id`) USING BTREE COMMENT 'for joining with zipkin_spans',
INDEX `trace_id_high_3`(`trace_id_high`, `trace_id`) USING BTREE COMMENT 'for getTraces/ByIds',
INDEX `endpoint_service_name`(`endpoint_service_name`) USING BTREE COMMENT 'for getTraces and getServiceNames',
INDEX `a_type`(`a_type`) USING BTREE COMMENT 'for getTraces',
INDEX `a_key`(`a_key`) USING BTREE COMMENT 'for getTraces',
INDEX `trace_id`(`trace_id`, `span_id`, `a_key`) USING BTREE COMMENT 'for dependencies job'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compressed;
-- ----------------------------
-- Table structure for zipkin_dependencies
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_dependencies`;
CREATE TABLE `zipkin_dependencies` (
`day` date NOT NULL,
`parent` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`child` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`call_count` bigint(20) NULL DEFAULT NULL,
`error_count` bigint(20) NULL DEFAULT NULL,
UNIQUE INDEX `day`(`day`, `parent`, `child`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compressed;
-- ----------------------------
-- Table structure for zipkin_spans
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_spans`;
CREATE TABLE `zipkin_spans` (
`trace_id_high` bigint(20) NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
`trace_id` bigint(20) NOT NULL,
`id` bigint(20) NOT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`parent_id` bigint(20) NULL DEFAULT NULL,
`debug` bit(1) NULL DEFAULT NULL,
`start_ts` bigint(20) NULL DEFAULT NULL COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
`duration` bigint(20) NULL DEFAULT NULL COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
UNIQUE INDEX `trace_id_high`(`trace_id_high`, `trace_id`, `id`) USING BTREE COMMENT 'ignore insert on duplicate',
INDEX `trace_id_high_2`(`trace_id_high`, `trace_id`, `id`) USING BTREE COMMENT 'for joining with zipkin_annotations',
INDEX `trace_id_high_3`(`trace_id_high`, `trace_id`) USING BTREE COMMENT 'for getTracesByIds',
INDEX `name`(`name`) USING BTREE COMMENT 'for getTraces and getSpanNames',
INDEX `start_ts`(`start_ts`) USING BTREE COMMENT 'for getTraces ordering and range'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compressed;
SET FOREIGN_KEY_CHECKS = 1;
File renamed without changes.
+243
View File
@@ -0,0 +1,243 @@
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 50723
Source Host : localhost
Source Database : nacos
Target Server Type : MySQL
Target Server Version : 50723
File Encoding : utf-8
Date: 04/20/2019 16:36:33 PM
*/
USE pigxx_config;
SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for `config_info`
-- ----------------------------
DROP TABLE IF EXISTS `config_info`;
CREATE TABLE `config_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(255) COLLATE utf8_bin DEFAULT NULL,
`content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
`src_user` text COLLATE utf8_bin COMMENT 'source user',
`src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
`c_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL,
`c_use` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`effect` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`type` varchar(64) COLLATE utf8_bin DEFAULT NULL,
`c_schema` text COLLATE utf8_bin,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info';
-- ----------------------------
-- Records of `config_info`
-- ----------------------------
BEGIN;
INSERT INTO `config_info` VALUES ('1', 'application-dev.yml', 'DEFAULT_GROUP', '# 加解密根密码\njasypt:\n encryptor:\n password: pigx #根密码\n# redis 相关\nspring:\n redis:\n password:\n host: ${REDIS-HOST:pigx-redis}\n # zipkin\n zipkin:\n enabled: true\n base-url: http://${ZIPKIN-HOST:pigx-zipkin}\n sleuth:\n web:\n client:\n enabled: true\n sampler:\n # 默认的采样比率为0.1,不能看到所有请求数据\n # 更改采样比率为1,就能看到所有的请求数据了,但是这样会增加接口调用延迟\n probability: 1.0\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n\n# feign 配置\nfeign:\n hystrix:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n# hystrix If you need to use ThreadLocal bound variables in your RequestInterceptor`s\n# you will need to either set the thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign.\nhystrix:\n command:\n default:\n execution:\n isolation:\n strategy: SEMAPHORE\n thread:\n timeoutInMilliseconds: 60000\n shareSecurityContext: true\n\n#请求处理的超时时间\nribbon:\n ReadTimeout: 10000\n ConnectTimeout: 10000\n\n# mybaits-plus配置\nmybatis-plus:\n # MyBatis Mapper所对应的XML文件位置\n mapper-locations: classpath:/mapper/*Mapper.xml\n global-config:\n # 关闭MP3.0自带的banner\n banner: false\n db-config:\n # 主键类型\n id-type: auto\n\n#swagger公共信息\nswagger:\n host: ${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}\n title: PigX Swagger API\n description: 全宇宙最牛逼的Spring Cloud微服务开发脚手架\n version: \'@project.version@\'\n license: Powered By PigX\n licenseUrl: https://pig4cloud.com/\n terms-of-service-url: https://pig4cloud.com/\n contact:\n name: 冷冷\n email: wangiegie@gmail.com\n url: https://pig4cloud.com/about.html\n authorization:\n name: pigX OAuth\n auth-regex: ^.*$\n authorization-scope-list:\n - scope: server\n description: server all\n token-url-list:\n - http://${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}/auth/oauth/token\n\n## spring security 配置\nsecurity:\n oauth2:\n client:\n # 默认放行url,如果子模块重写这里的配置就会被覆盖\n ignore-urls:\n - /actuator/**\n - /v2/api-docs\n resource:\n loadBalanced: true\n token-info-uri: http://${AUTH-HOST:pigx-auth}/oauth/check_token', '575cebbb771510b3afdc922502231a5b', '2019-04-18 02:10:20', '2019-04-18 02:24:13', null, '127.0.0.1', '', '', '通用配置文件', null, null, 'yaml', null), ('2', 'pigx-activiti-dev.yml', 'DEFAULT_GROUP', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n ignore-urls:\n - \'/actuator/**\'\n - \'/v2/api-docs\'\n - \'/editor-app/**\'\n - \'/modeler.html\'\n - \'/ws/**\'\nspring:\n autoconfigure:\n exclude: org.activiti.spring.boot.SecurityAutoConfiguration\n activiti:\n check-process-definitions: false\n datasource:\n type: com.zaxxer.hikari.HikariDataSource\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_ac}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - oa_leave_bill', '9ba263596903db9dba9c812a06ebd3b3', '2019-04-18 02:10:56', '2019-04-18 02:10:56', null, '127.0.0.1', '', '', '工作流配置文件', null, null, 'yaml', null), ('3', 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '# 数据源\nspring:\n datasource:\n type: com.zaxxer.hikari.HikariDataSource\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers:Line truncated
COMMIT;
-- ----------------------------
-- Table structure for `config_info_aggr`
-- ----------------------------
DROP TABLE IF EXISTS `config_info_aggr`;
CREATE TABLE `config_info_aggr` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`datum_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'datum_id',
`content` longtext COLLATE utf8_bin NOT NULL COMMENT '内容',
`gmt_modified` datetime NOT NULL COMMENT '修改时间',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL,
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段';
-- ----------------------------
-- Table structure for `config_info_beta`
-- ----------------------------
DROP TABLE IF EXISTS `config_info_beta`;
CREATE TABLE `config_info_beta` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
`content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
`beta_ips` varchar(1024) COLLATE utf8_bin DEFAULT NULL COMMENT 'betaIps',
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
`src_user` text COLLATE utf8_bin COMMENT 'source user',
`src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta';
-- ----------------------------
-- Table structure for `config_info_tag`
-- ----------------------------
DROP TABLE IF EXISTS `config_info_tag`;
CREATE TABLE `config_info_tag` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`tag_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_id',
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
`content` longtext COLLATE utf8_bin NOT NULL COMMENT 'content',
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'md5',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
`src_user` text COLLATE utf8_bin COMMENT 'source user',
`src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL COMMENT 'source ip',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag';
-- ----------------------------
-- Table structure for `config_tags_relation`
-- ----------------------------
DROP TABLE IF EXISTS `config_tags_relation`;
CREATE TABLE `config_tags_relation` (
`id` bigint(20) NOT NULL COMMENT 'id',
`tag_name` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'tag_name',
`tag_type` varchar(64) COLLATE utf8_bin DEFAULT NULL COMMENT 'tag_type',
`data_id` varchar(255) COLLATE utf8_bin NOT NULL COMMENT 'data_id',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'group_id',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`nid` bigint(20) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`nid`),
UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation';
-- ----------------------------
-- Table structure for `group_capacity`
-- ----------------------------
DROP TABLE IF EXISTS `group_capacity`;
CREATE TABLE `group_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`group_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_group_id` (`group_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表';
-- ----------------------------
-- Table structure for `his_config_info`
-- ----------------------------
DROP TABLE IF EXISTS `his_config_info`;
CREATE TABLE `his_config_info` (
`id` bigint(64) unsigned NOT NULL,
`nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`data_id` varchar(255) COLLATE utf8_bin NOT NULL,
`group_id` varchar(128) COLLATE utf8_bin NOT NULL,
`app_name` varchar(128) COLLATE utf8_bin DEFAULT NULL COMMENT 'app_name',
`content` longtext COLLATE utf8_bin NOT NULL,
`md5` varchar(32) COLLATE utf8_bin DEFAULT NULL,
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00',
`src_user` text COLLATE utf8_bin,
`src_ip` varchar(20) COLLATE utf8_bin DEFAULT NULL,
`op_type` char(10) COLLATE utf8_bin DEFAULT NULL,
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT '租户字段',
PRIMARY KEY (`nid`),
KEY `idx_gmt_create` (`gmt_create`),
KEY `idx_gmt_modified` (`gmt_modified`),
KEY `idx_did` (`data_id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造';
-- ----------------------------
-- Records of `his_config_info`
-- ----------------------------
BEGIN;
INSERT INTO `his_config_info` VALUES ('0', '1', 'application-dev.yml', 'DEFAULT_GROUP', '', '# 加解密根密码\njasypt:\n encryptor:\n password: pigx #根密码\n# redis 相关\nspring:\n redis:\n password:\n host: ${REDIS-HOST:pigx-redis}\n # zipkin\n zipkin:\n enabled: true\n base-url: http://${ZIPKIN-HOST:pigx-zipkin}\n sleuth:\n web:\n client:\n enabled: true\n sampler:\n # 默认的采样比率为0.1,不能看到所有请求数据\n # 更改采样比率为1,就能看到所有的请求数据了,但是这样会增加接口调用延迟\n probability: 1.0\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n\n# feign 配置\nfeign:\n hystrix:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n response:\n enabled: true\n# hystrix If you need to use ThreadLocal bound variables in your RequestInterceptor`s\n# you will need to either set the thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign.\nhystrix:\n command:\n default:\n execution:\n isolation:\n strategy: SEMAPHORE\n thread:\n timeoutInMilliseconds: 60000\n shareSecurityContext: true\n\n#请求处理的超时时间\nribbon:\n ReadTimeout: 10000\n ConnectTimeout: 10000\n\n# mybaits-plus配置\nmybatis-plus:\n # MyBatis Mapper所对应的XML文件位置\n mapper-locations: classpath:/mapper/*Mapper.xml\n global-config:\n # 关闭MP3.0自带的banner\n banner: false\n db-config:\n # 主键类型\n id-type: auto\n\n#swagger公共信息\nswagger:\n host: ${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}\n title: PigX Swagger API\n description: 全宇宙最牛逼的Spring Cloud微服务开发脚手架\n version: @project.version@\n license: Powered By PigX\n licenseUrl: https://pig4cloud.com/\n terms-of-service-url: https://pig4cloud.com/\n contact:\n name: 冷冷\n email: wangiegie@gmail.com\n url: https://pig4cloud.com/about.html\n authorization:\n name: pigX OAuth\n auth-regex: ^.*$\n authorization-scope-list:\n - scope: server\n description: server all\n token-url-list:\n - http://${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}/auth/oauth/token\n\n## spring security 配置\nsecurity:\n oauth2:\n client:\n # 默认放行url,如果子模块重写这里的配置就会被覆盖\n ignore-urls:\n - /actuator/**\n - /v2/api-docs\n resource:\n loadBalanced: true\n token-info-uri: http://${AUTH-HOST:pigx-auth}/oauth/check_token', 'f683a54f4a1f950c356c1863dfb0917a', '2010-05-05 00:00:00', '2019-04-18 02:10:20', null, '127.0.0.1', 'I', ''), ('0', '2', 'pigx-activiti-dev.yml', 'DEFAULT_GROUP', '', '## spring security 配置\nsecurity:\n oauth2:\n client:\n client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)\n scope: server\n ignore-urls:\n - \'/actuator/**\'\n - \'/v2/api-docs\'\n - \'/editor-app/**\'\n - \'/modeler.html\'\n - \'/ws/**\'\nspring:\n autoconfigure:\n exclude: org.activiti.spring.boot.SecurityAutoConfiguration\n activiti:\n check-process-definitions: false\n datasource:\n type: com.zaxxer.hikari.HikariDataSource\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_ac}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true\n\n# 租户表维护\npigx:\n tenant:\n column: tenant_id\n tables:\n - oa_leave_bill', '9ba263596903db9dba9c812a06ebd3b3', '2010-05-05 00:00:00', '2019-04-18 02:10:56', null, '127.0.0.1', 'I', ''), ('0', '3', 'pigx-auth-dev.yml', 'DEFAULT_GROUP', '', '# 数据源\nspring:\n datasource:\n type: com.zaxxer.hikari.HikariDataSource\n driver-class-name: com.mysql.cj.jdbc.Driver\n username: ${MYSQL-USER:root}\n password: ${MYSQL-PWD:root}\n url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8\n freemarker:\n allow-request-override: false\n allow-session-override: false\n cache: true\n charset: UTF-8\n check-template-location: true\n content-type: text/html\n enabled: true\n expose-request-attributes: false\n expose-session-attributes: false\n expose-spring-macro-helpers: true\n prefer-file-system-access: true\n suffix: .ftl\n tempLine truncated
COMMIT;
-- ----------------------------
-- Table structure for `roles`
-- ----------------------------
DROP TABLE IF EXISTS `roles`;
CREATE TABLE `roles` (
`username` varchar(50) NOT NULL,
`role` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Table structure for `tenant_capacity`
-- ----------------------------
DROP TABLE IF EXISTS `tenant_capacity`;
CREATE TABLE `tenant_capacity` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` varchar(128) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT 'Tenant ID',
`quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值',
`usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量',
`max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值',
`max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数',
`max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值',
`max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量',
`gmt_create` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '创建时间',
`gmt_modified` datetime NOT NULL DEFAULT '2010-05-05 00:00:00' COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表';
-- ----------------------------
-- Table structure for `tenant_info`
-- ----------------------------
DROP TABLE IF EXISTS `tenant_info`;
CREATE TABLE `tenant_info` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
`kp` varchar(128) COLLATE utf8_bin NOT NULL COMMENT 'kp',
`tenant_id` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_id',
`tenant_name` varchar(128) COLLATE utf8_bin DEFAULT '' COMMENT 'tenant_name',
`tenant_desc` varchar(256) COLLATE utf8_bin DEFAULT NULL COMMENT 'tenant_desc',
`create_source` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT 'create_source',
`gmt_create` bigint(20) NOT NULL COMMENT '创建时间',
`gmt_modified` bigint(20) NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`),
KEY `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info';
-- ----------------------------
-- Table structure for `users`
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`username` varchar(50) NOT NULL,
`password` varchar(500) NOT NULL,
`enabled` tinyint(1) NOT NULL,
PRIMARY KEY (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of `users`
-- ----------------------------
BEGIN;
INSERT INTO `users` VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', '1');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
+3 -3
View File
@@ -10,8 +10,8 @@ COPY ./db/2pigxx.sql /docker-entrypoint-initdb.d
COPY ./db/3pigxx_ac.sql /docker-entrypoint-initdb.d
COPY ./db/4pigxx_zipkin.sql /docker-entrypoint-initdb.d
COPY ./db/4pigxx_job.sql /docker-entrypoint-initdb.d
COPY ./db/5pigxx_job.sql /docker-entrypoint-initdb.d
COPY ./db/5pigxx_mp.sql /docker-entrypoint-initdb.d
COPY ./db/6pigxx_mp.sql /docker-entrypoint-initdb.d
COPY ./db/6pigxx_config.sql /docker-entrypoint-initdb.d
+8 -14
View File
@@ -1,4 +1,4 @@
# 使用说明 V2.8.0
# 使用说明 V3.0.0
# 1. 使用docker-compose 宿主机不需要配置host来发现
# 2. 无需修改源码,根目录 docker-compose up 即可
# 3. 静静等待服务启动
@@ -16,6 +16,8 @@ services:
image: pigx-mysql
ports:
- 3306:3306
volumes:
- ./pigx-mysql:/var/lib/mysql
command: --lower_case_table_names=1
pigx-zookeeper:
@@ -42,23 +44,15 @@ services:
- MINIO_ACCESS_KEY=lengleng
- MINIO_SECRET_KEY=lengleng
pigx-eureka:
pigx-register:
build:
context: ./
dockerfile: ./pigx-eureka/Dockerfile
dockerfile: ./pigx-register/Dockerfile
restart: always
container_name: pigx-eureka
image: pigx-eureka
container_name: pigx-register
image: pigx-register
ports:
- 8761:8761
pigx-config:
build:
context: ./
dockerfile: ./pigx-config/Dockerfile
restart: always
container_name: pigx-config
image: pigx-config
- 8848:8848
pigx-gateway:
build:
+6 -1
View File
@@ -33,10 +33,15 @@
<description>pigx 认证授权中心,基于 spring security oAuth2</description>
<dependencies>
<!--注册中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--upms api、model 模块-->
<dependency>
+7 -15
View File
@@ -5,20 +5,12 @@ spring:
application:
name: @artifactId@
cloud:
config:
fail-fast: true
name: ${spring.application.name}
profile: ${spring.profiles.active}
nacos:
discovery:
enabled: true
service-id: pigx-config
server-addr: ${NACOS-HOST:pigx-register}:${NACOS-PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
profiles:
active: dev
# 注册中心配置
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://pig:pig@${EUREKA-HOST:pigx-eureka}:${EUREKA-PORT:8761}/eureka/
active: dev
@@ -0,0 +1,42 @@
package com.pig4cloud.pigx.common.core.constant;
/**
* @author lengleng
* @date 2019-04-28
* <p>
* 缓存的key 常量
*/
public interface CacheConstants {
/**
* 用户信息缓存
*/
String USER_DETAILS = "user_details";
/**
* oauth 客户端信息
*/
String CLIENT_DETAILS_KEY = "pigx_oauth:client:details";
/**
* 菜单信息缓存
*/
String MENU_DETAILS = "menu_details";
/**
* spring boot admin 事件key
*/
String EVENT_KEY = "event_key";
/**
* 路由存放
*/
String ROUTE_KEY = "gateway_route_key";
/**
* 字典缓存
*/
String DICT_DETAILS = "dict_details";
}
@@ -62,16 +62,6 @@ public interface CommonConstants {
*/
String BACK_END_PROJECT = "pigx";
/**
* 路由存放
*/
String ROUTE_KEY = "gateway_route_key";
/**
* spring boot admin 事件key
*/
String EVENT_KEY = "event_key";
/**
* 验证码前缀
*/
@@ -82,10 +82,6 @@ public interface SecurityConstants {
* 自定义登录URL
*/
String MOBILE_TOKEN_URL = "/mobile/token/*";
/**
* oauth 客户端信息
*/
String CLIENT_DETAILS_KEY = "pigx_oauth:client:details";
/**
* 微信获取OPENID
@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
<property name="log.path" value="logs/${spring.application.name}" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<logger name="org.activiti.engine.impl.db" level="DEBUG">
<appender-ref ref="debug" />
</logger>
<!-- Level: FATAL 0 ERROR 3 WARN 4 INFO 6 DEBUG 7 -->
<root level="INFO">
<appender-ref ref="console" />
</root>
</configuration>
@@ -17,7 +17,7 @@
package com.pig4cloud.pigx.common.gateway.support;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.gateway.vo.RouteDefinitionVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -53,7 +53,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
BeanUtils.copyProperties(r, vo);
log.info("保存路由信息{}", vo);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.opsForHash().put(CommonConstants.ROUTE_KEY, r.getId(), vo);
redisTemplate.opsForHash().put(CacheConstants.ROUTE_KEY, r.getId(), vo);
return Mono.empty();
});
}
@@ -63,7 +63,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
routeId.subscribe(id -> {
log.info("删除路由信息{}", id);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.opsForHash().delete(CommonConstants.ROUTE_KEY, id);
redisTemplate.opsForHash().delete(CacheConstants.ROUTE_KEY, id);
});
return Mono.empty();
}
@@ -78,7 +78,7 @@ public class RedisRouteDefinitionWriter implements RouteDefinitionRepository {
public Flux<RouteDefinition> getRouteDefinitions() {
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(RouteDefinitionVo.class));
List<RouteDefinitionVo> values = redisTemplate.opsForHash().values(CommonConstants.ROUTE_KEY);
List<RouteDefinitionVo> values = redisTemplate.opsForHash().values(CacheConstants.ROUTE_KEY);
List<RouteDefinition> definitionList = new ArrayList<>();
values.forEach(vo -> {
RouteDefinition routeDefinition = new RouteDefinition();
@@ -17,7 +17,7 @@
package com.pig4cloud.pigx.common.security.service;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.oauth2.common.exceptions.InvalidClientException;
import org.springframework.security.oauth2.provider.ClientDetails;
@@ -45,7 +45,7 @@ public class PigxClientDetailsService extends JdbcClientDetailsService {
* @throws InvalidClientException
*/
@Override
@Cacheable(value = SecurityConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
@Cacheable(value = CacheConstants.CLIENT_DETAILS_KEY, key = "#clientId", unless = "#result == null")
public ClientDetails loadClientByClientId(String clientId) {
return super.loadClientByClientId(clientId);
}
@@ -22,6 +22,7 @@ import cn.hutool.core.util.StrUtil;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysUser;
import com.pig4cloud.pigx.admin.api.feign.RemoteUserService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
@@ -63,7 +64,7 @@ public class PigxUserDetailsServiceImpl implements PigxUserDetailsService {
@Override
@SneakyThrows
public UserDetails loadUserByUsername(String username) {
Cache cache = cacheManager.getCache("user_details");
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS);
if (cache != null && cache.get(username) != null) {
return (PigxUser) cache.get(username).get();
}
@@ -18,10 +18,12 @@
package org.springframework.cloud.openfeign;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import feign.FeignException;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
@@ -45,6 +47,7 @@ public class PigxFeignFallback<T> implements MethodInterceptor {
@Nullable
@Override
@SneakyThrows
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) {
Class<?> returnType = method.getReturnType();
if (R.class != returnType) {
@@ -57,7 +60,8 @@ public class PigxFeignFallback<T> implements MethodInterceptor {
String str = StrUtil.str(content, StandardCharsets.UTF_8);
log.error("PigxFeignFallback:[{}.{}] serviceId:[{}] message:[{}]", targetType.getName(), method.getName(), targetName, str);
return JSONUtil.toBean(str, R.class);
ObjectMapper objectMapper = SpringContextHolder.getBean(ObjectMapper.class);
return objectMapper.readValue(str, R.class);
}
@Override
-15
View File
@@ -1,15 +0,0 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER wangiegie@gmail.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /pigx-config
WORKDIR /pigx-config
EXPOSE 8888
ADD ./pigx-config/target/pigx-config.jar ./
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-config.jar
-67
View File
@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>2.8.0</version>
</parent>
<artifactId>pigx-config</artifactId>
<packaging>jar</packaging>
<description>pigx 配置中心,基于spring cloud config</description>
<dependencies>
<!--配置中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -1,38 +0,0 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.config;
import org.springframework.boot.SpringApplication;
import org.springframework.cloud.client.SpringCloudApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
/**
* @author lengleng
* @date 2018年06月22日
* 配置中心
*/
@EnableConfigServer
@SpringCloudApplication
public class PigxConfigApplication {
public static void main(String[] args) {
SpringApplication.run(PigxConfigApplication.class, args);
}
}
-16
View File
@@ -1,16 +0,0 @@
${AnsiColor.BRIGHT_YELLOW}
::::::::: ::::::::::: :::::::: ::: :::
:+: :+: :+: :+: :+: :+: :+:
+:+ +:+ +:+ +:+ +:+ +:+
+#++:++#+ +#+ :#: +#++:+
+#+ +#+ +#+ +#+# +#+ +#+
#+# #+# #+# #+# #+# #+#
### ########### ######## ### ###
www.pig4cloud.com
Pig Microservice Architecture
@@ -1,29 +0,0 @@
server:
port: 8888
spring:
application:
name: @artifactId@
profiles:
active: native
# 配置中心
cloud:
config:
server:
native:
search-locations: classpath:/config/
# 注册中心配置
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://pig:pig@${EUREKA-HOST:pigx-eureka}:${EUREKA-PORT:8761}/eureka/
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: '*'
@@ -1,108 +0,0 @@
# 加解密根密码
jasypt:
encryptor:
password: pigx #根密码
# redis 相关
spring:
redis:
password:
host: ${REDIS-HOST:pigx-redis}
# zipkin
zipkin:
enabled: true
base-url: http://${ZIPKIN-HOST:pigx-zipkin}
sleuth:
web:
client:
enabled: true
sampler:
# 默认的采样比率为0.1,不能看到所有请求数据
# 更改采样比率为1,就能看到所有的请求数据了,但是这样会增加接口调用延迟
probability: 1.0
# 暴露监控端点
management:
endpoints:
web:
exposure:
include: '*'
# feign 配置
feign:
hystrix:
enabled: true
okhttp:
enabled: true
httpclient:
enabled: false
client:
config:
default:
connectTimeout: 10000
readTimeout: 10000
compression:
request:
enabled: true
response:
enabled: true
# hystrix If you need to use ThreadLocal bound variables in your RequestInterceptor`s
# you will need to either set the thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign.
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
thread:
timeoutInMilliseconds: 60000
shareSecurityContext: true
#请求处理的超时时间
ribbon:
ReadTimeout: 10000
ConnectTimeout: 10000
# mybaits-plus配置
mybatis-plus:
# MyBatis Mapper所对应的XML文件位置
mapper-locations: classpath:/mapper/*Mapper.xml
global-config:
# 关闭MP3.0自带的banner
banner: false
db-config:
# 主键类型
id-type: auto
#swagger公共信息
swagger:
host: ${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}
title: PigX Swagger API
description: 全宇宙最牛逼的Spring Cloud微服务开发脚手架
version: @project.version@
license: Powered By PigX
licenseUrl: https://pig4cloud.com/
terms-of-service-url: https://pig4cloud.com/
contact:
name: 冷冷
email: wangiegie@gmail.com
url: https://pig4cloud.com/about.html
authorization:
name: pigX OAuth
auth-regex: ^.*$
authorization-scope-list:
- scope: server
description: server all
token-url-list:
- http://${GATEWAY-HOST:pigx-gateway}:${GATEWAY-PORT:9999}/auth/oauth/token
## spring security 配置
security:
oauth2:
client:
# 默认放行url,如果子模块重写这里的配置就会被覆盖
ignore-urls:
- /actuator/**
- /v2/api-docs
resource:
loadBalanced: true
token-info-uri: http://${AUTH-HOST:pigx-auth}/oauth/check_token
@@ -1,31 +0,0 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)
client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)
scope: server
ignore-urls:
- '/actuator/**'
- '/v2/api-docs'
- '/editor-app/**'
- '/modeler.html'
- '/ws/**'
spring:
autoconfigure:
exclude: org.activiti.spring.boot.SecurityAutoConfiguration
activiti:
check-process-definitions: false
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_ac}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true
# 租户表维护
pigx:
tenant:
column: tenant_id
tables:
- oa_leave_bill
@@ -1,22 +0,0 @@
# 数据源
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
freemarker:
allow-request-override: false
allow-session-override: false
cache: true
charset: UTF-8
check-template-location: true
content-type: text/html
enabled: true
expose-request-attributes: false
expose-session-attributes: false
expose-spring-macro-helpers: true
prefer-file-system-access: true
suffix: .ftl
template-loader-path: classpath:/templates/
@@ -1,23 +0,0 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)
client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)
scope: server
# 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
resources:
static-locations: classpath:/static/,classpath:/views/
pigx:
tenant:
column: tenant_id
tables:
- sys_datasource_conf
@@ -1,52 +0,0 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)
client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)
scope: server
## 定时任务
spring:
# 保存定时任务的数据源
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
elasticjob:
# 分布式任务协调依赖zookeeper
zookeeper:
server-lists: ${ZOOKEEPER-HOST:pigx-zookeeper}:${ZOOKEEPER-PORT:2181}
namespace: pigx-daemon
# 普通任务
simples:
spring-simple-job:
job-class: com.pig4cloud.pigx.daemon.elastic.job.PigxSimpleJob
cron: 0 0 0/1 * * ?
sharding-total-count: 3
sharding-item-parameters: 0=service1,1=service2,2=service3
eventTraceRdbDataSource: 'dataSource'
listener:
listener-class: com.pig4cloud.pigx.daemon.elastic.listener.PigxElasticJobListener
spring-simple-job2:
job-class: com.pig4cloud.pigx.daemon.elastic.job.PigxSimpleJob2
cron: 0 0 0/1 * * ?
sharding-total-count: 3
sharding-item-parameters: 0=service1,1=service2,2=service3
eventTraceRdbDataSource: 'dataSource'
listener:
listener-class: com.pig4cloud.pigx.daemon.elastic.listener.PigxElasticJobListener
# 简单任务
dataflows:
spring-dataflow-job:
job-class: com.pig4cloud.pigx.daemon.elastic.job.PigxDataflowJob
cron: 0 0 0/1 * * ?
sharding-total-count: 3
sharding-item-parameters: 0=service1,1=service2,2=service3
streaming-process: true
eventTraceRdbDataSource: 'dataSource'
listener:
distributed-listener-class: com.pig4cloud.pigx.daemon.elastic.listener.PigxDistributeElasticJobListener
started-timeout-milliseconds: 5000
completed-timeout-milliseconds: 10000
@@ -1,45 +0,0 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)
client-secret: ENC(tz2NM4GcmnE7sNJTYL8ZSg==)
scope: server
# 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_job}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
resources:
static-locations: classpath:/static/,classpath:/views/
quartz:
#相关属性配置
properties:
org:
quartz:
scheduler:
instanceName: clusteredScheduler
instanceId: AUTO
jobStore:
class: org.quartz.impl.jdbcjobstore.JobStoreTX
driverDelegateClass: org.quartz.impl.jdbcjobstore.StdJDBCDelegate
tablePrefix: QRTZ_
isClustered: true
clusterCheckinInterval: 10000
useProperties: false
threadPool:
class: org.quartz.simpl.SimpleThreadPool
threadCount: 50
threadPriority: 5
threadsInheritContextClassLoaderOfInitializingThread: true
#数据库方式
job-store-type: jdbc
#初始化表结构
#jdbc:
#initialize-schema: never
@@ -1,12 +0,0 @@
security:
encode:
# 前端密码密钥,必须16位
key: 'pigxpigxpigxpigx'
# 不校验验证码终端
ignore:
clients:
- test
swagger-providers:
- ${AUTH-HOST:pigx-auth}
- ${TX-MGR-HOST:pigx-tx-manager}
@@ -1,13 +0,0 @@
spring:
# 安全配置
security:
user:
name: ENC(rZHA4LW5hHmhLAAzJoFNag==) # pigx
password: ENC(bjeyh+Aeii3kHXkoo00ZUw==) # pigx
boot:
admin:
ui:
resource-locations: 'classpath:/ui/,classpath:/static/'
template-location: 'classpath:/ui/'
title: 'pigx 服务状态监控'
brand: 'pigx 服务状态监控'
@@ -1,31 +0,0 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)
client-secret: ENC(gPFcUOmJm8WqM3k3eSqS0Q==)
scope: server
# 数据源配置
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_mp}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
hikari:
connection-init-sql: SET NAMES utf8mb4
resources:
static-locations: classpath:/static/,classpath:/views/
# 租户表维护
pigx:
tenant:
column: tenant_id
tables:
- wx_menu
- wx_account
- wx_account_fans
- wx_fans_msg_res
@@ -1,24 +0,0 @@
# 页面配置
spring:
mvc:
static-path-pattern: /**
resources:
static-locations: classpath:/static/
# LCN 配置
tm:
transaction:
netty:
delaytime: 5 # 客户端链接最大通讯时间 (秒)
hearttime: 15 # 客户端心跳时间 (秒)
redis:
savemaxtime: 30 # redis 保存时间 (秒)
socket:
port: 9998 # 通讯端口
maxconnection: 1000 #最大链接数
compensate:
auto: false #是否自动补偿
notifyUrl: http://ip:port/path #补偿结果通知(配消息总线里面)
tryTime: 30 # z再次重试时间间隔
maxWaitTime: 5000 # 请求超时的最大时间 (毫秒)
@@ -1,41 +0,0 @@
## spring security 配置
security:
oauth2:
client:
client-id: ENC(ltJPpR50wT0oIY9kfOe1Iw==)
client-secret: ENC(ltJPpR50wT0oIY9kfOe1Iw==)
scope: server
# 数据源
spring:
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8&allowMultiQueries=true
# 文件系统 (提供测试环境,不要乱传)
minio:
url: https://minio.pig4cloud.com
access-key: ENC(O4GgJmcJLQAnvfz+RRq65aps5HgbWQXZ)
secret-key: ENC(O4GgJmcJLQAnvfz+RRq65aps5HgbWQXZ)
# Logger Config
logging:
level:
com.pig4cloud.pigx.admin.mapper: debug
# 租户表维护
pigx:
tenant:
column: tenant_id
tables:
- sys_user
- sys_role
- sys_dept
- sys_log
- sys_social_details
- sys_dict
- sys_dict_item
- sys_log
@@ -1,18 +0,0 @@
spring:
# 数据源
datasource:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
username: ${MYSQL-USER:root}
password: ${MYSQL-PWD:root}
url: jdbc:mysql://${MYSQL-HOST:pigx-mysql}:${MYSQL-PORT:3306}/${MYSQL-DB:pigxx_zipkin}?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8
management:
metrics:
web:
server:
auto-time-requests: false
zipkin:
storage:
type: mysql
sleuth:
enabled: true
-15
View File
@@ -1,15 +0,0 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER wangiegie@gmail.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /pigx-eureka
WORKDIR /pigx-eureka
EXPOSE 8761
ADD ./pigx-eureka/target/pigx-eureka.jar ./
CMD java -Djava.security.egd=file:/dev/./urandom -jar pigx-eureka.jar
-76
View File
@@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~
~ Copyright (c) 2018-2025, lengleng All rights reserved.
~
~ Redistribution and use in source and binary forms, with or without
~ modification, are permitted provided that the following conditions are met:
~
~ Redistributions of source code must retain the above copyright notice,
~ this list of conditions and the following disclaimer.
~ Redistributions in binary form must reproduce the above copyright
~ notice, this list of conditions and the following disclaimer in the
~ documentation and/or other materials provided with the distribution.
~ Neither the name of the pig4cloud.com developer nor the names of its
~ contributors may be used to endorse or promote products derived from
~ this software without specific prior written permission.
~ Author: lengleng (wangiegie@gmail.com)
~
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>2.8.0</version>
</parent>
<artifactId>pigx-eureka</artifactId>
<packaging>jar</packaging>
<description>pigx 服务中心,基于eureka</description>
<dependencies>
<!--服务中心-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!--security-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<!--web 模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--undertow容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -1,39 +0,0 @@
/*
*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*
*/
package com.pig4cloud.pigx.eureka;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
/**
* @author lengleng
* @date 2018年06月21日
* 服务中心
*/
@EnableEurekaServer
@SpringBootApplication
public class PigxEurekaApplication {
public static void main(String[] args) {
SpringApplication.run(PigxEurekaApplication.class, args);
}
}
@@ -1,41 +0,0 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng (wangiegie@gmail.com)
*/
package com.pig4cloud.pigx.eureka.security;
/**
* @author lengleng
* @date 2018/7/12
*/
import lombok.SneakyThrows;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
@SneakyThrows
protected void configure(HttpSecurity http) {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/actuator/**").permitAll()
.anyRequest()
.authenticated().and().httpBasic();
}
}
-16
View File
@@ -1,16 +0,0 @@
${AnsiColor.BRIGHT_YELLOW}
::::::::: ::::::::::: :::::::: ::: :::
:+: :+: :+: :+: :+: :+: :+:
+:+ +:+ +:+ +:+ +:+ +:+
+#++:++#+ +#+ :#: +#++:+
+#+ +#+ +#+ +#+# +#+ +#+
#+# #+# #+# #+# #+# #+#
### ########### ######## ### ###
www.pig4cloud.com
Pig Microservice Architecture
@@ -1,34 +0,0 @@
server:
port: 8761
spring:
security:
user:
name: pig
password: pig
application:
name: @artifactId@
cloud:
config:
enabled: false
# docker-compose部署时候 hostname 换成pigx-eureka
# 类似的 redis 使用pigx-redis ,gateway 换成 pigx-gateway
eureka:
instance:
hostname: pigx-eureka
prefer-ip-address: true
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://pig:pig@${eureka.instance.hostname}:${server.port}/eureka/
server:
eviction-interval-timer-in-ms: 4000
enable-self-preservation: false
renewal-percent-threshold: 0.9
management:
endpoints:
web:
exposure:
include: '*'
@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="false">
<springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue=""/>
<property name="log.path" value="logs/${spring.application.name}" />
<!-- 彩色日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
<!-- 彩色日志依赖的渲染类 -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx"
converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<!-- Console log output -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Log file debug output -->
<appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM, aux}/debug.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
</appender>
<!-- Log file error output -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
<maxFileSize>50MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
</appender>
<root level="INFO">
<appender-ref ref="console" />
</root>
</configuration>
+6 -1
View File
@@ -47,10 +47,15 @@
<groupId>com.pig4cloud</groupId>
<artifactId>pigx-common-gateway</artifactId>
</dependency>
<!--注册中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--配置中心客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--验证码-->
<dependency>
@@ -18,7 +18,6 @@
package com.pig4cloud.pigx.gateway.filter;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.gateway.config.SwaggerProvider;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
@@ -47,7 +46,6 @@ import static org.springframework.cloud.gateway.support.ServerWebExchangeUtils.a
*/
@Component
public class PigxRequestGlobalFilter implements GlobalFilter, Ordered {
private static final String HEADER_NAME = "X-Forwarded-Prefix";
/**
* Process the Web request and (optionally) delegate to the next
@@ -74,16 +72,9 @@ public class PigxRequestGlobalFilter implements GlobalFilter, Ordered {
.build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, newRequest.getURI());
// 3. 支持swagger添加X-Forwarded-Prefix header
String path = request.getURI().getPath();
if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
return chain.filter(exchange.mutate().request(newRequest).build());
}
String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
return chain.filter(exchange.mutate()
.request(newRequest.mutate()
.header(HEADER_NAME, basePath)
.build()).build());
.request(newRequest.mutate()
.build()).build());
}
@Override
+6 -17
View File
@@ -4,24 +4,13 @@ server:
spring:
application:
name: @artifactId@
# 配置中心
cloud:
config:
fail-fast: true
name: ${spring.application.name}
profile: ${spring.profiles.active}
nacos:
discovery:
enabled: true
service-id: pigx-config
server-addr: ${NACOS-HOST:pigx-register}:${NACOS-PORT:8848}
config:
server-addr: ${spring.cloud.nacos.discovery.server-addr}
file-extension: yml
shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
profiles:
active: dev
# 注册中心
eureka:
instance:
prefer-ip-address: true
client:
service-url:
defaultZone: http://pig:pig@${EUREKA-HOST:pigx-eureka}:${EUREKA-PORT:8761}/eureka/
+18
View File
@@ -0,0 +1,18 @@
FROM anapsix/alpine-java:8_server-jre_unlimited
MAINTAINER wangiegie@gmail.com
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN mkdir -p /pigx-register
WORKDIR /pigx-register
EXPOSE 8848
ADD ./pigx-register/target/pigx-register.jar ./
CMD sleep 10;java -Djava.security.egd=file:/dev/./urandom -jar pigx-register.jar
+75
View File
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 1999-2018 Alibaba Group Holding Ltd.
Licensed 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.pig4cloud</groupId>
<artifactId>pigx</artifactId>
<version>2.8.0</version>
</parent>
<artifactId>pigx-register</artifactId>
<packaging>jar</packaging>
<name>pigx-register</name>
<description>nacos 注册配置中</description>
<dependencies>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-config</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-naming</artifactId>
<version>1.0.0</version>
</dependency>
<!-- log -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
@@ -0,0 +1,40 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos;
import com.alibaba.nacos.console.config.ConfigConstants;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author nacos
* <p>
* nacos console 源码运行,方便开发
* 生产建议从官网下载最新版配置运行
*/
@EnableScheduling
@SpringBootApplication
public class PigxNacosApplication {
public static void main(String[] args) {
System.setProperty(ConfigConstants.TOMCAT_DIR, "logs");
System.setProperty(ConfigConstants.TOMCAT_ACCESS_LOG, "false");
System.setProperty(ConfigConstants.STANDALONE_MODE, "true");
SpringApplication.run(PigxNacosApplication.class, args);
}
}
@@ -0,0 +1,25 @@
package com.alibaba.nacos.console.config;
/**
* @author lengleng
* @date 2019-04-19
* <p>
* 覆盖nacos 默认配置
*/
public interface ConfigConstants {
/**
* The System property name of Standalone mode
*/
String STANDALONE_MODE = "nacos.standalone";
/**
* tomcat 目录
*/
String TOMCAT_DIR = "server.tomcat.basedir";
/**
* tomcat 日志配置
*/
String TOMCAT_ACCESS_LOG = "server.tomcat.accesslog.enabled";
}
@@ -0,0 +1,107 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.config;
import com.alibaba.nacos.console.filter.JwtAuthenticationTokenFilter;
import com.alibaba.nacos.console.security.CustomUserDetailsServiceImpl;
import com.alibaba.nacos.console.security.JwtAuthenticationEntryPoint;
import com.alibaba.nacos.console.utils.JwtTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.security.authentication.AuthenticationManager;
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.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* Spring security config
*
* @author Nacos
*/
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
public static final String AUTHORIZATION_HEADER = "Authorization";
public static final String AUTHORIZATION_TOKEN = "access_token";
public static final String SECURITY_IGNORE_URLS_SPILT_CHAR = ",";
@Autowired
private CustomUserDetailsServiceImpl userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private JwtTokenUtils tokenProvider;
@Autowired
private Environment env;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) {
String ignoreURLs = env.getProperty("nacos.security.ignore.urls", "/**");
for (String ignoreURL : ignoreURLs.trim().split(SECURITY_IGNORE_URLS_SPILT_CHAR)) {
web.ignoring().antMatchers(ignoreURL.trim());
}
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated().and()
// custom token authorize exception handler
.exceptionHandling()
.authenticationEntryPoint(unauthorizedHandler).and()
// since we use jwt, session is not necessary
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
// since we use jwt, csrf is not necessary
.csrf().disable();
http.addFilterBefore(new JwtAuthenticationTokenFilter(tokenProvider), UsernamePasswordAuthenticationFilter.class);
// disable cache
http.headers().cacheControl();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
@@ -0,0 +1,82 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.controller;
import com.alibaba.nacos.console.config.WebSecurityConfig;
import com.alibaba.nacos.config.server.model.RestResult;
import com.alibaba.nacos.console.utils.JwtTokenUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* auth
*
* @author wfnuser
*/
@RestController("auth")
@RequestMapping("/v1/auth")
public class AuthController {
@Autowired
private JwtTokenUtils jwtTokenUtils;
@Autowired
private AuthenticationManager authenticationManager;
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted
*
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states.
*/
@ResponseBody
@RequestMapping(value = "login", method = RequestMethod.POST)
public RestResult<String> login(HttpServletRequest request, HttpServletResponse response) throws Exception {
String username = request.getParameter("username");
String password = request.getParameter("password");
// 通过用户名和密码创建一个 Authentication 认证对象,实现类为 UsernamePasswordAuthenticationToken
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
RestResult<String> rr = new RestResult<String>();
try {
//通过 AuthenticationManager(默认实现为ProviderManager)的authenticate方法验证 Authentication 对象
Authentication authentication = authenticationManager.authenticate(authenticationToken);
//将 Authentication 绑定到 SecurityContext
SecurityContextHolder.getContext().setAuthentication(authentication);
//生成Token
String token = jwtTokenUtils.createToken(authentication);
//将Token写入到Http头部
response.addHeader(WebSecurityConfig.AUTHORIZATION_HEADER, "Bearer " + token);
rr.setCode(200);
rr.setData("Bearer " + token);
return rr;
} catch (BadCredentialsException authentication) {
rr.setCode(401);
rr.setMessage("Login failed");
return rr;
}
}
}
@@ -0,0 +1,108 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.naming.controllers.OperatorController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
/**
* @author <a href="mailto:huangxiaoyu1018@gmail.com">hxy1991</a>
*/
@RestController("consoleHealth")
@RequestMapping("/v1/console/health")
public class HealthController {
private static final Logger logger = LoggerFactory.getLogger(HealthController.class);
private final PersistService persistService;
private final OperatorController apiCommands;
@Autowired
public HealthController(PersistService persistService, OperatorController apiCommands) {
this.persistService = persistService;
this.apiCommands = apiCommands;
}
/**
* Whether the Nacos is in broken states or not, and cannot recover except by being restarted
*
* @return HTTP code equal to 200 indicates that Nacos is in right states. HTTP code equal to 500 indicates that
* Nacos is in broken states.
*/
@ResponseBody
@RequestMapping(value = "liveness", method = RequestMethod.GET)
public ResponseEntity liveness() {
return ResponseEntity.ok().body("OK");
}
/**
* Ready to receive the request or not
*
* @return HTTP code equal to 200 indicates that Nacos is ready. HTTP code equal to 500 indicates that Nacos is not
* ready.
*/
@ResponseBody
@RequestMapping(value = "readiness", method = RequestMethod.GET)
public ResponseEntity readiness(HttpServletRequest request) {
boolean isConfigReadiness = isConfigReadiness();
boolean isNamingReadiness = isNamingReadiness(request);
if (isConfigReadiness && isNamingReadiness) {
return ResponseEntity.ok().body("OK");
}
if (!isConfigReadiness && !isNamingReadiness) {
return ResponseEntity.status(500).body("Config and Naming are not in readiness");
}
if (!isConfigReadiness) {
return ResponseEntity.status(500).body("Config is not in readiness");
}
return ResponseEntity.status(500).body("Naming is not in readiness");
}
private boolean isConfigReadiness() {
// check db
try {
persistService.configInfoCount("");
return true;
} catch (Exception e) {
logger.error("Config health check fail.", e);
}
return false;
}
private boolean isNamingReadiness(HttpServletRequest request) {
try {
apiCommands.metrics(request);
return true;
} catch (Exception e) {
logger.error("Naming health check fail.", e);
}
return false;
}
}
@@ -0,0 +1,166 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.controller;
import com.alibaba.nacos.config.server.exception.NacosException;
import com.alibaba.nacos.config.server.model.RestResult;
import com.alibaba.nacos.config.server.model.TenantInfo;
import com.alibaba.nacos.config.server.service.PersistService;
import com.alibaba.nacos.config.server.utils.StringUtils;
import com.alibaba.nacos.console.model.Namespace;
import com.alibaba.nacos.console.model.NamespaceAllInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* namespace service
*
* @author Nacos
*/
@Controller
@RequestMapping("/v1/console/namespaces")
public class NamespaceController {
@Autowired
private transient PersistService persistService;
/**
* Get namespace list
*
* @param request request
* @param response response
* @return namespace list
*/
@ResponseBody
@RequestMapping(method = RequestMethod.GET)
public RestResult<List<Namespace>> getNamespaces(HttpServletRequest request, HttpServletResponse response) {
RestResult<List<Namespace>> rr = new RestResult<List<Namespace>>();
rr.setCode(200);
// TODO 获取用kp
List<TenantInfo> tenantInfos = persistService.findTenantByKp("1");
Namespace namespace0 = new Namespace("", "Public", 200, persistService.configInfoCount(""), 0);
List<Namespace> namespaces = new ArrayList<Namespace>();
namespaces.add(namespace0);
for (TenantInfo tenantInfo : tenantInfos) {
int configCount = persistService.configInfoCount(tenantInfo.getTenantId());
Namespace namespaceTmp = new Namespace(tenantInfo.getTenantId(), tenantInfo.getTenantName(), 200,
configCount, 2);
namespaces.add(namespaceTmp);
}
rr.setData(namespaces);
return rr;
}
/**
* get namespace all info by namespace id
*
* @param request request
* @param response response
* @param namespaceId namespaceId
* @return namespace all info
*/
@ResponseBody
@RequestMapping(params = "show=all", method = RequestMethod.GET)
public NamespaceAllInfo getNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) {
// TODO 获取用kp
if (StringUtils.isBlank(namespaceId)) {
NamespaceAllInfo namespaceTmp = new NamespaceAllInfo(namespaceId, "Public", 200, persistService.configInfoCount(""), 0,
"Public Namespace");
return namespaceTmp;
} else {
TenantInfo tenantInfo = persistService.findTenantByKp("1", namespaceId);
int configCount = persistService.configInfoCount(namespaceId);
NamespaceAllInfo namespaceTmp = new NamespaceAllInfo(namespaceId, tenantInfo.getTenantName(), 200,
configCount, 2, tenantInfo.getTenantDesc());
return namespaceTmp;
}
}
/**
* create namespace
*
* @param request request
* @param response response
* @param namespaceName namespace Name
* @param namespaceDesc namespace Desc
* @return whether create ok
* @throws NacosException
*/
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public Boolean createNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceName") String namespaceName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc)
throws NacosException {
// TODO 获取用kp
String namespaceId = UUID.randomUUID().toString();
persistService.insertTenantInfoAtomic("1", namespaceId, namespaceName, namespaceDesc, "nacos",
System.currentTimeMillis());
return true;
}
/**
* edit namespace
*
* @param request request
* @param response response
* @param namespace namespace
* @param namespaceShowName namespace ShowName
* @param namespaceDesc namespace Desc
* @return whether edit ok
* @throws NacosException NacosException
*/
@RequestMapping(method = RequestMethod.PUT)
@ResponseBody
public Boolean editNamespace(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespace") String namespace,
@RequestParam("namespaceShowName") String namespaceShowName,
@RequestParam(value = "namespaceDesc", required = false) String namespaceDesc)
throws NacosException {
// TODO 获取用kp
persistService.updateTenantNameAtomic("1", namespace, namespaceShowName, namespaceDesc);
return true;
}
/**
* del namespace by id
*
* @param request request
* @param response response
* @param namespaceId namespace Id
* @return whether del ok
* @throws NacosException NacosException
*/
@RequestMapping(method = RequestMethod.DELETE)
@ResponseBody
public Boolean deleteConfig(HttpServletRequest request, HttpServletResponse response,
@RequestParam("namespaceId") String namespaceId) throws NacosException {
persistService.removeTenantInfoAtomic("1", namespaceId);
return true;
}
}
@@ -0,0 +1,60 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.controller;
import com.alibaba.nacos.common.util.VersionUtils;
import com.alibaba.nacos.core.utils.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
/**
* @author xingxuechao
* on:2019/2/27 11:17 AM
*/
@RestController
@RequestMapping("/v1/console/server")
public class ServerStateController {
private static final Logger logger = LoggerFactory.getLogger(ServerStateController.class);
public static String VERSION ;
@ResponseBody
@RequestMapping(value = "state", method = RequestMethod.GET)
public ResponseEntity serverState() {
Map<String,String> serverState = new HashMap<String, String>(3);
serverState.put("standalone_mode",SystemUtils.STANDALONE_MODE ?
SystemUtils.STANDALONE_MODE_ALONE : SystemUtils.STANDALONE_MODE_CLUSTER);
serverState.put("function_mode", SystemUtils.FUNCTION_MODE);
serverState.put("version", VersionUtils.VERSION);
return ResponseEntity.ok().body(serverState);
}
}
@@ -0,0 +1,80 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.filter;
import com.alibaba.nacos.console.config.WebSecurityConfig;
import com.alibaba.nacos.console.utils.JwtTokenUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* jwt auth token filter
*
* @author wfnuser
*/
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
private static final String TOKEN_PREFIX = "Bearer ";
private JwtTokenUtils tokenProvider;
public JwtAuthenticationTokenFilter(JwtTokenUtils tokenProvider) {
this.tokenProvider = tokenProvider;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String jwt = resolveToken(request);
if (jwt != null && !"".equals(jwt.trim()) && SecurityContextHolder.getContext().getAuthentication() == null) {
if (this.tokenProvider.validateToken(jwt)) {
/**
* get auth info
*/
Authentication authentication = this.tokenProvider.getAuthentication(jwt);
/**
* save user info to securityContext
*/
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
chain.doFilter(request, response);
}
/**
* Get token from header
*/
private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader(WebSecurityConfig.AUTHORIZATION_HEADER);
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(TOKEN_PREFIX)) {
return bearerToken.substring(7, bearerToken.length());
}
String jwt = request.getParameter(WebSecurityConfig.AUTHORIZATION_TOKEN);
if (StringUtils.hasText(jwt)) {
return jwt;
}
return null;
}
}
@@ -0,0 +1,93 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.model;
/**
* Namespace
*
* @author diamond
*/
public class Namespace {
private String namespace;
private String namespaceShowName;
private int quota;
private int configCount;
/**
* 0 : Global configuration, 1 : Default private namespace ,2 : Custom namespace
*/
private int type;
public String getNamespaceShowName() {
return namespaceShowName;
}
public void setNamespaceShowName(String namespaceShowName) {
this.namespaceShowName = namespaceShowName;
}
public String getNamespace() {
return namespace;
}
public void setNamespace(String namespace) {
this.namespace = namespace;
}
public Namespace() {
}
public Namespace(String namespace, String namespaceShowName) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
}
public Namespace(String namespace, String namespaceShowName, int quota, int configCount, int type) {
this.namespace = namespace;
this.namespaceShowName = namespaceShowName;
this.quota = quota;
this.configCount = configCount;
this.type = type;
}
public int getQuota() {
return quota;
}
public void setQuota(int quota) {
this.quota = quota;
}
public int getConfigCount() {
return configCount;
}
public void setConfigCount(int configCount) {
this.configCount = configCount;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.model;
/**
* all namespace info
*
* @author Nacos
*/
public class NamespaceAllInfo extends Namespace {
private String namespaceDesc;
public String getNamespaceDesc() {
return namespaceDesc;
}
public void setNamespaceDesc(String namespaceDesc) {
this.namespaceDesc = namespaceDesc;
}
public NamespaceAllInfo() {
}
;
public NamespaceAllInfo(String namespace, String namespaceShowName, int quota, int configCount, int type,
String namespaceDesc) {
super(namespace, namespaceShowName, quota, configCount, type);
this.namespaceDesc = namespaceDesc;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
/**
* auth provider
*
* @author wfnuser
*/
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private CustomUserDetailsServiceImpl userDetailsService;
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
String username = (String) authentication.getPrincipal();
String password = (String) authentication.getCredentials();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (!password.equals(userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(username, null, null);
}
return null;
}
@Override
public boolean supports(Class<?> aClass) {
return aClass.equals(UsernamePasswordAuthenticationToken.class);
}
}
@@ -0,0 +1,73 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.security;
import com.alibaba.nacos.config.server.model.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
/**
* custem user
*
* @author wfnuser
*/
public class CustomUserDetails implements UserDetails {
private User user;
public CustomUserDetails(User user) {
this.user = user;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
// TODO: get authorities
return AuthorityUtils.commaSeparatedStringToAuthorityList("");
}
@Override
public String getPassword() {
return user.getPassword();
}
@Override
public String getUsername() {
return user.getUsername();
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.security;
import com.alibaba.nacos.config.server.model.User;
import com.alibaba.nacos.config.server.service.PersistService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
/**
* Custem user service
*
* @author wfnuser
*/
@Service
public class CustomUserDetailsServiceImpl implements UserDetailsService {
@Autowired
private transient PersistService persistService;
@Override
public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
User user = persistService.findUserByUsername(userName);
if (user == null) {
throw new UsernameNotFoundException(userName);
}
return new CustomUserDetails(user);
}
}
@@ -0,0 +1,46 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.security;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.stereotype.Component;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* jwt auth fail point
*
* @author wfnuser
*/
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
private static final Logger logger = LoggerFactory.getLogger(JwtAuthenticationEntryPoint.class);
@Override
public void commence(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
AuthenticationException e) throws IOException, ServletException {
logger.error("Responding with unauthorized error. Message - {}", e.getMessage());
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
@@ -0,0 +1,139 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.utils;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Date;
import java.util.List;
/**
* Jwt token tool
*
* @author wfnuser
*/
@Component
public class JwtTokenUtils {
private final Logger log = LoggerFactory.getLogger(JwtTokenUtils.class);
private static final String AUTHORITIES_KEY = "auth";
/**
* secret key
*/
private String secretKey;
/**
* Token validity time(ms)
*/
private long tokenValidityInMilliseconds;
@PostConstruct
public void init() {
this.secretKey = "SecretKey012345678901234567890123456789012345678901234567890123456789";
this.tokenValidityInMilliseconds = 1000 * 60 * 30L;
}
/**
* Create token
*
* @param authentication auth info
* @return token
*/
public String createToken(Authentication authentication) {
/**
* Current time
*/
long now = (new Date()).getTime();
/**
* Validity date
*/
Date validity;
validity = new Date(now + this.tokenValidityInMilliseconds);
/**
* create token
*/
return Jwts.builder()
.setSubject(authentication.getName())
.claim(AUTHORITIES_KEY, "")
.setExpiration(validity)
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
}
/**
* Get auth Info
*
* @param token token
* @return auth info
*/
public Authentication getAuthentication(String token) {
/**
* parse the payload of token
*/
Claims claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token)
.getBody();
List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList((String) claims.get(AUTHORITIES_KEY));
User principal = new User(claims.getSubject(), "", authorities);
return new UsernamePasswordAuthenticationToken(principal, "", authorities);
}
/**
* validate token
*
* @param token token
* @return whether valid
*/
public boolean validateToken(String token) {
try {
Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token);
return true;
} catch (SignatureException e) {
log.info("Invalid JWT signature.");
log.trace("Invalid JWT signature trace: {}", e);
} catch (MalformedJwtException e) {
log.info("Invalid JWT token.");
log.trace("Invalid JWT token trace: {}", e);
} catch (ExpiredJwtException e) {
log.info("Expired JWT token.");
log.trace("Expired JWT token trace: {}", e);
} catch (UnsupportedJwtException e) {
log.info("Unsupported JWT token.");
log.trace("Unsupported JWT token trace: {}", e);
} catch (IllegalArgumentException e) {
log.info("JWT token compact of handler are invalid.");
log.trace("JWT token compact of handler are invalid trace: {}", e);
}
return false;
}
}
@@ -0,0 +1,30 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.console.utils;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**
* Password encoder tool
*
* @author nacos
*/
public class PasswordEncoderUtil {
public static void main(String[] args) {
System.out.println(new BCryptPasswordEncoder().encode("nacos"));
}
}
+24
View File
@@ -0,0 +1,24 @@
nacos:
cmdb:
dumpTaskInterval: 3600
eventTaskInterval: 10
labelTaskInterval: 300
loadDataAtStart: false
# 数据源相关配置
db:
num: 1
user: root
password: root
url:
0: jdbc:mysql://pigx-mysql:3306/pigxx_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
spring:
datasource:
platform: mysql
security:
enabled: false
server:
tomcat:
basedir: logs
+1
View File
@@ -0,0 +1 @@
version=${project.version}
@@ -0,0 +1,26 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
],
"react-app"
],
"plugins": [
[
"@babel/plugin-proposal-decorators",
{
"legacy": true
}
],
[
"babel-plugin-import",
{
"libraryName": "@alifd/next",
"style": true
}
]
]
}
@@ -0,0 +1,16 @@
# http://editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab
@@ -0,0 +1,6 @@
*.svg
*.ejs
.DS_Store
build
node_modules
public
@@ -0,0 +1,35 @@
{
"extends": "eslint-config-ali/react",
"parser": "babel-eslint",
"env": {},
"globals": {
"window": true
},
"rules": {
"no-shadow": "off",
"no-empty": "off",
"no-useless-escape": "off",
"no-template-curly-in-string": "off",
"no-unused-vars": "off",
"no-tabs": "off",
"no-param-reassign": "off",
"react/no-string-refs": "off",
"react/no-unused-state": "off",
"no-return-assign": "off",
"no-plusplus": "off",
"no-script-url": "off",
"no-mixed-operators": "off",
"react/jsx-indent": "off",
"react/jsx-no-bind": "off",
"react/forbid-prop-types": "off",
"react/no-array-index-key": "off",
"react/sort-comp": "off",
"implicit-arrow-linebreak": "off",
"prefer-const": "off",
"space-before-function-paren": "off",
"generator-star-spacing": "off",
"wrap-iife": "off",
"arrow-parens": "off",
"indent": "off"
}
}
@@ -0,0 +1,16 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
# production
/dist
# misc
.DS_Store
npm-debug.log*
# test
test/uirecorder.log
test/reports
test/screenshots/*
@@ -0,0 +1,6 @@
*.svg
*.ejs
.DS_Store
build
node_modules
public
@@ -0,0 +1,9 @@
{
"tabWidth": 2,
"printWidth": 100,
"semi": true,
"useTabs": false,
"bracketSpacing": true,
"singleQuote": true,
"trailingComma": "es5"
}
@@ -0,0 +1,60 @@
# 开始项目
## cnpm 安装(可忽略)
```sh
npm install -g cnpm --registry=https://registry.npm.taobao.org
# 设置匿名
alias cnpm="npm --registry=https://registry.npm.taobao.org \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=https://npm.taobao.org/dist \
--userconfig=$HOME/.cnpmrc"
# Or alias it in .bashrc or .zshrc
$ echo '\n#alias for cnpm\nalias cnpm="npm --registry=https://registry.npm.taobao.org \
--cache=$HOME/.npm/.cache/cnpm \
--disturl=https://npm.taobao.org/dist \
--userconfig=$HOME/.cnpmrc"' >> ~/.zshrc && source ~/.zshrc
```
[详情地址: http://npm.taobao.org/](http://npm.taobao.org/)
## 安装依赖
```sh
yarn
```
或
```
cnpm install
```
## 启动
```sh
yarn start
```
或
```
npm start
```
## 构建打包
```sh
yarn build
```
或
```
npm run build
```
##
# 代理配置
`build/webpack.dev.conf.js`
修改proxy属性
```
proxy: [{
context: ['/'],
changeOrigin: true,
secure: false,
target: 'http://ip:port',
}],
```
@@ -0,0 +1,80 @@
{
"name": "console-fe",
"version": "1.0.0",
"description": "console fe",
"main": "index.js",
"scripts": {
"start": "cross-env NODE_ENV=development webpack-dev-server --config build/webpack.dev.conf.js",
"build": "cross-env NODE_ENV=production webpack --config build/webpack.prod.conf.js && node build/copyFile.js",
"eslint": "eslint --ext .js src/",
"eslint-fix": "eslint --ext .js --fix src/"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.{js,css,less}": [
"prettier --write",
"git add"
]
},
"license": "Apache-2.0",
"repository": {
"type": "git",
"url": "git+https://github.com/alibaba/nacos.git"
},
"devDependencies": {
"@babel/cli": "^7.2.3",
"@babel/core": "^7.2.2",
"@babel/plugin-proposal-decorators": "^7.2.3",
"@babel/preset-env": "^7.2.3",
"@babel/runtime": "^7.2.0",
"babel-eslint": "^10.0.1",
"babel-loader": "^8.0.4",
"babel-plugin-import": "^1.11.0",
"babel-preset-react-app": "^6.1.0",
"clean-webpack-plugin": "^0.1.19",
"copy-webpack-plugin": "^4.6.0",
"cross-env": "^5.2.0",
"css-loader": "^2.0.2",
"eslint": "^5.11.0",
"eslint-config-ali": "^4.1.0",
"eslint-config-prettier": "^3.3.0",
"eslint-loader": "^2.1.1",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-prettier": "^3.0.0",
"eslint-plugin-react": "^7.11.1",
"file-loader": "^2.0.0",
"html-webpack-plugin": "^3.2.0",
"husky": "^1.1.4",
"lint-staged": "^8.0.4",
"mini-css-extract-plugin": "^0.5.0",
"node-sass": "^4.11.0",
"optimize-css-assets-webpack-plugin": "^5.0.1",
"prettier": "1.15.2",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"uglifyjs-webpack-plugin": "^2.1.0",
"url-loader": "^1.1.2",
"webpack": "^4.28.2",
"webpack-cli": "^3.1.2",
"webpack-dev-server": "^3.1.13"
},
"dependencies": {
"@alifd/next": "^1.11.10",
"axios": "^0.18.0",
"jquery": "^3.3.1",
"moment": "^2.23.0",
"prop-types": "^15.6.2",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"react-redux": "^5.1.1",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"react-router-redux": "^4.0.8",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0"
}
}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,353 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
/* BASICS */
.CodeMirror {
/* Set height, width, borders, and global font properties here */
font-family: monospace;
height: 300px;
color: black;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background: #ffa;
background: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
@@ -0,0 +1 @@
@charset "UTF-8";.viewFramework-topbar{position:fixed;width:100%;height:50px;background:#09C;z-index:101}.viewFramework-body{position:absolute;width:100%;top:50px;bottom:0px;background-color:#000;z-index:100}.viewFramework-body .console-global-notice .console-global-notice-nav{top:14px}.viewFramework-body .console-global-notice .console-global-notice-list{margin:0;height:40px}.viewFramework-body .console-global-notice .console-global-notice-list .console-global-notice-item{padding:11px 12px;border:none}.viewFramework-body .console-global-notice .console-global-notice-list .console-global-notice-item .console-global-notice-nomore{top:10px}.viewFramework-body.viewFramework-topbar-hide{top:0px}.viewFramework-body.viewFramework-topbar-hide .viewFramework-sidebar{top:0px}.viewFramework-sidebar{width:0px;display:none;position:fixed;top:50px;bottom:0px;background-color:#293038;z-index:102;overflow-x:hidden}.viewFramework-sidebar .sidebar-content{width:200px;height:100%;overflow:auto;overflow-x:hidden}.viewFramework-sidebar .sidebar-trans{-o-transition:all 0.12s ease,0.12s ease;-ms-transition:all 0.12s ease,0.12s ease;-moz-transition:all 0.12s ease,0.12s ease;-webkit-transition:all 0.12s ease,0.12s ease}.viewFramework-sidebar .sidebar-fold{height:30px;width:180px;background:#394555;color:#aeb9c2;text-align:center;line-height:30px !important;font-size:12px;user-select:none;cursor:pointer;-webkit-user-select:none;-moz-user-select:none}.viewFramework-sidebar .sidebar-fold:hover{background:#37424f}.viewFramework-sidebar .sidebar-nav{width:180px}.viewFramework-sidebar .sidebar-nav ul{margin:0px;padding:0px;list-style:none;overflow:hidden}.viewFramework-sidebar .sidebar-nav li a{display:block;width:100%;height:40px;line-height:40px;overflow:hidden}.viewFramework-sidebar .sidebar-nav li a:hover{background:#37424f}.viewFramework-sidebar .sidebar-nav li a:hover .nav-icon,.viewFramework-sidebar .sidebar-nav li a:hover .nav-title{color:#fff}.viewFramework-sidebar .sidebar-nav .nav-item{position:relative}.viewFramework-sidebar .sidebar-nav .nav-comment{background:#2d3945;color:#cccccc;height:26px;margin-left:8px;line-height:26px;padding:0 7px;vertical-align:middle;position:relative;display:none}.viewFramework-sidebar .sidebar-nav .nav-comment .icon-arrow-left{position:absolute;left:-14px;line-height:26px;font-size:24px;color:#2d3945}.viewFramework-sidebar .sidebar-nav .nav-tooltip-comment{color:#ccc}.viewFramework-sidebar .sidebar-nav .sidebar-title{height:40px;background:#22282e;color:#fff;line-height:40px;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none}.viewFramework-sidebar .sidebar-nav .sidebar-title:hover{background:#414d5c}.viewFramework-sidebar .sidebar-nav .sidebar-title-icon{display:inline-block;margin:0 8px 0 20px;vertical-align:middle;transition:transform 0.12s;-o-transition:-o-transform 0.12s;-ms-transition:-ms-transform 0.12s;-moz-transition:-moz-transform 0.12s;-webkit-transition:-webkit-transform 0.12s}.viewFramework-sidebar .sidebar-manage{vertical-align:middle;position:absolute;height:40px;width:40px;right:0}.viewFramework-sidebar .sidebar-manage a{display:block;width:100%;height:100%;text-align:center;line-height:40px;font-size:14px;color:#a0abb3;text-decoration:none}.viewFramework-sidebar .sidebar-nav-fold ul{height:0 !important;overflow:hidden}.viewFramework-sidebar .sidebar-nav-fold .sidebar-title-icon{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg)}.viewFramework-sidebar .sidebar-nav-fold .sidebar-title{background:#37424f;border-bottom:1px solid #414d5c}.viewFramework-sidebar .sidebar-nav .nav-item:hover .nav-comment{display:inline-block}.viewFramework-sidebar .entrance-nav .nav-comment{margin-left:10px}.viewFramework-sidebar .sidebar-nav .nav-icon{width:50px;text-align:center;font-size:16px;float:left;color:#aeb9c2}.viewFramework-sidebar .sidebar-nav .nav-title{float:left;overflow:hidden;color:#fff;white-space:nowrap;text-overflow:ellipsis;display:block;width:130px}.viewFramework-sidebar .entrance-nav .nav-title{width:auto}.viewFramework-sidebar .sidebar-nav li.consolehome .nav-tooltip{top:15px;line-height:40px}.viewFramework-sidebar .sidebar-nav li.consolehome a{height:70px;line-height:70px;background:#293038}.viewFramework-sidebar .sidebar-nav li.consolehome a .nav-icon{font-size:20px}.viewFramework-sidebar .sidebar-nav li.consolehome.active a{background:#293038}.viewFramework-sidebar .sidebar-nav li.active a{background:#0099cc}.viewFramework-sidebar .sidebar-nav li.active a .nav-title{color:#fff}.viewFramework-sidebar .sidebar-nav li.active a .nav-icon{color:#fff}.viewFramework-sidebar .sidebar-nav .manage-nav{height:30px;overflow:hidden}.viewFramework-sidebar .sidebar-nav .manage-nav:hover .nav-icon{color:#fff}.viewFramework-sidebar .sidebar-nav .manage-nav a{display:block;height:100%}.viewFramework-sidebar .sidebar-nav .manage-nav .nav-icon{height:100%;line-height:30px;foLine truncated
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,262 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
@font-face {
/*无边框*/
font-family: "iconfont-1";
src: url('icon1/iconfont.eot?t=1458627591'); /* IE9*/
src: url('icon1/iconfont.eot?t=1458627591#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('icon1/iconfont.woff?t=1458627591') format('woff'), /* chrome, firefox */ url('icon1/iconfont.ttf?t=1458627591') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('icon1/iconfont.svg?t=1458627591#iconfont') format('svg'); /* iOS 4.1- */
}
@font-face {
/*有边框*/
font-family: "iconfont-2";
src: url('icon/iconfont.eot'); /* IE9*/
src: url('icon/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ url('icon/iconfont.woff') format('woff'), /* chrome, firefox */ url('icon/iconfont.ttf') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ url('icon/iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
/* 有边框 */
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.iconfont-1 {
/*无边框*/
font-family: "iconfont-1" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.iconfont-2 {
/*有边框*/
font-family: "iconfont-2" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: 0.2px;
-moz-osx-font-smoothing: grayscale;
}
.logo {
}
.panel-logo {
padding-right: 2px;
font-size: 18px;
display: inline-block;
color: #333;
}
.icon-lg {
font-size: 80px !important;
}
.icon-size-md {
font-size: 40px !important;
vertical-align: middle;
}
.icon-size-lg {
font-size: 80px !important;
vertical-align: middle;
}
.icon-hsf:before {
content: "\e62f" !important;
}
.icon-rocketmq:before {
content: "\e632" !important;
}
.icon-notify:before {
content: "\e61e" !important;
}
.icon-tddl:before {
content: "\e61e" !important;
}
.icon-pandora:before {
content: "\e622" !important;
}
.icon-ailtomcat:before {
content: "\e628" !important;
}
.icon-configserver:before {
content: "\e61e" !important;
}
.icon-diamondserver:before {
content: "\e62a" !important;
}
.icon-vipserver:before {
content: "\e625" !important;
}
.icon-eagleeye:before {
content: "\e62c" !important;
}
.icon-tengine:before {
content: "\e635" !important;
}
.icon-tair:before {
content: "\e634" !important;
}
.icon-hbase:before {
content: "\e62d" !important;
}
.icon-jstorm:before {
content: "\e627" !important;
}
.icon-histore:before {
content: "\e62e" !important;
}
.icon-jingwei:before {
content: "\e61e" !important;
}
.icon-txc:before {
content: "\e636" !important;
}
.icon-edas:before {
content: "\e620" !important;
}
.icon-csb:before {
content: "\e61e" !important;
}
.icon-ons:before {
content: "\e630" !important;
}
.icon-drds:before {
content: "\e61f" !important;
}
.icon-duct:before {
content: "\e62b" !important;
}
.icon-amazon:before {
content: "\e61e" !important;
}
.icon-autoload:before {
content: "\e61e" !important;
}
.icon-switch:before {
content: "\e633" !important;
}
.icon-sentinel:before {
content: "\e623" !important;
}
.icon-preplan:before {
content: "\e631" !important;
}
.icon-moses:before {
content: "\e61e" !important;
}
.icon-zeus:before {
content: "\e61e" !important;
}
.icon-athena:before {
content: "\e61e" !important;
}
.icon-bcp:before {
content: "\e61e" !important;
}
.icon-lark:before {
content: "\e61e" !important;
}
.icon-nest:before {
content: "\e61e" !important;
}
.icon-monkeyking:before {
content: "\e61e" !important;
}
.icon-tab:before {
content: "\e61e" !important;
}
.icon-oceanus:before {
content: "\e61e" !important;
}
.icon-eos :before {
content: "\e61e" !important;
}
.icon-sonar:before {
content: "\e61e" !important;
}
.icon-ai:before {
content: "\e605" !important;
}
.icon-hotcode:before {
content: "\e621" !important;
}
.icon-taokeeper:before {
content: "\e624" !important;
}
.icon-mdl:before {
content: "\e61e" !important;
}
.icon-mw:before {
content: "\e61e" !important;
}
.icon-default:before {
content: "\e607" !important;
}
.icon-alitomcat:before {
content: "\e607" !important;
}
@@ -0,0 +1,126 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
.CodeMirror-merge {
position: relative;
border: 1px solid #ddd;
white-space: pre;
}
.CodeMirror-merge, .CodeMirror-merge .CodeMirror {
height: 350px;
}
.CodeMirror-merge-2pane .CodeMirror-merge-pane { width: 47%; }
.CodeMirror-merge-2pane .CodeMirror-merge-gap { width: 6%; }
.CodeMirror-merge-3pane .CodeMirror-merge-pane { width: 31%; }
.CodeMirror-merge-3pane .CodeMirror-merge-gap { width: 3.5%; }
.CodeMirror-merge-pane {
display: inline-block;
white-space: normal;
vertical-align: top;
}
.CodeMirror-merge-pane-rightmost {
position: absolute;
right: 0px;
z-index: 1;
}
.CodeMirror-merge-gap {
z-index: 2;
display: inline-block;
height: 100%;
-moz-box-sizing: border-box;
box-sizing: border-box;
overflow: hidden;
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
position: relative;
background: #f8f8f8;
}
.CodeMirror-merge-scrolllock-wrap {
position: absolute;
bottom: 0; left: 50%;
}
.CodeMirror-merge-scrolllock {
position: relative;
left: -50%;
cursor: pointer;
color: #555;
line-height: 1;
}
.CodeMirror-merge-copybuttons-left, .CodeMirror-merge-copybuttons-right {
position: absolute;
left: 0; top: 0;
right: 0; bottom: 0;
line-height: 1;
}
.CodeMirror-merge-copy {
position: absolute;
cursor: pointer;
color: #44c;
z-index: 3;
}
.CodeMirror-merge-copy-reverse {
position: absolute;
cursor: pointer;
color: #44c;
}
.CodeMirror-merge-copybuttons-left .CodeMirror-merge-copy { left: 2px; }
.CodeMirror-merge-copybuttons-right .CodeMirror-merge-copy { right: 2px; }
.CodeMirror-merge-r-inserted, .CodeMirror-merge-l-inserted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12MwuCXy3+CWyH8GBgYGJgYkAABZbAQ9ELXurwAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-deleted, .CodeMirror-merge-l-deleted {
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAACCAYAAACddGYaAAAAGUlEQVQI12M4Kyb2/6yY2H8GBgYGJgYkAABURgPz6Ks7wQAAAABJRU5ErkJggg==);
background-position: bottom left;
background-repeat: repeat-x;
}
.CodeMirror-merge-r-chunk { background: #ffffe0; }
.CodeMirror-merge-r-chunk-start { border-top: 1px solid #ee8; }
.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #ee8; }
.CodeMirror-merge-r-connect { fill: #ffffe0; stroke: #ee8; stroke-width: 1px; }
.CodeMirror-merge-l-chunk { background: #eef; }
.CodeMirror-merge-l-chunk-start { border-top: 1px solid #88e; }
.CodeMirror-merge-l-chunk-end { border-bottom: 1px solid #88e; }
.CodeMirror-merge-l-connect { fill: #eef; stroke: #88e; stroke-width: 1px; }
.CodeMirror-merge-l-chunk.CodeMirror-merge-r-chunk { background: #dfd; }
.CodeMirror-merge-l-chunk-start.CodeMirror-merge-r-chunk-start { border-top: 1px solid #4e4; }
.CodeMirror-merge-l-chunk-end.CodeMirror-merge-r-chunk-end { border-bottom: 1px solid #4e4; }
.CodeMirror-merge-collapsed-widget:before {
content: "(...)";
}
.CodeMirror-merge-collapsed-widget {
cursor: pointer;
color: #88b;
background: #eef;
border: 1px solid #ddf;
font-size: 90%;
padding: 0 3px;
border-radius: 4px;
}
.CodeMirror-merge-collapsed-line .CodeMirror-gutter-elt { display: none; }
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 390.21"><defs><style>.cls-1{fill:#fff}.cls-2{fill:url(#未命名的渐变_7)}</style><linearGradient id="未命名的渐变_7" x1="816.73" y1="195.1" x2="1492.16" y2="195.1" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#4190ff"/><stop offset="1" stop-color="#1be1f6"/></linearGradient></defs><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M1788 389.24h-175.45v-77.1H1788c7.13 0 17.72-1.53 26.06-5.83 8.08-4.17 16.35-10.47 16.35-32.72 0-21.89-8.25-28-16.31-32-7.22-3.59-17.1-5.59-27.1-5.59h-69.4c-5.4 0-33.74-.78-61.47-16.17-36.18-20.08-56.13-55.13-56.13-100.46 0-45.17 19.81-80.33 55.78-100.75a133.14 133.14 0 0 1 61.8-16.83h161.92v77.1h-161.76c-.77 0-13.5.64-24.5 7.14-7.5 4.44-16.12 11.39-16.12 33.34s8.58 28.58 16.05 32.83c9.44 5.37 20.87 6.65 24.48 6.69H1787c22.16 0 43.38 4.73 61.37 13.67 38.12 18.94 59.11 54.2 59.11 101 0 46.59-20.64 81.92-58.11 101.25-24.31 12.56-48.91 14.43-61.37 14.43zm-1498.84-3.85c-11.54 0-23.71-3.26-31.17-12.66L72.29 146.09l1 241.22H1l-1-347C0 23.94 9.41 11.27 24.9 5.87s33.65-1.38 43.85 11.47l184.74 228.57V2h72.29l1 346.76c0 16.4-9.41 29.08-24.9 34.48a38.48 38.48 0 0 1-12.72 2.15z"/><path class="cls-2" d="M937.33 390.21c-107.58 0-195.1-87.52-195.1-195.1S829.75 0 937.33 0a193.92 193.92 0 0 1 137.17 56.36l.16.15 52.64 52.64-54.52 54.52-52.56-52.56a118 118 0 1 0 .56 167.43l53.91-53.91 54.52 54.52-53.91 53.91a193.83 193.83 0 0 1-137.97 57.15z"/><path class="cls-2" d="M1379.86 390.21a194 194 0 0 1-137-56.17l-.38-.38-137.2-139.15L1241.9 57.14A193.83 193.83 0 0 1 1379.86 0C1487.44 0 1575 87.52 1575 195.1s-87.56 195.11-195.14 195.11zm-82.66-110.9a118 118 0 1 0-.76-167.67l-82.64 83.1z"/><path class="cls-1" d="M442.45 386.35L552.52 98.73a84.56 84.56 0 0 1 5.35-10.8 79.54 79.54 0 0 1 4.62 9.35l111.4 289.07h82.88L634.2 68.95A164.41 164.41 0 0 0 619 40.2C597.63 8.45 573.9 1.79 557.75 1.79c-29.44 0-49.78 21.48-61.67 39.5a172.83 172.83 0 0 0-15.37 29.34L359.64 386.35z"/><circle cx="1966.27" cy="356.47" r="33.73" fill="#1be1f6"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1,54 @@
<!DOCTYPE html>
<!--
~ Copyright 1999-2018 Alibaba Group Holding Ltd.
~ Licensed 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.
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Nacos</title>
<link rel="shortcut icon" href="//www.aliyun.com/favicon.ico" type="image/x-icon" />
<link rel="stylesheet" type="text/css" href="css/bootstrap.css">
<link rel="stylesheet" type="text/css" href="css/console1412.css">
<!-- 第三方css开始 -->
<link rel="stylesheet" type="text/css" href="css/codemirror.css">
<link rel="stylesheet" type="text/css" href="css/merge.css">
<link rel="stylesheet" type="text/css" href="css/icon.css">
<link rel="stylesheet" type="text/css" href="css/font-awesome.css">
<!-- 第三方css结束 -->
</head>
<body>
<div id="root" style="overflow:hidden"></div>
<div id="app"></div>
<div id="other"></div>
<!-- 第三方js开始 -->
<script src="js/jquery.js"></script>
<script src="js/codemirror.js"></script>
<script src="js/javascript.js"></script>
<script src="js/xml.js"></script>
<script src="js/codemirror.addone.fullscreen.js"></script>
<script src="js/codemirror.addone.lint.js"></script>
<script src="js/codemirror.lib.json-lint.js"></script>
<script src="js/codemirror.addone.json-lint.js"></script>
<script src="js/codemirror.lib.clike-lint.js"></script>
<script src="js/diff_match_patch.js"></script>
<script src="js/merge.js"></script>
<script src="js/loader.js"></script>
<!-- 第三方js结束 -->
</body>
</html>
@@ -0,0 +1,51 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.defineOption("fullScreen", false, function(cm, val, old) {
if (old == CodeMirror.Init) old = false;
if (!old == !val) return;
if (val) setFullscreen(cm);
else setNormal(cm);
});
function setFullscreen(cm) {
var wrap = cm.getWrapperElement();
cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,
width: wrap.style.width, height: wrap.style.height};
wrap.style.width = "";
wrap.style.height = "auto";
wrap.className += " CodeMirror-fullscreen";
document.documentElement.style.overflow = "hidden";
cm.refresh();
}
function setNormal(cm) {
var wrap = cm.getWrapperElement();
wrap.className = wrap.className.replace(/\s*CodeMirror-fullscreen\b/, "");
document.documentElement.style.overflow = "";
var info = cm.state.fullScreenRestore;
wrap.style.width = info.width; wrap.style.height = info.height;
window.scrollTo(info.scrollLeft, info.scrollTop);
cm.refresh();
}
});
@@ -0,0 +1,41 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
// Depends on jsonlint.js from https://github.com/zaach/jsonlint
// declare global: jsonlint
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
CodeMirror.registerHelper("lint", "json", function(text) {
var found = [];
jsonlint.parseError = function(str, hash) {
var loc = hash.loc;
found.push({from: CodeMirror.Pos(loc.first_line - 1, loc.first_column),
to: CodeMirror.Pos(loc.last_line - 1, loc.last_column),
message: str});
};
try { jsonlint.parse(text); }
catch(e) {}
return found;
});
});
@@ -0,0 +1,248 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
var GUTTER_ID = "CodeMirror-lint-markers";
function showTooltip(e, content) {
var tt = document.createElement("div");
tt.className = "CodeMirror-lint-tooltip";
tt.appendChild(content.cloneNode(true));
document.body.appendChild(tt);
function position(e) {
if (!tt.parentNode) return CodeMirror.off(document, "mousemove", position);
tt.style.top = Math.max(0, e.clientY - tt.offsetHeight - 5) + "px";
tt.style.left = (e.clientX + 5) + "px";
}
CodeMirror.on(document, "mousemove", position);
position(e);
if (tt.style.opacity != null) tt.style.opacity = 1;
return tt;
}
function rm(elt) {
if (elt.parentNode) elt.parentNode.removeChild(elt);
}
function hideTooltip(tt) {
if (!tt.parentNode) return;
if (tt.style.opacity == null) rm(tt);
tt.style.opacity = 0;
setTimeout(function() { rm(tt); }, 600);
}
function showTooltipFor(e, content, node) {
var tooltip = showTooltip(e, content);
function hide() {
CodeMirror.off(node, "mouseout", hide);
if (tooltip) { hideTooltip(tooltip); tooltip = null; }
}
var poll = setInterval(function() {
if (tooltip) for (var n = node;; n = n.parentNode) {
if (n && n.nodeType == 11) n = n.host;
if (n == document.body) return;
if (!n) { hide(); break; }
}
if (!tooltip) return clearInterval(poll);
}, 400);
CodeMirror.on(node, "mouseout", hide);
}
function LintState(cm, options, hasGutter) {
this.marked = [];
this.options = options;
this.timeout = null;
this.hasGutter = hasGutter;
this.onMouseOver = function(e) { onMouseOver(cm, e); };
this.waitingFor = 0
}
function parseOptions(_cm, options) {
if (options instanceof Function) return {getAnnotations: options};
if (!options || options === true) options = {};
return options;
}
function clearMarks(cm) {
var state = cm.state.lint;
if (state.hasGutter) cm.clearGutter(GUTTER_ID);
for (var i = 0; i < state.marked.length; ++i)
state.marked[i].clear();
state.marked.length = 0;
}
function makeMarker(labels, severity, multiple, tooltips) {
var marker = document.createElement("div"), inner = marker;
marker.className = "CodeMirror-lint-marker-" + severity;
if (multiple) {
inner = marker.appendChild(document.createElement("div"));
inner.className = "CodeMirror-lint-marker-multiple";
}
if (tooltips != false) CodeMirror.on(inner, "mouseover", function(e) {
showTooltipFor(e, labels, inner);
});
return marker;
}
function getMaxSeverity(a, b) {
if (a == "error") return a;
else return b;
}
function groupByLine(annotations) {
var lines = [];
for (var i = 0; i < annotations.length; ++i) {
var ann = annotations[i], line = ann.from.line;
(lines[line] || (lines[line] = [])).push(ann);
}
return lines;
}
function annotationTooltip(ann) {
var severity = ann.severity;
if (!severity) severity = "error";
var tip = document.createElement("div");
tip.className = "CodeMirror-lint-message-" + severity;
tip.appendChild(document.createTextNode(ann.message));
return tip;
}
function lintAsync(cm, getAnnotations, passOptions) {
var state = cm.state.lint
var id = ++state.waitingFor
function abort() {
id = -1
cm.off("change", abort)
}
cm.on("change", abort)
getAnnotations(cm.getValue(), function(annotations, arg2) {
cm.off("change", abort)
if (state.waitingFor != id) return
if (arg2 && annotations instanceof CodeMirror) annotations = arg2
updateLinting(cm, annotations)
}, passOptions, cm);
}
function startLinting(cm) {
var state = cm.state.lint, options = state.options;
var passOptions = options.options || options; // Support deprecated passing of `options` property in options
var getAnnotations = options.getAnnotations || cm.getHelper(CodeMirror.Pos(0, 0), "lint");
if (!getAnnotations) return;
if (options.async || getAnnotations.async) {
lintAsync(cm, getAnnotations, passOptions)
} else {
updateLinting(cm, getAnnotations(cm.getValue(), passOptions, cm));
}
}
function updateLinting(cm, annotationsNotSorted) {
clearMarks(cm);
var state = cm.state.lint, options = state.options;
var annotations = groupByLine(annotationsNotSorted);
for (var line = 0; line < annotations.length; ++line) {
var anns = annotations[line];
if (!anns) continue;
var maxSeverity = null;
var tipLabel = state.hasGutter && document.createDocumentFragment();
for (var i = 0; i < anns.length; ++i) {
var ann = anns[i];
var severity = ann.severity;
if (!severity) severity = "error";
maxSeverity = getMaxSeverity(maxSeverity, severity);
if (options.formatAnnotation) ann = options.formatAnnotation(ann);
if (state.hasGutter) tipLabel.appendChild(annotationTooltip(ann));
if (ann.to) state.marked.push(cm.markText(ann.from, ann.to, {
className: "CodeMirror-lint-mark-" + severity,
__annotation: ann
}));
}
if (state.hasGutter)
cm.setGutterMarker(line, GUTTER_ID, makeMarker(tipLabel, maxSeverity, anns.length > 1,
state.options.tooltips));
}
if (options.onUpdateLinting) options.onUpdateLinting(annotationsNotSorted, annotations, cm);
}
function onChange(cm) {
var state = cm.state.lint;
if (!state) return;
clearTimeout(state.timeout);
state.timeout = setTimeout(function(){startLinting(cm);}, state.options.delay || 500);
}
function popupTooltips(annotations, e) {
var target = e.target || e.srcElement;
var tooltip = document.createDocumentFragment();
for (var i = 0; i < annotations.length; i++) {
var ann = annotations[i];
tooltip.appendChild(annotationTooltip(ann));
}
showTooltipFor(e, tooltip, target);
}
function onMouseOver(cm, e) {
var target = e.target || e.srcElement;
if (!/\bCodeMirror-lint-mark-/.test(target.className)) return;
var box = target.getBoundingClientRect(), x = (box.left + box.right) / 2, y = (box.top + box.bottom) / 2;
var spans = cm.findMarksAt(cm.coordsChar({left: x, top: y}, "client"));
var annotations = [];
for (var i = 0; i < spans.length; ++i) {
annotations.push(spans[i].__annotation);
}
if (annotations.length) popupTooltips(annotations, e);
}
CodeMirror.defineOption("lint", false, function(cm, val, old) {
if (old && old != CodeMirror.Init) {
clearMarks(cm);
if (cm.state.lint.options.lintOnChange !== false)
cm.off("change", onChange);
CodeMirror.off(cm.getWrapperElement(), "mouseover", cm.state.lint.onMouseOver);
clearTimeout(cm.state.lint.timeout);
delete cm.state.lint;
}
if (val) {
var gutters = cm.getOption("gutters"), hasLintGutter = false;
for (var i = 0; i < gutters.length; ++i) if (gutters[i] == GUTTER_ID) hasLintGutter = true;
var state = cm.state.lint = new LintState(cm, parseOptions(cm, val), hasLintGutter);
if (state.options.lintOnChange !== false)
cm.on("change", onChange);
if (state.options.tooltips != false)
CodeMirror.on(cm.getWrapperElement(), "mouseover", state.onMouseOver);
startLinting(cm);
}
});
CodeMirror.defineExtension("performLint", function() {
if (this.state.lint) startLinting(this);
});
});
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,799 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
function Context(indented, column, type, info, align, prev) {
this.indented = indented;
this.column = column;
this.type = type;
this.info = info;
this.align = align;
this.prev = prev;
}
function pushContext(state, col, type, info) {
var indent = state.indented;
if (state.context && state.context.type == "statement" && type != "statement")
indent = state.context.indented;
return state.context = new Context(indent, col, type, info, null, state.context);
}
function popContext(state) {
var t = state.context.type;
if (t == ")" || t == "]" || t == "}")
state.indented = state.context.indented;
return state.context = state.context.prev;
}
function typeBefore(stream, state, pos) {
if (state.prevToken == "variable" || state.prevToken == "type") return true;
if (/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(stream.string.slice(0, pos))) return true;
if (state.typeAtEndOfLine && stream.column() == stream.indentation()) return true;
}
function isTopScope(context) {
for (;;) {
if (!context || context.type == "top") return true;
if (context.type == "}" && context.prev.info != "namespace") return false;
context = context.prev;
}
}
CodeMirror.defineMode("clike", function(config, parserConfig) {
var indentUnit = config.indentUnit,
statementIndentUnit = parserConfig.statementIndentUnit || indentUnit,
dontAlignCalls = parserConfig.dontAlignCalls,
keywords = parserConfig.keywords || {},
types = parserConfig.types || {},
builtin = parserConfig.builtin || {},
blockKeywords = parserConfig.blockKeywords || {},
defKeywords = parserConfig.defKeywords || {},
atoms = parserConfig.atoms || {},
hooks = parserConfig.hooks || {},
multiLineStrings = parserConfig.multiLineStrings,
indentStatements = parserConfig.indentStatements !== false,
indentSwitch = parserConfig.indentSwitch !== false,
namespaceSeparator = parserConfig.namespaceSeparator,
isPunctuationChar = parserConfig.isPunctuationChar || /[\[\]{}\(\),;\:\.]/,
numberStart = parserConfig.numberStart || /[\d\.]/,
number = parserConfig.number || /^(?:0x[a-f\d]+|0b[01]+|(?:\d+\.?\d*|\.\d+)(?:e[-+]?\d+)?)(u|ll?|l|f)?/i,
isOperatorChar = parserConfig.isOperatorChar || /[+\-*&%=<>!?|\/]/,
isIdentifierChar = parserConfig.isIdentifierChar || /[\w\$_\xa1-\uffff]/;
var curPunc, isDefKeyword;
function tokenBase(stream, state) {
var ch = stream.next();
if (hooks[ch]) {
var result = hooks[ch](stream, state);
if (result !== false) return result;
}
if (ch == '"' || ch == "'") {
state.tokenize = tokenString(ch);
return state.tokenize(stream, state);
}
if (isPunctuationChar.test(ch)) {
curPunc = ch;
return null;
}
if (numberStart.test(ch)) {
stream.backUp(1)
if (stream.match(number)) return "number"
stream.next()
}
if (ch == "/") {
if (stream.eat("*")) {
state.tokenize = tokenComment;
return tokenComment(stream, state);
}
if (stream.eat("/")) {
stream.skipToEnd();
return "comment";
}
}
if (isOperatorChar.test(ch)) {
while (!stream.match(/^\/[\/*]/, false) && stream.eat(isOperatorChar)) {}
return "operator";
}
stream.eatWhile(isIdentifierChar);
if (namespaceSeparator) while (stream.match(namespaceSeparator))
stream.eatWhile(isIdentifierChar);
var cur = stream.current();
if (contains(keywords, cur)) {
if (contains(blockKeywords, cur)) curPunc = "newstatement";
if (contains(defKeywords, cur)) isDefKeyword = true;
return "keyword";
}
if (contains(types, cur)) return "type";
if (contains(builtin, cur)) {
if (contains(blockKeywords, cur)) curPunc = "newstatement";
return "builtin";
}
if (contains(atoms, cur)) return "atom";
return "variable";
}
function tokenString(quote) {
return function(stream, state) {
var escaped = false, next, end = false;
while ((next = stream.next()) != null) {
if (next == quote && !escaped) {end = true; break;}
escaped = !escaped && next == "\\";
}
if (end || !(escaped || multiLineStrings))
state.tokenize = null;
return "string";
};
}
function tokenComment(stream, state) {
var maybeEnd = false, ch;
while (ch = stream.next()) {
if (ch == "/" && maybeEnd) {
state.tokenize = null;
break;
}
maybeEnd = (ch == "*");
}
return "comment";
}
function maybeEOL(stream, state) {
if (parserConfig.typeFirstDefinitions && stream.eol() && isTopScope(state.context))
state.typeAtEndOfLine = typeBefore(stream, state, stream.pos)
}
// Interface
return {
startState: function(basecolumn) {
return {
tokenize: null,
context: new Context((basecolumn || 0) - indentUnit, 0, "top", null, false),
indented: 0,
startOfLine: true,
prevToken: null
};
},
token: function(stream, state) {
var ctx = state.context;
if (stream.sol()) {
if (ctx.align == null) ctx.align = false;
state.indented = stream.indentation();
state.startOfLine = true;
}
if (stream.eatSpace()) { maybeEOL(stream, state); return null; }
curPunc = isDefKeyword = null;
var style = (state.tokenize || tokenBase)(stream, state);
if (style == "comment" || style == "meta") return style;
if (ctx.align == null) ctx.align = true;
if (curPunc == ";" || curPunc == ":" || (curPunc == "," && stream.match(/^\s*(?:\/\/.*)?$/, false)))
while (state.context.type == "statement") popContext(state);
else if (curPunc == "{") pushContext(state, stream.column(), "}");
else if (curPunc == "[") pushContext(state, stream.column(), "]");
else if (curPunc == "(") pushContext(state, stream.column(), ")");
else if (curPunc == "}") {
while (ctx.type == "statement") ctx = popContext(state);
if (ctx.type == "}") ctx = popContext(state);
while (ctx.type == "statement") ctx = popContext(state);
}
else if (curPunc == ctx.type) popContext(state);
else if (indentStatements &&
(((ctx.type == "}" || ctx.type == "top") && curPunc != ";") ||
(ctx.type == "statement" && curPunc == "newstatement"))) {
pushContext(state, stream.column(), "statement", stream.current());
}
if (style == "variable" &&
((state.prevToken == "def" ||
(parserConfig.typeFirstDefinitions && typeBefore(stream, state, stream.start) &&
isTopScope(state.context) && stream.match(/^\s*\(/, false)))))
style = "def";
if (hooks.token) {
var result = hooks.token(stream, state, style);
if (result !== undefined) style = result;
}
if (style == "def" && parserConfig.styleDefs === false) style = "variable";
state.startOfLine = false;
state.prevToken = isDefKeyword ? "def" : style || curPunc;
maybeEOL(stream, state);
return style;
},
indent: function(state, textAfter) {
if (state.tokenize != tokenBase && state.tokenize != null || state.typeAtEndOfLine) return CodeMirror.Pass;
var ctx = state.context, firstChar = textAfter && textAfter.charAt(0);
if (ctx.type == "statement" && firstChar == "}") ctx = ctx.prev;
if (parserConfig.dontIndentStatements)
while (ctx.type == "statement" && parserConfig.dontIndentStatements.test(ctx.info))
ctx = ctx.prev
if (hooks.indent) {
var hook = hooks.indent(state, ctx, textAfter);
if (typeof hook == "number") return hook
}
var closing = firstChar == ctx.type;
var switchBlock = ctx.prev && ctx.prev.info == "switch";
if (parserConfig.allmanIndentation && /[{(]/.test(firstChar)) {
while (ctx.type != "top" && ctx.type != "}") ctx = ctx.prev
return ctx.indented
}
if (ctx.type == "statement")
return ctx.indented + (firstChar == "{" ? 0 : statementIndentUnit);
if (ctx.align && (!dontAlignCalls || ctx.type != ")"))
return ctx.column + (closing ? 0 : 1);
if (ctx.type == ")" && !closing)
return ctx.indented + statementIndentUnit;
return ctx.indented + (closing ? 0 : indentUnit) +
(!closing && switchBlock && !/^(?:case|default)\b/.test(textAfter) ? indentUnit : 0);
},
electricInput: indentSwitch ? /^\s*(?:case .*?:|default:|\{\}?|\})$/ : /^\s*[{}]$/,
blockCommentStart: "/*",
blockCommentEnd: "*/",
lineComment: "//",
fold: "brace"
};
});
function words(str) {
var obj = {}, words = str.split(" ");
for (var i = 0; i < words.length; ++i) obj[words[i]] = true;
return obj;
}
function contains(words, word) {
if (typeof words === "function") {
return words(word);
} else {
return words.propertyIsEnumerable(word);
}
}
var cKeywords = "auto if break case register continue return default do sizeof " +
"static else struct switch extern typedef union for goto while enum const volatile";
var cTypes = "int long char short double float unsigned signed void size_t ptrdiff_t";
function cppHook(stream, state) {
if (!state.startOfLine) return false
for (var ch, next = null; ch = stream.peek();) {
if (ch == "\\" && stream.match(/^.$/)) {
next = cppHook
break
} else if (ch == "/" && stream.match(/^\/[\/\*]/, false)) {
break
}
stream.next()
}
state.tokenize = next
return "meta"
}
function pointerHook(_stream, state) {
if (state.prevToken == "type") return "type";
return false;
}
function cpp14Literal(stream) {
stream.eatWhile(/[\w\.']/);
return "number";
}
function cpp11StringHook(stream, state) {
stream.backUp(1);
// Raw strings.
if (stream.match(/(R|u8R|uR|UR|LR)/)) {
var match = stream.match(/"([^\s\\()]{0,16})\(/);
if (!match) {
return false;
}
state.cpp11RawStringDelim = match[1];
state.tokenize = tokenRawString;
return tokenRawString(stream, state);
}
// Unicode strings/chars.
if (stream.match(/(u8|u|U|L)/)) {
if (stream.match(/["']/, /* eat */ false)) {
return "string";
}
return false;
}
// Ignore this hook.
stream.next();
return false;
}
function cppLooksLikeConstructor(word) {
var lastTwo = /(\w+)::~?(\w+)$/.exec(word);
return lastTwo && lastTwo[1] == lastTwo[2];
}
// C#-style strings where "" escapes a quote.
function tokenAtString(stream, state) {
var next;
while ((next = stream.next()) != null) {
if (next == '"' && !stream.eat('"')) {
state.tokenize = null;
break;
}
}
return "string";
}
// C++11 raw string literal is <prefix>"<delim>( anything )<delim>", where
// <delim> can be a string up to 16 characters long.
function tokenRawString(stream, state) {
// Escape characters that have special regex meanings.
var delim = state.cpp11RawStringDelim.replace(/[^\w\s]/g, '\\$&');
var match = stream.match(new RegExp(".*?\\)" + delim + '"'));
if (match)
state.tokenize = null;
else
stream.skipToEnd();
return "string";
}
function def(mimes, mode) {
if (typeof mimes == "string") mimes = [mimes];
var words = [];
function add(obj) {
if (obj) for (var prop in obj) if (obj.hasOwnProperty(prop))
words.push(prop);
}
add(mode.keywords);
add(mode.types);
add(mode.builtin);
add(mode.atoms);
if (words.length) {
mode.helperType = mimes[0];
CodeMirror.registerHelper("hintWords", mimes[0], words);
}
for (var i = 0; i < mimes.length; ++i)
CodeMirror.defineMIME(mimes[i], mode);
}
def(["text/x-csrc", "text/x-c", "text/x-chdr"], {
name: "clike",
keywords: words(cKeywords),
types: words(cTypes + " bool _Complex _Bool float_t double_t intptr_t intmax_t " +
"int8_t int16_t int32_t int64_t uintptr_t uintmax_t uint8_t uint16_t " +
"uint32_t uint64_t"),
blockKeywords: words("case do else for if switch while struct"),
defKeywords: words("struct"),
typeFirstDefinitions: true,
atoms: words("null true false"),
hooks: {"#": cppHook, "*": pointerHook},
modeProps: {fold: ["brace", "include"]}
});
def(["text/x-c++src", "text/x-c++hdr"], {
name: "clike",
keywords: words(cKeywords + " asm dynamic_cast namespace reinterpret_cast try explicit new " +
"static_cast typeid catch operator template typename class friend private " +
"this using const_cast inline public throw virtual delete mutable protected " +
"alignas alignof constexpr decltype nullptr noexcept thread_local final " +
"static_assert override"),
types: words(cTypes + " bool wchar_t"),
blockKeywords: words("catch class do else finally for if struct switch try while"),
defKeywords: words("class namespace struct enum union"),
typeFirstDefinitions: true,
atoms: words("true false null"),
dontIndentStatements: /^template$/,
isIdentifierChar: /[\w\$_~\xa1-\uffff]/,
hooks: {
"#": cppHook,
"*": pointerHook,
"u": cpp11StringHook,
"U": cpp11StringHook,
"L": cpp11StringHook,
"R": cpp11StringHook,
"0": cpp14Literal,
"1": cpp14Literal,
"2": cpp14Literal,
"3": cpp14Literal,
"4": cpp14Literal,
"5": cpp14Literal,
"6": cpp14Literal,
"7": cpp14Literal,
"8": cpp14Literal,
"9": cpp14Literal,
token: function(stream, state, style) {
if (style == "variable" && stream.peek() == "(" &&
(state.prevToken == ";" || state.prevToken == null ||
state.prevToken == "}") &&
cppLooksLikeConstructor(stream.current()))
return "def";
}
},
namespaceSeparator: "::",
modeProps: {fold: ["brace", "include"]}
});
def("text/x-java", {
name: "clike",
keywords: words("abstract assert break case catch class const continue default " +
"do else enum extends final finally float for goto if implements import " +
"instanceof interface native new package private protected public " +
"return static strictfp super switch synchronized this throw throws transient " +
"try volatile while @interface"),
types: words("byte short int long float double boolean char void Boolean Byte Character Double Float " +
"Integer Long Number Object Short String StringBuffer StringBuilder Void"),
blockKeywords: words("catch class do else finally for if switch try while"),
defKeywords: words("class interface package enum @interface"),
typeFirstDefinitions: true,
atoms: words("true false null"),
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
hooks: {
"@": function(stream) {
// Don't match the @interface keyword.
if (stream.match('interface', false)) return false;
stream.eatWhile(/[\w\$_]/);
return "meta";
}
},
modeProps: {fold: ["brace", "import"]}
});
def("text/x-csharp", {
name: "clike",
keywords: words("abstract as async await base break case catch checked class const continue" +
" default delegate do else enum event explicit extern finally fixed for" +
" foreach goto if implicit in interface internal is lock namespace new" +
" operator out override params private protected public readonly ref return sealed" +
" sizeof stackalloc static struct switch this throw try typeof unchecked" +
" unsafe using virtual void volatile while add alias ascending descending dynamic from get" +
" global group into join let orderby partial remove select set value var yield"),
types: words("Action Boolean Byte Char DateTime DateTimeOffset Decimal Double Func" +
" Guid Int16 Int32 Int64 Object SByte Single String Task TimeSpan UInt16 UInt32" +
" UInt64 bool byte char decimal double short int long object" +
" sbyte float string ushort uint ulong"),
blockKeywords: words("catch class do else finally for foreach if struct switch try while"),
defKeywords: words("class interface namespace struct var"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {
"@": function(stream, state) {
if (stream.eat('"')) {
state.tokenize = tokenAtString;
return tokenAtString(stream, state);
}
stream.eatWhile(/[\w\$_]/);
return "meta";
}
}
});
function tokenTripleString(stream, state) {
var escaped = false;
while (!stream.eol()) {
if (!escaped && stream.match('"""')) {
state.tokenize = null;
break;
}
escaped = stream.next() == "\\" && !escaped;
}
return "string";
}
def("text/x-scala", {
name: "clike",
keywords: words(
/* scala */
"abstract case catch class def do else extends final finally for forSome if " +
"implicit import lazy match new null object override package private protected return " +
"sealed super this throw trait try type val var while with yield _ " +
/* package scala */
"assert assume require print println printf readLine readBoolean readByte readShort " +
"readChar readInt readLong readFloat readDouble"
),
types: words(
"AnyVal App Application Array BufferedIterator BigDecimal BigInt Char Console Either " +
"Enumeration Equiv Error Exception Fractional Function IndexedSeq Int Integral Iterable " +
"Iterator List Map Numeric Nil NotNull Option Ordered Ordering PartialFunction PartialOrdering " +
"Product Proxy Range Responder Seq Serializable Set Specializable Stream StringBuilder " +
"StringContext Symbol Throwable Traversable TraversableOnce Tuple Unit Vector " +
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
multiLineStrings: true,
blockKeywords: words("catch class enum do else finally for forSome if match switch try while"),
defKeywords: words("class enum def object package trait type val var"),
atoms: words("true false null"),
indentStatements: false,
indentSwitch: false,
isOperatorChar: /[+\-*&%=<>!?|\/#:@]/,
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
},
'"': function(stream, state) {
if (!stream.match('""')) return false;
state.tokenize = tokenTripleString;
return state.tokenize(stream, state);
},
"'": function(stream) {
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
return "atom";
},
"=": function(stream, state) {
var cx = state.context
if (cx.type == "}" && cx.align && stream.eat(">")) {
state.context = new Context(cx.indented, cx.column, cx.type, cx.info, null, cx.prev)
return "operator"
} else {
return false
}
}
},
modeProps: {closeBrackets: {triples: '"'}}
});
function tokenKotlinString(tripleString){
return function (stream, state) {
var escaped = false, next, end = false;
while (!stream.eol()) {
if (!tripleString && !escaped && stream.match('"') ) {end = true; break;}
if (tripleString && stream.match('"""')) {end = true; break;}
next = stream.next();
if(!escaped && next == "$" && stream.match('{'))
stream.skipTo("}");
escaped = !escaped && next == "\\" && !tripleString;
}
if (end || !tripleString)
state.tokenize = null;
return "string";
}
}
def("text/x-kotlin", {
name: "clike",
keywords: words(
/*keywords*/
"package as typealias class interface this super val " +
"var fun for is in This throw return " +
"break continue object if else while do try when !in !is as? " +
/*soft keywords*/
"file import where by get set abstract enum open inner override private public internal " +
"protected catch finally out final vararg reified dynamic companion constructor init " +
"sealed field property receiver param sparam lateinit data inline noinline tailrec " +
"external annotation crossinline const operator infix suspend"
),
types: words(
/* package java.lang */
"Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable " +
"Compiler Double Exception Float Integer Long Math Number Object Package Pair Process " +
"Runtime Runnable SecurityManager Short StackTraceElement StrictMath String " +
"StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void"
),
intendSwitch: false,
indentStatements: false,
multiLineStrings: true,
number: /^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+\.?\d*|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,
blockKeywords: words("catch class do else finally for if where try while enum"),
defKeywords: words("class val var object package interface fun"),
atoms: words("true false null this"),
hooks: {
'"': function(stream, state) {
state.tokenize = tokenKotlinString(stream.match('""'));
return state.tokenize(stream, state);
}
},
modeProps: {closeBrackets: {triples: '"'}}
});
def(["x-shader/x-vertex", "x-shader/x-fragment"], {
name: "clike",
keywords: words("sampler1D sampler2D sampler3D samplerCube " +
"sampler1DShadow sampler2DShadow " +
"const attribute uniform varying " +
"break continue discard return " +
"for while do if else struct " +
"in out inout"),
types: words("float int bool void " +
"vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 " +
"mat2 mat3 mat4"),
blockKeywords: words("for while do if else struct"),
builtin: words("radians degrees sin cos tan asin acos atan " +
"pow exp log exp2 sqrt inversesqrt " +
"abs sign floor ceil fract mod min max clamp mix step smoothstep " +
"length distance dot cross normalize ftransform faceforward " +
"reflect refract matrixCompMult " +
"lessThan lessThanEqual greaterThan greaterThanEqual " +
"equal notEqual any all not " +
"texture1D texture1DProj texture1DLod texture1DProjLod " +
"texture2D texture2DProj texture2DLod texture2DProjLod " +
"texture3D texture3DProj texture3DLod texture3DProjLod " +
"textureCube textureCubeLod " +
"shadow1D shadow2D shadow1DProj shadow2DProj " +
"shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod " +
"dFdx dFdy fwidth " +
"noise1 noise2 noise3 noise4"),
atoms: words("true false " +
"gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex " +
"gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 " +
"gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 " +
"gl_FogCoord gl_PointCoord " +
"gl_Position gl_PointSize gl_ClipVertex " +
"gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor " +
"gl_TexCoord gl_FogFragCoord " +
"gl_FragCoord gl_FrontFacing " +
"gl_FragData gl_FragDepth " +
"gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix " +
"gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse " +
"gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse " +
"gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose " +
"gl_ProjectionMatrixInverseTranspose " +
"gl_ModelViewProjectionMatrixInverseTranspose " +
"gl_TextureMatrixInverseTranspose " +
"gl_NormalScale gl_DepthRange gl_ClipPlane " +
"gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel " +
"gl_FrontLightModelProduct gl_BackLightModelProduct " +
"gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ " +
"gl_FogParameters " +
"gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords " +
"gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats " +
"gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits " +
"gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits " +
"gl_MaxDrawBuffers"),
indentSwitch: false,
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-nesc", {
name: "clike",
keywords: words(cKeywords + "as atomic async call command component components configuration event generic " +
"implementation includes interface module new norace nx_struct nx_union post provides " +
"signal task uses abstract extends"),
types: words(cTypes),
blockKeywords: words("case do else for if switch while struct"),
atoms: words("null true false"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
def("text/x-objectivec", {
name: "clike",
keywords: words(cKeywords + "inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in " +
"inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),
types: words(cTypes),
atoms: words("YES NO NULL NILL ON OFF true false"),
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$]/);
return "keyword";
},
"#": cppHook,
indent: function(_state, ctx, textAfter) {
if (ctx.type == "statement" && /^@\w/.test(textAfter)) return ctx.indented
}
},
modeProps: {fold: "brace"}
});
def("text/x-squirrel", {
name: "clike",
keywords: words("base break clone continue const default delete enum extends function in class" +
" foreach local resume return this throw typeof yield constructor instanceof static"),
types: words(cTypes),
blockKeywords: words("case catch class else for foreach if switch try while"),
defKeywords: words("function local class"),
typeFirstDefinitions: true,
atoms: words("true false null"),
hooks: {"#": cppHook},
modeProps: {fold: ["brace", "include"]}
});
// Ceylon Strings need to deal with interpolation
var stringTokenizer = null;
function tokenCeylonString(type) {
return function(stream, state) {
var escaped = false, next, end = false;
while (!stream.eol()) {
if (!escaped && stream.match('"') &&
(type == "single" || stream.match('""'))) {
end = true;
break;
}
if (!escaped && stream.match('``')) {
stringTokenizer = tokenCeylonString(type);
end = true;
break;
}
next = stream.next();
escaped = type == "single" && !escaped && next == "\\";
}
if (end)
state.tokenize = null;
return "string";
}
}
def("text/x-ceylon", {
name: "clike",
keywords: words("abstracts alias assembly assert assign break case catch class continue dynamic else" +
" exists extends finally for function given if import in interface is let module new" +
" nonempty object of out outer package return satisfies super switch then this throw" +
" try value void while"),
types: function(word) {
// In Ceylon all identifiers that start with an uppercase are types
var first = word.charAt(0);
return (first === first.toUpperCase() && first !== first.toLowerCase());
},
blockKeywords: words("case catch class dynamic else finally for function if interface module new object switch try while"),
defKeywords: words("class dynamic function interface module object package value"),
builtin: words("abstract actual aliased annotation by default deprecated doc final formal late license" +
" native optional sealed see serializable shared suppressWarnings tagged throws variable"),
isPunctuationChar: /[\[\]{}\(\),;\:\.`]/,
isOperatorChar: /[+\-*&%=<>!?|^~:\/]/,
numberStart: /[\d#$]/,
number: /^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,
multiLineStrings: true,
typeFirstDefinitions: true,
atoms: words("true false null larger smaller equal empty finished"),
indentSwitch: false,
styleDefs: false,
hooks: {
"@": function(stream) {
stream.eatWhile(/[\w\$_]/);
return "meta";
},
'"': function(stream, state) {
state.tokenize = tokenCeylonString(stream.match('""') ? "triple" : "single");
return state.tokenize(stream, state);
},
'`': function(stream, state) {
if (!stringTokenizer || !stream.match('`')) return false;
state.tokenize = stringTokenizer;
stringTokenizer = null;
return state.tokenize(stream, state);
},
"'": function(stream) {
stream.eatWhile(/[\w\$_\xa1-\uffff]/);
return "atom";
},
token: function(_stream, state, style) {
if ((style == "variable" || style == "type") &&
state.prevToken == ".") {
return "variable-2";
}
}
},
modeProps: {
fold: ["brace", "import"],
closeBrackets: {triples: '"'}
}
});
});
@@ -0,0 +1,445 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
* Licensed 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.
*/
/* Jison generated parser */
var jsonlint = (function(){
var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"JSONString":3,"STRING":4,"JSONNumber":5,"NUMBER":6,"JSONNullLiteral":7,"NULL":8,"JSONBooleanLiteral":9,"TRUE":10,"FALSE":11,"JSONText":12,"JSONValue":13,"EOF":14,"JSONObject":15,"JSONArray":16,"{":17,"}":18,"JSONMemberList":19,"JSONMember":20,":":21,",":22,"[":23,"]":24,"JSONElementList":25,"$accept":0,"$end":1},
terminals_: {2:"error",4:"STRING",6:"NUMBER",8:"NULL",10:"TRUE",11:"FALSE",14:"EOF",17:"{",18:"}",21:":",22:",",23:"[",24:"]"},
productions_: [0,[3,1],[5,1],[7,1],[9,1],[9,1],[12,2],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[15,2],[15,3],[20,3],[19,1],[19,3],[16,2],[16,3],[25,1],[25,3]],
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
var $0 = $$.length - 1;
switch (yystate) {
case 1: // replace escaped characters with actual character
this.$ = yytext.replace(/\\(\\|")/g, "$"+"1")
.replace(/\\n/g,'\n')
.replace(/\\r/g,'\r')
.replace(/\\t/g,'\t')
.replace(/\\v/g,'\v')
.replace(/\\f/g,'\f')
.replace(/\\b/g,'\b');
break;
case 2:this.$ = Number(yytext);
break;
case 3:this.$ = null;
break;
case 4:this.$ = true;
break;
case 5:this.$ = false;
break;
case 6:return this.$ = $$[$0-1];
break;
case 13:this.$ = {};
break;
case 14:this.$ = $$[$0-1];
break;
case 15:this.$ = [$$[$0-2], $$[$0]];
break;
case 16:this.$ = {}; this.$[$$[$0][0]] = $$[$0][1];
break;
case 17:this.$ = $$[$0-2]; $$[$0-2][$$[$0][0]] = $$[$0][1];
break;
case 18:this.$ = [];
break;
case 19:this.$ = $$[$0-1];
break;
case 20:this.$ = [$$[$0]];
break;
case 21:this.$ = $$[$0-2]; $$[$0-2].push($$[$0]);
break;
}
},
table: [{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],12:1,13:2,15:7,16:8,17:[1,14],23:[1,15]},{1:[3]},{14:[1,16]},{14:[2,7],18:[2,7],22:[2,7],24:[2,7]},{14:[2,8],18:[2,8],22:[2,8],24:[2,8]},{14:[2,9],18:[2,9],22:[2,9],24:[2,9]},{14:[2,10],18:[2,10],22:[2,10],24:[2,10]},{14:[2,11],18:[2,11],22:[2,11],24:[2,11]},{14:[2,12],18:[2,12],22:[2,12],24:[2,12]},{14:[2,3],18:[2,3],22:[2,3],24:[2,3]},{14:[2,4],18:[2,4],22:[2,4],24:[2,4]},{14:[2,5],18:[2,5],22:[2,5],24:[2,5]},{14:[2,1],18:[2,1],21:[2,1],22:[2,1],24:[2,1]},{14:[2,2],18:[2,2],22:[2,2],24:[2,2]},{3:20,4:[1,12],18:[1,17],19:18,20:19},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:23,15:7,16:8,17:[1,14],23:[1,15],24:[1,21],25:22},{1:[2,6]},{14:[2,13],18:[2,13],22:[2,13],24:[2,13]},{18:[1,24],22:[1,25]},{18:[2,16],22:[2,16]},{21:[1,26]},{14:[2,18],18:[2,18],22:[2,18],24:[2,18]},{22:[1,28],24:[1,27]},{22:[2,20],24:[2,20]},{14:[2,14],18:[2,14],22:[2,14],24:[2,14]},{3:20,4:[1,12],20:29},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:30,15:7,16:8,17:[1,14],23:[1,15]},{14:[2,19],18:[2,19],22:[2,19],24:[2,19]},{3:5,4:[1,12],5:6,6:[1,13],7:3,8:[1,9],9:4,10:[1,10],11:[1,11],13:31,15:7,16:8,17:[1,14],23:[1,15]},{18:[2,17],22:[2,17]},{18:[2,15],22:[2,15]},{22:[2,21],24:[2,21]}],
defaultActions: {16:[2,6]},
parseError: function parseError(str, hash) {
throw new Error(str);
},
parse: function parse(input) {
var self = this,
stack = [0],
vstack = [null], // semantic value stack
lstack = [], // location stack
table = this.table,
yytext = '',
yylineno = 0,
yyleng = 0,
recovering = 0,
TERROR = 2,
EOF = 1;
//this.reductionCount = this.shiftCount = 0;
this.lexer.setInput(input);
this.lexer.yy = this.yy;
this.yy.lexer = this.lexer;
if (typeof this.lexer.yylloc == 'undefined')
this.lexer.yylloc = {};
var yyloc = this.lexer.yylloc;
lstack.push(yyloc);
if (typeof this.yy.parseError === 'function')
this.parseError = this.yy.parseError;
function popStack (n) {
stack.length = stack.length - 2*n;
vstack.length = vstack.length - n;
lstack.length = lstack.length - n;
}
function lex() {
var token;
token = self.lexer.lex() || 1; // $end = 1
// if token isn't its numeric value, convert
if (typeof token !== 'number') {
token = self.symbols_[token] || token;
}
return token;
}
var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
while (true) {
// retreive state number from top of stack
state = stack[stack.length-1];
// use default actions if available
if (this.defaultActions[state]) {
action = this.defaultActions[state];
} else {
if (symbol == null)
symbol = lex();
// read action for current state and first input
action = table[state] && table[state][symbol];
}
// handle parse error
_handle_error:
if (typeof action === 'undefined' || !action.length || !action[0]) {
if (!recovering) {
// Report error
expected = [];
for (p in table[state]) if (this.terminals_[p] && p > 2) {
expected.push("'"+this.terminals_[p]+"'");
}
var errStr = '';
if (this.lexer.showPosition) {
errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+expected.join(', ') + ", got '" + this.terminals_[symbol]+ "'";
} else {
errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
(symbol == 1 /*EOF*/ ? "end of input" :
("'"+(this.terminals_[symbol] || symbol)+"'"));
}
this.parseError(errStr,
{text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
}
// just recovered from another error
if (recovering == 3) {
if (symbol == EOF) {
throw new Error(errStr || 'Parsing halted.');
}
// discard current lookahead and grab another
yyleng = this.lexer.yyleng;
yytext = this.lexer.yytext;
yylineno = this.lexer.yylineno;
yyloc = this.lexer.yylloc;
symbol = lex();
}
// try to recover from error
while (1) {
// check for error recovery rule in this state
if ((TERROR.toString()) in table[state]) {
break;
}
if (state == 0) {
throw new Error(errStr || 'Parsing halted.');
}
popStack(1);
state = stack[stack.length-1];
}
preErrorSymbol = symbol; // save the lookahead token
symbol = TERROR; // insert generic error symbol as new lookahead
state = stack[stack.length-1];
action = table[state] && table[state][TERROR];
recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
}
// this shouldn't happen, unless resolve defaults are off
if (action[0] instanceof Array && action.length > 1) {
throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
}
switch (action[0]) {
case 1: // shift
//this.shiftCount++;
stack.push(symbol);
vstack.push(this.lexer.yytext);
lstack.push(this.lexer.yylloc);
stack.push(action[1]); // push state
symbol = null;
if (!preErrorSymbol) { // normal execution/no error
yyleng = this.lexer.yyleng;
yytext = this.lexer.yytext;
yylineno = this.lexer.yylineno;
yyloc = this.lexer.yylloc;
if (recovering > 0)
recovering--;
} else { // error just occurred, resume old lookahead f/ before error
symbol = preErrorSymbol;
preErrorSymbol = null;
}
break;
case 2: // reduce
//this.reductionCount++;
len = this.productions_[action[1]][1];
// perform semantic action
yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
// default location, uses first token for firsts, last for lasts
yyval._$ = {
first_line: lstack[lstack.length-(len||1)].first_line,
last_line: lstack[lstack.length-1].last_line,
first_column: lstack[lstack.length-(len||1)].first_column,
last_column: lstack[lstack.length-1].last_column
};
r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
if (typeof r !== 'undefined') {
return r;
}
// pop off stack
if (len) {
stack = stack.slice(0,-1*len*2);
vstack = vstack.slice(0, -1*len);
lstack = lstack.slice(0, -1*len);
}
stack.push(this.productions_[action[1]][0]); // push nonterminal (reduce)
vstack.push(yyval.$);
lstack.push(yyval._$);
// goto new state = table[STATE][NONTERMINAL]
newState = table[stack[stack.length-2]][stack[stack.length-1]];
stack.push(newState);
break;
case 3: // accept
return true;
}
}
return true;
}};
/* Jison generated lexer */
var lexer = (function(){
var lexer = ({EOF:1,
parseError:function parseError(str, hash) {
if (this.yy.parseError) {
this.yy.parseError(str, hash);
} else {
throw new Error(str);
}
},
setInput:function (input) {
this._input = input;
this._more = this._less = this.done = false;
this.yylineno = this.yyleng = 0;
this.yytext = this.matched = this.match = '';
this.conditionStack = ['INITIAL'];
this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
return this;
},
input:function () {
var ch = this._input[0];
this.yytext+=ch;
this.yyleng++;
this.match+=ch;
this.matched+=ch;
var lines = ch.match(/\n/);
if (lines) this.yylineno++;
this._input = this._input.slice(1);
return ch;
},
unput:function (ch) {
this._input = ch + this._input;
return this;
},
more:function () {
this._more = true;
return this;
},
less:function (n) {
this._input = this.match.slice(n) + this._input;
},
pastInput:function () {
var past = this.matched.substr(0, this.matched.length - this.match.length);
return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
},
upcomingInput:function () {
var next = this.match;
if (next.length < 20) {
next += this._input.substr(0, 20-next.length);
}
return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
},
showPosition:function () {
var pre = this.pastInput();
var c = new Array(pre.length + 1).join("-");
return pre + this.upcomingInput() + "\n" + c+"^";
},
next:function () {
if (this.done) {
return this.EOF;
}
if (!this._input) this.done = true;
var token,
match,
tempMatch,
index,
col,
lines;
if (!this._more) {
this.yytext = '';
this.match = '';
}
var rules = this._currentRules();
for (var i=0;i < rules.length; i++) {
tempMatch = this._input.match(this.rules[rules[i]]);
if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
match = tempMatch;
index = i;
if (!this.options.flex) break;
}
}
if (match) {
lines = match[0].match(/\n.*/g);
if (lines) this.yylineno += lines.length;
this.yylloc = {first_line: this.yylloc.last_line,
last_line: this.yylineno+1,
first_column: this.yylloc.last_column,
last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
this.yytext += match[0];
this.match += match[0];
this.yyleng = this.yytext.length;
this._more = false;
this._input = this._input.slice(match[0].length);
this.matched += match[0];
token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
if (this.done && this._input) this.done = false;
if (token) return token;
else return;
}
if (this._input === "") {
return this.EOF;
} else {
this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
{text: "", token: null, line: this.yylineno});
}
},
lex:function lex() {
var r = this.next();
if (typeof r !== 'undefined') {
return r;
} else {
return this.lex();
}
},
begin:function begin(condition) {
this.conditionStack.push(condition);
},
popState:function popState() {
return this.conditionStack.pop();
},
_currentRules:function _currentRules() {
return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
},
topState:function () {
return this.conditionStack[this.conditionStack.length-2];
},
pushState:function begin(condition) {
this.begin(condition);
}});
lexer.options = {};
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
var YYSTATE=YY_START
switch($avoiding_name_collisions) {
case 0:/* skip whitespace */
break;
case 1:return 6
break;
case 2:yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2); return 4
break;
case 3:return 17
break;
case 4:return 18
break;
case 5:return 23
break;
case 6:return 24
break;
case 7:return 22
break;
case 8:return 21
break;
case 9:return 10
break;
case 10:return 11
break;
case 11:return 8
break;
case 12:return 14
break;
case 13:return 'INVALID'
break;
}
};
lexer.rules = [/^(?:\s+)/,/^(?:(-?([0-9]|[1-9][0-9]+))(\.[0-9]+)?([eE][-+]?[0-9]+)?\b)/,/^(?:"(?:\\[\\"bfnrt/]|\\u[a-fA-F0-9]{4}|[^\\\0-\x09\x0a-\x1f"])*")/,/^(?:\{)/,/^(?:\})/,/^(?:\[)/,/^(?:\])/,/^(?:,)/,/^(?::)/,/^(?:true\b)/,/^(?:false\b)/,/^(?:null\b)/,/^(?:$)/,/^(?:.)/];
lexer.conditions = {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13],"inclusive":true}};
;
return lexer;})()
parser.lexer = lexer;
return parser;
})();
if (typeof require !== 'undefined' && typeof exports !== 'undefined') {
exports.parser = jsonlint;
exports.parse = function () { return jsonlint.parse.apply(jsonlint, arguments); }
exports.main = function commonjsMain(args) {
if (!args[1])
throw new Error('Usage: '+args[0]+' FILE');
if (typeof process !== 'undefined') {
var source = require('fs').readFileSync(require('path').join(process.cwd(), args[1]), "utf8");
} else {
var cwd = require("file").path(require("file").cwd());
var source = cwd.join(args[1]).read({charset: "utf-8"});
}
return exports.parser.parse(source);
}
if (typeof module !== 'undefined' && require.main === module) {
exports.main(typeof process !== 'undefined' ? process.argv.slice(1) : require("system").args);
}
}
Loaded 100 of 345 files, more files were not shown because too many files have changed in this diff. Show more